Windows 執行檔 (.exe/.dll/.ocx) 內建 **版本資源 (VS_VERSION_INFO)**,包含檔案版本、產品版本、公司名稱、著作權等中繼資料。GetFileVersionInfo 系列 API 可在執行期讀取這些資訊,常用於自動更新檢查、診斷日誌、關於對話框顯示。
String __fastcall TForm1::GetFileVersion(String FileName)
{
String asVer = "";
DWORD dwHandle = 0;
UINT uiSize = 0;
// 1. 取得版本資源大小
DWORD dwVerSize = GetFileVersionInfoSize(FileName.c_str(), &dwHandle);
if (dwVerSize == 0) return asVer; // 無版本資源
// 2. 分配緩衝區並讀取版本資源
std::vector buf(dwVerSize);
if (!GetFileVersionInfo(FileName.c_str(), dwHandle, dwVerSize, buf.data()))
return asVer;
// 3. 查詢固定檔案資訊 (VS_FIXEDFILEINFO)
VS_FIXEDFILEINFO *pInfo = NULL;
UINT uiLen = 0;
if (VerQueryValue(buf.data(), "\\", (LPVOID*)&pInfo, &uiLen) && pInfo)
{
// dwFileVersionMS: 高字=主版本, 低字=次版本
// dwFileVersionLS: 高字=建置編號, 低字=修訂編號
asVer = IntToStr(HIWORD(pInfo->dwFileVersionMS)) + "." +
IntToStr(LOWORD(pInfo->dwFileVersionMS)) + "." +
IntToStr(HIWORD(pInfo->dwFileVersionLS)) + "." +
IntToStr(LOWORD(pInfo->dwFileVersionLS));
}
return asVer; // 格式: "1.2.3.4"
}
GetFileVersionInfoSize → 取得資源大小 (bytes)GetFileVersionInfo → 將版本資源複製至緩衝區VerQueryValue(buf, "\\", ...) → 取得 VS_FIXEDFILEINFO 結構指標dwFileVersionMS/LS 四個 16-bit 欄位組合版本號// 查詢字串表 (語言/代碼頁相關)
struct LANGANDCODEPAGE { WORD wLanguage; WORD wCodePage; } *lpTranslate;
UINT cbTranslate;
VerQueryValue(buf.data(), "\\VarFileInfo\\Translation", (LPVOID*)&lpTranslate, &cbTranslate);
for (UINT i=0; i < cbTranslate/sizeof(LANGANDCODEPAGE); ++i) {
AnsiString subBlock = "\\StringFileInfo\\" +
IntToHex(lpTranslate[i].wLanguage, 4) + IntToHex(lpTranslate[i].wCodePage, 4) + "\\";
char *pValue; UINT len;
if (VerQueryValue(buf.data(), (subBlock + "CompanyName").c_str(), (LPVOID*)&pValue, &len))
ShowMessage("Company: " + String(pValue));
// 同理:FileDescription, FileVersion, InternalName, LegalCopyright, OriginalFilename, ProductName, ProductVersion...
}
標準庫 std::filesystem::file_time_type 無法讀取版本資源,仍需 Win32 API。