2013-06-24 37 views
-1

GetFileVersionInfoSize爲0(零) 而GetFileVersionInfo返回任何GetFileVersionInfoSize而GetFileVersionInfo任何回報

我使用這樣的:基於堆棧的答覆Get FileVersion with Build

它工作在

function FileVersion(const FileName: TFileName): String; 
var 
    VerInfoSize: Cardinal; 
    VerValueSize: Cardinal; 
    Dummy: Cardinal; 
    PVerInfo: Pointer; 
    PVerValue: PVSFixedFileInfo; 
begin 
    Result := ''; 
    VerInfoSize := GetFileVersionInfoSize(PChar(FileName), Dummy); 
    GetMem(PVerInfo, VerInfoSize); 
    try 
    if GetFileVersionInfo(PChar(FileName), 0, VerInfoSize, PVerInfo) then 
     if VerQueryValue(PVerInfo, '\', Pointer(PVerValue), VerValueSize) then 
     with PVerValue^ do 
      Result := Format('v%d.%d.%d build %d', [ 
      HiWord(dwFileVersionMS), //Major 
      LoWord(dwFileVersionMS), //Minor 
      HiWord(dwFileVersionLS), //Release 
      LoWord(dwFileVersionLS)]); //Build 
    finally 
    FreeMem(PVerInfo, VerInfoSize); 
    end; 
end; 

大部分情況。

感謝

+0

你沒有檢查'GetFileVersionInfoSize'是否返回了一個有用的值(VerInfoSize> 0)。你也沒有檢查'GetFileVersionInfo'的返回值。添加一個'else',看看'GetLastError'告訴你什麼。 –

+0

是的,我明白了。但是,如果文件存在int正確的路徑,什麼可以讓GetFileVersionInfoSize返回0? – Jlouro

+0

再一次,你需要調用'GetLastError()'來找出它返回0的原因。最有可能的是,文件根本沒有任何可用的版本信息。 –

回答

5

你不檢查的GetFileVersionInfoSize返回值。如果文件名無效或沒有可用的版本信息,它將返回零(false),並且文檔說明您可以找出使用GetLastError的原因。在使用Delphi 2007時,跨平臺兼容性不是問題(至少現在是這樣),您可以使用SysErrorMessage(GetLastError)來獲取字符串描述失敗原因的描述。

我已經寫了它來返回錯誤信息,如果失敗了;在實際應用中,當然你可能不會那麼做。

這工作(Delphi的7測試中,Win7 64位):

function FileVersion(const FileName: TFileName): String; 
var 
    VerInfoSize: Cardinal; 
    VerValueSize: Cardinal; 
    Dummy: Cardinal; 
    PVerInfo: Pointer; 
    PVerValue: PVSFixedFileInfo; 
    iLastError: DWord; 
begin 
    Result := ''; 
    VerInfoSize := GetFileVersionInfoSize(PChar(FileName), Dummy); 
    if VerInfoSize > 0 then 
    begin 
    GetMem(PVerInfo, VerInfoSize); 
    try 
     if GetFileVersionInfo(PChar(FileName), 0, VerInfoSize, PVerInfo) then 
     begin 
     if VerQueryValue(PVerInfo, '\', Pointer(PVerValue), VerValueSize) then 
      with PVerValue^ do 
      Result := Format('v%d.%d.%d build %d', [ 
       HiWord(dwFileVersionMS), //Major 
       LoWord(dwFileVersionMS), //Minor 
       HiWord(dwFileVersionLS), //Release 
       LoWord(dwFileVersionLS)]); //Build 
     end 
     else 
     begin 
     iLastError := GetLastError; 
     Result := Format('GetFileVersionInfo failed: (%d) %s', 
         [iLastError, SysErrorMessage(iLastError)]); 
     end; 
    finally 
     FreeMem(PVerInfo, VerInfoSize); 
    end; 
    end 
    else 
    begin 
    iLastError := GetLastError; 
    Result := Format('GetFileVersionInfo failed: (%d) %s', 
        [iLastError, SysErrorMessage(iLastError)]); 
    end; 
end; 

始終測試WinAPI的的返回值調用。 MSDN上的文檔描述了返回值和失敗的原因(或者告訴你可以從GetLastError中獲取它)。

+0

如果要顯示錯誤消息,通常會在消息中包含實際的錯誤代碼,例如:var iLastError:Integer; ... iLastError:= GetLastError;結果:=格式('GetFileVersionInfoSize失敗:(%d)%s',[iLastError,SysErrorMessage(iLastError)]);' –

+0

@Remy:當然你是對的。編輯實施您的建議。謝謝。 –