As you might know; in Lazarus you can add version and build info to the executable (at least under Linux, Windows, and MacOS X).
The question is - for example for an About box - how do I extract that information from my executable at runtime? And ... preferably cross platform.
Follow these steps:
1. Add units vinfo (step 3 creates the unit) and versiontypes to the Uses clause.
2. Add code to one of the forms (typically the main form so you can read it if you make it a property of tform).
As you can see in the code below, version info can be extracted from the TVersionInfo object:
...
var Info: TVersionInfo;
Version: string;
begin
// Get application compiled version#
Info := TVersionInfo.Create;
Info.Load(HINSTANCE);
Version := Format('%d.%d.%d', [Info.FixedInfo.FileVersion[0],Info.FixedInfo.FileVersion[1],Info.FixedInfo.FileVersion[2]]);
Info.Free;
self.Caption:='Name My TV Series v'+Version+' - © Hans Luijten - www.tweaking4all.com';
...
3. Create and save the file vinfo.pas (which we added to the sues clause in step 1).
unit vinfo;
{$mode objfpc}
interface
uses
Classes, SysUtils, resource, versiontypes, versionresource;
type
{ TVersionInfo }
TVersionInfo = class
private
FVersResource: TVersionResource;
function GetFixedInfo: TVersionFixedInfo;
function GetStringFileInfo: TVersionStringFileInfo;
function GetVarFileInfo: TVersionVarFileInfo;
function SearchValue(const aString : string) : string;
public
constructor Create;
destructor Destroy; override;
function CompanyName : string;
function InternalName : string;
function FileVersion : string;
function ProductName : string;
procedure Load(Instance: THandle);
property FixedInfo: TVersionFixedInfo read GetFixedInfo;
property StringFileInfo: TVersionStringFileInfo read GetStringFileInfo;
property VarFileInfo: TVersionVarFileInfo read GetVarFileInfo;
end;
implementation
{ TVersionInfo }
function TVersionInfo.GetFixedInfo: TVersionFixedInfo;
begin
Result := FVersResource.FixedInfo;
end;
function TVersionInfo.GetStringFileInfo: TVersionStringFileInfo;
begin
Result := FVersResource.StringFileInfo;
end;
function TVersionInfo.GetVarFileInfo: TVersionVarFileInfo;
begin
Result := FVersResource.VarFileInfo;
end;
function TVersionInfo.SearchValue(const aString: string): string;
var s : TVersionStringTable;
i,j : integer;
begin
result := '';
for i:=0 to StringFileInfo.Count-1 do begin
s := StringFileInfo.Items;
for j:=0 to s.Count-1 do
if s.Keys[j] = aString then begin
result := s.Values[j];
break;
end;
end;
end;
function TVersionInfo.CompanyName: string;
begin
Result := SearchValue('CompanyName');
end;
function TVersionInfo.InternalName: string;
begin
Result := SearchValue('InternalName');
end;
function TVersionInfo.FileVersion: string;
begin
Result := SearchValue('FileVersion');
end;
function TVersionInfo.ProductName: string;
begin
Result := SearchValue('ProductName');
end;
constructor TVersionInfo.Create;
begin
inherited Create;
FVersResource := TVersionResource.Create;
Load(HInstance);
end;
destructor TVersionInfo.Destroy;
begin
FVersResource.Free;
inherited Destroy;
end;
procedure TVersionInfo.Load(Instance: THandle);
var
Stream: TResourceStream;
begin
Stream := TResourceStream.CreateFromID(Instance, 1, PChar(RT_VERSION));
try
FVersResource.SetCustomRawDataStream(Stream);
// access some property to load from the stream
FVersResource.FixedInfo;
// clear the stream
FVersResource.SetCustomRawDataStream(nil);
finally
Stream.Free;
end;
end;
end.