2012-12-18 45 views
2

我有版本信息資源宣佈:如何從資源獲取版本信息?

100 VERSIONINFO 
FILEVERSION 1,0,0,2 
PRODUCTVERSION 1,0,0,2 
FILEOS VOS_NT 
FILETYPE VFT_APP 
{ 
    BLOCK "StringFileInfo" 
    { 
     BLOCK "000004b0" 
     { 
      VALUE "FileDescription", "My application" 
      VALUE "FileVersion", "1.0.0.2" 
      VALUE "InternalName", "app.exe" 
      VALUE "LegalCopyright", "Copyright © 2012 by David." 
      VALUE "OriginalFilename", "app.exe" 
      VALUE "ProductName", "app" 
      VALUE "ProductVersion", "1.0.0.2" 
      VALUE "Assembly Version", "1.0.0.2" 
     } 
    } 

    BLOCK "VarFileInfo" 
    { 
     VALUE "Translation", 0x0000 0x04B0 
    } 
} 

我越來越版本信息是這樣的:

HRSRC hResInfo; 
HGLOBAL hResData; 
LPCVOID pRes; 
UINT uLen; 
VS_FIXEDFILEINFO *lpFfi; 

hResInfo = FindResource(hInst, MAKEINTRESOURCE(100), RT_VERSION); 
MessageBox(0, "FindResource", 0,0); 

hResData = LoadResource(hInst, hResInfo); 
MessageBox(0, "LoadResource", 0,0); 

pRes = LockResource(hResData); 
MessageBox(0, "LockResource", 0,0); 

VerQueryValue(pRes, "\\" ,(LPVOID*)&lpFfi, &uLen); 
MessageBox(0, "VerQueryValue", 0,0); 

FreeResource(hResData); 

DWORD dwFileVersionMS = lpFfi->dwFileVersionMS; 
DWORD dwFileVersionLS = lpFfi->dwFileVersionLS; 

DWORD dwLeftMost  = HIWORD(dwFileVersionMS); 
DWORD dwSecondLeft = LOWORD(dwFileVersionMS); 
DWORD dwSecondRight = HIWORD(dwFileVersionLS); 
DWORD dwRightMost = LOWORD(dwFileVersionLS); 

在功能VerQueryValue是一個錯誤,因爲程序中斷(消息框與文本「VerQueryValue」不顯示)和Visual C++讓我看到以下消息:在ProxyCU.exe在0x77bf15a5

第一次機會異常:0000005: 訪問衝突寫入地址0x00483192。

如何修復這個代碼?

的問候,大衛

+0

我通常分解出的版本信息的定義,其中,[如這裏所示](http://stackoverflow.com/questions/13607986乘以它消失/ how-can-i-share-same-product-version-between-two-visual-c-projects/13608454#13608454),所以當它在代碼中使用它時,它是一個編譯器定義而不是調用到'LoadResource()'。如果你不能讓你的代碼工作,你可能會認爲它是一個選項。 –

+0

我建議在LoadResource()後面檢查錯誤代碼(@ERR在調試器中監視,或GetLastError)。另外,請檢查此地址0x00483192是否位於pRes指向的內存內。 –

+0

與問題完全無關,但爲什麼您的版本資源在ID 100?據我所知它預計將在ID爲1 VS_VERSION_INFO – poizan42

回答

12

VerQueryValue()不能直接從原始資源訪問版本信息。您必須在內存中創建資源的副本,然後將該內存傳遞給VerQueryValue()。原因是因爲VerQueryValue()被設計爲與GetFileVersionInfo()一起使用,其需要用戶分配的可寫內存塊並在該內存中執行某些修正。訪問VS_FIXEDFILEINFO結構不需要修正,但內存塊必須仍然可寫。您不能將原始資源直接傳遞給VerQueryValue(),因爲它是隻讀內存。

試試這個:

HRSRC hResInfo; 
DWORD dwSize; 
HGLOBAL hResData; 
LPVOID pRes, pResCopy; 
UINT uLen; 
VS_FIXEDFILEINFO *lpFfi; 

hResInfo = FindResource(hInst, MAKEINTRESOURCE(100), RT_VERSION); 
dwSize = SizeofResource(hInst, hResInfo); 
hResData = LoadResource(hInst, hResInfo); 
pRes = LockResource(hResData); 
pResCopy = LocalAlloc(LMEM_FIXED, dwSize); 
CopyMemory(pResCopy, pRes, dwSize); 
FreeResource(hResData); 

VerQueryValue(pResCopy, TEXT("\\"), (LPVOID*)&lpFfi, &uLen); 

DWORD dwFileVersionMS = lpFfi->dwFileVersionMS; 
DWORD dwFileVersionLS = lpFfi->dwFileVersionLS; 

DWORD dwLeftMost  = HIWORD(dwFileVersionMS); 
DWORD dwSecondLeft = LOWORD(dwFileVersionMS); 
DWORD dwSecondRight = HIWORD(dwFileVersionLS); 
DWORD dwRightMost = LOWORD(dwFileVersionLS); 

LocalFree(pResCopy); 
+1

+1。你的代碼效果很好。十分感謝。 – David

+0

+1我只是需要和使用這個。謝謝。一個非常小的評論:根據文檔,'FreeResource'調用不需要並且返回'FALSE'。 –

+0

是否有任何正式文件證明您必須複製該塊的事實? –