2004. március 23., kedd

Retrieve version information from an executable or DLL


Problem/Question/Abstract:

Is there a quick way to include the build number created by Project/ Options/ Version Info in my About Box?

Answer:

Solve 1:

Here's a function which will read the version info:

{Get Major, Minor, Release, Build for an EXE or DLL file.
returns true = success.
returns false = failure, probably info not found in the file.}

function GetFileVersion(const FileName: string; var Major, Minor, Release, Build:
  Integer;
  var PreRelease, Debug: Boolean; var Description: string): Boolean;
var
  Zero: DWORD; {set to 0 by GetFileVersionInfoSize}
  VersionInfoSize: DWORD;
  PVersionData: pointer;
  PFixedFileInfo: PVSFixedFileInfo;
  FixedFileInfoLength: UINT;
  FileFlags: WORD;
begin
  {ask Windows how big a data buffer to allocate to hold this EXE or DLL version info}
  VersionInfoSize := GetFileVersionInfoSize(pChar(FileName), Zero);
  {if no version info in the EXE or DLL}
  if VersionInfoSize = 0 then
  begin
    result := False;
    exit;
  end;
  {allocate memory needed to hold version info}
  PVersionData := AllocMem(VersionInfoSize);
  try
    {load version resource out of EXE or DLL into our buffer}
    if GetFileVersionInfo(pChar(FileName), 0, VersionInfoSize, PVersionData) = false
      then
    begin
      raise Exception.Create('Can''''t get version info');
    end;
    {get the fixed file info portion of the resource in buffer}
    if VerQueryValue(PVersionData, '\', pointer(PFixedFileInfo), FixedFileInfoLength)
      = false then
    begin
      {no fixed file info in this version resource !}
      result := False;
      exit;
    end;
    {extract the info from the the fixed file data structure}
    Major := PFixedFileInfo^.dwFileVersionMS shr 16;
    Minor := PFixedFileInfo^.dwFileVersionMS and $FFFF;
    Release := PFixedFileInfo^.dwFileVersionLS shr 16;
    Build := PFixedFileInfo^.dwFileVersionLS and $FFFF;
    FileFlags := PFixedFileInfo^.dwFileFlags;
    PreRelease := (VS_FF_PRERELEASE and FileFlags) < > 0;
    Debug := (VS_FF_DEBUG and FileFlags) < > 0;
    Description := Format('Ver %d.%d, Release %d Build %d', [Major, Minor, Release,
      Build]);
    if PreRelease then
    begin
      Description := Description + ' Beta';
    end;
    if Debug then
    begin
      Description := Description + ' Debug';
    end;
  finally
    FreeMem(PVersionData);
  end;
  result := True;
end;


Solve 2:

{ ... }

TVer = record
  case integer of
    0: (both: integer);
    1: (LowPart, HighPart: Word);
end;

TVersion = record
  Major: Word;
  Minor: Word;
  Release: Word;
  Build: Word;
end;

function GetVersionInfo(FileName: string): TVersion;
var
  Len: DWord;
  Size: DWord;
  buf: pChar;
  Info: pVSFixedFileInfo;
begin
  fillChar(result, sizeOf(TVersion), #0);
  Size := GetFileVersionInfoSize(pChar(FileName), Len);
  if Size = 0 then
    exit;
  GetMem(buf, Size);
  try
    GetFileVersionInfo(pChar(FileName), 0, Size, buf);
    if VerQueryValue(buf, '\', pointer(Info), Len) then
      with Result do
      begin
        Major := TVer(Info.dwFileVersionMS).HighPart;
        Minor := TVer(Info.dwFileVersionMS).LowPart;
        Release := TVer(Info.dwFileVersionLS).HighPart;
        Build := TVer(Info.dwFileVersionLS).LowPart;
      end;
  finally
    FreeMem(buf);
  end;
end;


Solve 3:

Get the version info stored inside a DLL.

function dgGetBuildInfo: string;
var
  V1, V2, V3, V4: Word;
  VerInfoSize: DWORD;
  VerInfo: Pointer;
  VerValueSize: DWORD;
  VerValue: PVSFixedFileInfo;
  Dummy: DWORD;
begin
  VerInfoSize := GetFileVersionInfoSize(PChar(ParamStr(0)), Dummy);
  GetMem(VerInfo, VerInfoSize);
  try
    GetFileVersionInfo(PChar(ParamStr(0)), 0, VerInfoSize, VerInfo);
    VerQueryValue(VerInfo, '\', Pointer(VerValue), VerValueSize);
    with VerValue^ do
    begin
      V1 := dwFileVersionMS shr 16;
      V2 := dwFileVersionMS and $FFFF;
      V3 := dwFileVersionLS shr 16;
      V4 := dwFileVersionLS and $FFFF;
    end;
    Result := IntToStr(V1) + '.' + IntToStr(V2) + '.' + IntToStr(V3) + '.' +
      IntToStr(V4);
  finally
    FreeMem(VerInfo, VerInfoSize);
  end;
end;

Nincsenek megjegyzések:

Megjegyzés küldése