GetFileVersionInfoSize is 0 (zero) And GetFileVersionInfo return nothing
I am using it Like this:
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;
Based on the stack reply Get FileVersion with Build
It work in most of the cases.
Thanks
You're not checking the return value of GetFileVersionInfoSize
. If the file name is invalid or there's no version info available, it will return zero (false), and the documentation says you can find out why using GetLastError
. As you're using Delphi 2007, cross-platform compatibility isn't an issue (at least for now), and you can use SysErrorMessage(GetLastError)
to get a string description of the reason it failed.
I've written it to return the error message if something fails; in an actual application, you probably won't want to do that, of course.
This works (tested on Delphi 7, Win7 64-bit):
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;
Always test the return value of WinAPI calls. The documentation at MSDN describes the return values and reasons for failure (or tells you that you can get it from GetLastError).