Question:
The VS_VERSIONINFO structure can be used to obtain file version data about files with extended version data. This structure is not included in Delphi 4.0, nor is it included in any Microsoft SDK. How do I use it and the associated functions to get this version data?
Answer:
Instead of going into the dirty details of this structure, let me just say that getting the version information revolves around the GetFileVersionInfo Win API call. If you compile your program with extended version information, you can get the version information using this call. However, as with most things in the WinAPI, it's a lot more complicated than that. Therefore, I've created a wrapper class that will handle that stuff for you. All you need to do is create the class and access its properties to get the version information for your executable. Here's the listing (please observe the copyright info):
{======================================================================
*****PLEASE DO NOT REMOVE THIS HEADER EVEN IF YOU CHANGE THE FILE*****
======================================================================
Author : Brendan V. Delumpa bdelumpa@delumpa.com
Copyright © 1999 Brendan V. Delumpa
TITLE
Version Info Unit
DESCRIPTION
This unit can be included in any project to affect version information
display in an about box. Simply create and instance of the class,
passing a fully qualified file name to the constructor, and the object
will retrieve version information about the file.
NOTES
Since I created this to cover only the functionality I wanted for my
own programs, I didn't include everything that you can get with
this set of routines. I handle all the return values of GetFileVersion-
Info, but only scratch the surface with the PVSFixedFileInfo structure.
There's stuff there that I just didn't need.
By the way, you're free to use and copy this code to your heart's
content. All I ask is that you make sure that you give credit where
credit is due. Also, if you make changes, I'd appreciate you sharing
them. And if you do, make sure to include your name and e-mail address
in the Changes section. Thanks!
Brendan
EXAMPLE USAGE:
implementation
uses VerInfo; //Merely include this in your uses statement somewhere
procedure TfrmInfo.FormCreate(Sender: TObject);
var
VInfo : TVersionInfo;
begin
with Animate1 do begin
Active := False;
ResName := 'RHS_Act';
Active := True;
end;
VInfo := TVersionInfo.Create(Application.ExeName);
Label1.Caption := VInfo.CompanyName;
Label3.Caption := VInfo.FileVersion;
Label5.Caption := VInfo.LegalCopyright;
Label8.Caption := VInfo.ProductName;
Label9.Caption := VInfo.ProductVersion;
Label11.Caption := VInfo.OSVersion;
VInfo.Free;
end;
CHANGES:
Date Who What
========== ===================== =================================
1/13/1999 Brendan Added some example code for when
unit is distributed
======================================================================}
unit VerInfo;
interface
uses
Windows, SysUtils, Forms;
type
TVersionInfo = class
private
FPVSFileInfoBuf : PVSFixedFileInfo;
FVerInfoSize : DWORD;
FVersBuffer,
FCompanyNameText,
FFileDescriptionText,
FFileVersionText,
FInternalNameText,
FLegalCopyrightText,
FLegalTrademarksText,
FOriginalFilenameText,
FProductNameText,
FProductVersionText,
FCommentsText : String;
function GetVersionInfo(FieldString : String) : String;
function GetOSVersion : String;
public
constructor Create(FileName : String);
property CompanyName : String read FCompanyNameText;
property FileDescription : String read FFileDescriptionText;
property FileVersion : String read FFileVersionText;
property InternalName : String read FInternalNameText;
property LegalCopyright : String read FLegalCopyrightText;
property LegalTrademarks : String read FLegalTrademarksText;
property OriginalFilename : String read FOriginalFilenameText;
property ProductName : String read FProductNameText;
property ProductVersion : String read FProductVersionText;
property Comments : String read FCommentsText;
property OSVersion : String read GetOSVersion;
end;
implementation
constructor TVersionInfo.Create(FileName : String);
var
Hndl : DWORD;
iSize : Cardinal;
begin
//Get the size of the version information structure
FVerInfoSize := GetFileVersionInfoSize(PChar(FileName), Hndl);
if not (FVerInfoSize <= 0) then
begin
//Initialize the version buffer
SetLength(FVersBuffer, FVerInfoSize);
//Get File Version Information, then set object field values
GetFileVersionInfo(PChar(FileName), Hndl, FVerInfoSize, PChar(FVersBuffer));
FCompanyNameText := GetVersionInfo('CompanyName');
FFileDescriptionText := GetVersionInfo('FileDescription');
FFileVersionText := GetVersionInfo('FileVersion');
FInternalNameText := GetVersionInfo('InternalName');
FLegalCopyrightText := GetVersionInfo('LegalCopyright');
FLegalTrademarksText := GetVersionInfo('LegalTrademarks');
FOriginalFilenameText := GetVersionInfo('OriginalFilename');
FProductNameText := GetVersionInfo('ProductName');
FProductVersionText := GetVersionInfo('ProductVersion');
FCommentsText := GetVersionInfo('Comments');
//File the Fixed File Info Buffer for OS and Product Versions
//You get the Fixed File Info by passing "\" as the SubType param
VerQueryValue(PChar(FVersBuffer), '\', Pointer(FPVSFileInfoBuf), iSize);
end;
end;
function TVersionInfo.GetVersionInfo(FieldString : String) : String;
var
sTemp : String;
begin
//Set the size of the temporary buffer
SetLength(sTemp, FVerInfoSize);
//040904E4 value is the Locale ID in Project Options dialog VersionInfo tab
//In the case of there being no version information, simply return
//a "not available" string for the property
if VerQueryValue(Pointer(PChar(FVersBuffer)), PChar('\StringFileInfo\040904E4\' + FieldString),
Pointer(sTemp), FVerInfoSize) then
Result := StrPas(PChar(sTemp))
else
Result := 'Version information for ' + FieldString + ' is not available';
end;
function TVersionInfo.GetOSVersion: String;
begin
//There are lots of versions covered with dwFileOS, but
//only a couple are really useful for our purposes.
if (FVerInfoSize > 0) then
with FPVSFileInfoBuf^ do
case dwFileOS of
VOS_UNKNOWN : Result := 'Unknown';
VOS_DOS : Result := 'MS-DOS';
VOS_NT : Result := 'Windows NT';
VOS__WINDOWS16 : Result := '16-bit Windows';
VOS__WINDOWS32 : Result := '32-bit Windows';
VOS_DOS_WINDOWS16 : Result := '16-bit Windows on MS-DOS';
VOS_DOS_WINDOWS32 : Result := 'Win32 on MS-DOS';
VOS_NT_WINDOWS32 : Result := 'Win32 on Windows NT';
else
Result := 'Designed for non-Windows OS or non-Current Windows OS';
end
else
Result := 'OS Version information not available';
end;
end.