首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 動態讀取檔案版本資訊:API 完整解析與關於對話框實作

     編輯:Delphi

版本資訊的作用與 API 基礎

檔案版本資訊(版本號、描述、作者、版權等)讓安裝程式能判斷覆蓋策略、多語系環境選擇正確語言、防止重複安裝、運行時驗證版本、顯示於「關於」對話框、線上更新檢查。Windows 透過 VERSION.DLL 提供 API:GetFileVersionInfoSize、GetFileVersionInfo、VerQueryValue、VerLanguageName 等。

四大核心 API Delphi 宣告與參數詳解

function GetFileVersionInfoSize(lptstrFilename: PChar; var lpdwHandle: DWORD): DWORD; stdcall;
// 回傳版本資源大小(位元組),失敗回傳 0

function GetFileVersionInfo(lptstrFilename: PChar; dwHandle: DWORD; dwLen: DWORD; lpData: Pointer): BOOL; stdcall;
// 將版本資源複製至緩衝區 lpData,dwLen 需 >= GetFileVersionInfoSize 回傳值

function VerQueryValue(pBlock: Pointer; lpSubBlock: PChar; var lplpBuffer: Pointer; var puLen: UINT): BOOL; stdcall;
// 從版本資源區塊查詢特定值,lpSubBlock 格式:
// "\" 根區域 → VS_FIXEDFILEINFO
// "\VarFileInfo\Translation" → 語言/代碼頁陣列
// "\StringFileInfo\lang-codepage\string-name" → 字串值(如 FileVersion, CompanyName)

function VerLanguageName(wLang: DWORD; szLang: PChar; nSize: DWORD): DWORD; stdcall;
// 語言識別碼轉換為描述字串(如 0x0404 → "繁體中文")

預定義字串名稱:Comments, InternalName, ProductName, CompanyName, LegalCopyright, ProductVersion, FileDescription, LegalTrademarks, PrivateBuild, FileVersion, OriginalFilename, SpecialBuild。

實作範例:關於對話框動態顯示版本資訊

關於對話框版面配置 版本資訊API列表表格 專案選項版本資訊頁面填寫範例

步驟 1:專案選項填寫版本資訊(Shift+Ctrl+F11,Version Info 頁面勾選 Include Version Information,填入上述預定義欄位)。

步驟 2:關於對話框 OnCreate 事件代碼:

const InfoNum = 9;
InfoStr: array[1..InfoNum] of String = (
  'ProductName', 'ProductVersion', 'FileDescription', 'LegalCopyright',
  'FileVersion', 'CompanyName', 'LegalTradeMarks', 'InternalName', 'OriginalFileName');
var S: String; BufSize, Len: DWORD; Buf, Value: PChar;
begin
  S := Application.ExeName;
  BufSize := GetFileVersionInfoSize(PChar(S), BufSize);
  if BufSize > 0 then
  begin
    Buf := AllocMem(BufSize);
    GetFileVersionInfo(PChar(S), 0, BufSize, Buf);
    // 080403A8 = 語言代碼頁(繁體中文 CP950),需根據實際資源調整
    if VerQueryValue(Buf, PChar('\StringFileInfo\080403A8\' + InfoStr[1]), Pointer(Value), Len) then
      ProductName.Caption := Value;
    if VerQueryValue(Buf, PChar('\StringFileInfo\080403A8\' + InfoStr[2]), Pointer(Value), Len) then
      ProductVersion.Caption := '產品版本: ' + Value;
    if VerQueryValue(Buf, PChar('\StringFileInfo\080403A8\' + InfoStr[3]), Pointer(Value), Len) then
      FileDescription.Caption := '檔案說明: ' + Value;
    if VerQueryValue(Buf, PChar('\StringFileInfo\080403A8\' + InfoStr[4]), Pointer(Value), Len) then
      LegalCopyright.Caption := '合法版權: ' + Value;
    if VerQueryValue(Buf, PChar('\StringFileInfo\080403A8\' + InfoStr[5]), Pointer(Value), Len) then
      FileVersion.Caption := '檔案版本: ' + Value;
    if VerQueryValue(Buf, PChar('\StringFileInfo\080403A8\' + InfoStr[6]), Pointer(Value), Len) then
      CompanyName.Caption := '公司名稱: ' + Value;
    if VerQueryValue(Buf, PChar('\StringFileInfo\080403A8\' + InfoStr[7]), Pointer(Value), Len) then
      LegalTrademarks.Caption := '合法商標: ' + Value;
    if VerQueryValue(Buf, PChar('\StringFileInfo\080403A8\' + InfoStr[8]), Pointer(Value), Len) then
      InternalName.Caption := '內部名稱: ' + Value;
    if VerQueryValue(Buf, PChar('\StringFileInfo\080403A8\' + InfoStr[9]), Pointer(Value), Len) then
      OriginalFilename.Caption := '原始檔名: ' + Value;
    FreeMem(Buf, BufSize);
  end
  else
  begin
    Application.MessageBox('讀取版本資訊失敗,請重新啟動。', '錯誤', MB_OK + MB_ICONSTOP);
    Application.Terminate;
  end;
end;

關鍵注意事項

  • API 呼叫順序嚴格:GetFileVersionInfoSize → AllocMem → GetFileVersionInfo → VerQueryValue → FreeMem
  • 語言代碼頁(080403A8)必須與資源編譯器產生的值一致,可透過 \VarFileInfo\Translation 動態查詢
  • 記憶體洩漏預防:必須配對 FreeMem 釋放 AllocMem 分配的緩衝區
  • Win XP 支援 16/32/64 位元檔案,Win9x/NT 僅支援 16/32 位元

此技術讓應用程式具備專業級的版本管理與顯示能力,是部署與維護的基礎設施。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved