Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get FileVersion with Build

Tags:

delphi

DelphiXe.

For reception of the version of a file I use function:

function FileVersion(AFileName: string): string;
var
  szName: array[0..255] of Char;
  P: Pointer;
  Value: Pointer;
  Len: UINT;
  GetTranslationString: string;
  FFileName: PChar;
  FValid: boolean;
  FSize: DWORD;
  FHandle: DWORD;
  FBuffer: PChar;
begin
  try
    FFileName := StrPCopy(StrAlloc(Length(AFileName) + 1), AFileName);
    FValid := False;
    FSize := GetFileVersionInfoSize(FFileName, FHandle);
    if FSize > 0 then
    try
      GetMem(FBuffer, FSize);
      FValid := GetFileVersionInfo(FFileName, FHandle, FSize, FBuffer);
    except
      FValid := False;
      raise;
    end;
    Result := '';
    if FValid then
      VerQueryValue(FBuffer, '\VarFileInfo\Translation', p, Len)
    else
      p := nil;
    if P <> nil then
      GetTranslationString := IntToHex(MakeLong(HiWord(Longint(P^)),
        LoWord(Longint(P^))), 8);
    if FValid then
    begin
      StrPCopy(szName, '\StringFileInfo\' + GetTranslationString +
        '\FileVersion');
      if VerQueryValue(FBuffer, szName, Value, Len) then
        Result := StrPas(PChar(Value));
    end;
  finally
    try
      if FBuffer <> nil then
        FreeMem(FBuffer, FSize);
    except
    end;
    try
      StrDispose(FFileName);
    except
    end;
  end;
end;

For the majority of executed files and libraries it returns correct value. But at some files the version is cut off and shown without Build. Here for example file BASS.DLL (http://us.un4seen.com/files/bass24.zip) In Windows Explorer in properties of a file I see version 2.4.7.1, function result='2.4.7' :(

I open a file through Resourcehacker.exe (http://angusj.com/resourcehacker/), I look structure VersionInfo:

1 VERSIONINFO
FILEVERSION 2,4,7,1
PRODUCTVERSION 2,4,0,0
FILEOS 0x4
FILETYPE 0x2
{
BLOCK "StringFileInfo"
{
    BLOCK "000004b0"
    {
        VALUE "CompanyName", "Un4seen Developments"
        VALUE "FileDescription", "BASS"
        VALUE "FileVersion", "2.4.7"
        VALUE "LegalCopyright", "Copyright © 1999-2010"
    }
}

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

Question: how to receive 2.4.7.1, i.e. the full version?

like image 244
Gu. Avatar asked Jul 02 '11 15:07

Gu.


1 Answers

If you want the file version of the root block, then forget about the language specific translation:

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;
like image 52
NGLN Avatar answered Nov 02 '22 23:11

NGLN