2011-04-04 154 views

回答

26

這在大約進行了描述:

基本上,你只需要使用GetFileVersionInfo函數來獲取數據,然後VerQueryValue函數讀取它。

因爲這些API函數都有點「硬」來使用,我寫了一個簡單的例子:

type 
    TEXEVersionData = record 
    CompanyName, 
    FileDescription, 
    FileVersion, 
    InternalName, 
    LegalCopyright, 
    LegalTrademarks, 
    OriginalFileName, 
    ProductName, 
    ProductVersion, 
    Comments, 
    PrivateBuild, 
    SpecialBuild: string; 
    end; 

function GetEXEVersionData(const FileName: string): TEXEVersionData; 
type 
    PLandCodepage = ^TLandCodepage; 
    TLandCodepage = record 
    wLanguage, 
    wCodePage: word; 
    end; 
var 
    dummy, 
    len: cardinal; 
    buf, pntr: pointer; 
    lang: string; 
begin 
    len := GetFileVersionInfoSize(PChar(FileName), dummy); 
    if len = 0 then 
    RaiseLastOSError; 
    GetMem(buf, len); 
    try 
    if not GetFileVersionInfo(PChar(FileName), 0, len, buf) then 
     RaiseLastOSError; 

    if not VerQueryValue(buf, '\VarFileInfo\Translation\', pntr, len) then 
     RaiseLastOSError; 

    lang := Format('%.4x%.4x', [PLandCodepage(pntr)^.wLanguage, PLandCodepage(pntr)^.wCodePage]); 

    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\CompanyName'), pntr, len){ and (@len <> nil)} then 
     result.CompanyName := PChar(pntr); 
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\FileDescription'), pntr, len){ and (@len <> nil)} then 
     result.FileDescription := PChar(pntr); 
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\FileVersion'), pntr, len){ and (@len <> nil)} then 
     result.FileVersion := PChar(pntr); 
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\InternalName'), pntr, len){ and (@len <> nil)} then 
     result.InternalName := PChar(pntr); 
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\LegalCopyright'), pntr, len){ and (@len <> nil)} then 
     result.LegalCopyright := PChar(pntr); 
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\LegalTrademarks'), pntr, len){ and (@len <> nil)} then 
     result.LegalTrademarks := PChar(pntr); 
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\OriginalFileName'), pntr, len){ and (@len <> nil)} then 
     result.OriginalFileName := PChar(pntr); 
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\ProductName'), pntr, len){ and (@len <> nil)} then 
     result.ProductName := PChar(pntr); 
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\ProductVersion'), pntr, len){ and (@len <> nil)} then 
     result.ProductVersion := PChar(pntr); 
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\Comments'), pntr, len){ and (@len <> nil)} then 
     result.Comments := PChar(pntr); 
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\PrivateBuild'), pntr, len){ and (@len <> nil)} then 
     result.PrivateBuild := PChar(pntr); 
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\SpecialBuild'), pntr, len){ and (@len <> nil)} then 
     result.SpecialBuild := PChar(pntr); 
    finally 
    FreeMem(buf); 
    end; 
end; 

試試吧。但要小心 - 目前,這個只有適用於en-us EXE!例如,它不適用於瑞典機器上的大多數EXE。現在已經晚了;明天,如果我只剩下一些時間,我會將其擴展到任何EXE語言。 [在About.com代碼有同樣的問題,但他們甚至不假裝這是一個問題!]

更新:現在,該代碼適用於任何EXE語言。

Sample usage on Connect.exe http://privat.rejbrand.se/verinfo.png
(EN-US)

Sample usage on Explorer.exe (Swedish) http://privat.rejbrand.se/verinfo2.png
(瑞典)

+0

非常有用的。我的第一個搜索源是關於,但我找不到它,我想知道爲什麼!!!真的謝謝 – Armin 2011-04-04 14:36:50

+0

編譯時出現這個錯誤:「實際的和正式的var參數的類型必須相同」這個問題呢?我沒有對描述的功能做任何改變! – Armin 2011-04-04 18:54:25

+0

@Armin:如果你告訴我們錯誤發生在哪一行,這將有所幫助。 – 2011-04-04 19:09:52