Page 1 of 1
Forum

Welcome to the Tweaking4All community forums!
When participating, please keep the Forum Rules in mind!

Topics for particular software or systems: Start your topic link with the name of the application or system.
For example “MacOS X – Your question“, or “MS Word – Your Tip or Trick“.

Please note that switching to another language when reading a post will not bring you to the same post, in Dutch, as there is most likely no translated for the post!





Share:
Notifications
Clear all

Lazarus - How to use (and extract) version info cross platform  

  RSS

 Hans
(@hans)
Noble Member Admin
Joined: 7 years ago
Posts: 1521
September 27, 2013 10:15 AM  

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.


ReplyQuote
 Hans
(@hans)
Noble Member Admin
Joined: 7 years ago
Posts: 1521
November 14, 2013 8:50 AM  

An improved vinfo.pas (typo in the previous version):

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.


ReplyQuote
 Hans
(@hans)
Noble Member Admin
Joined: 7 years ago
Posts: 1521
January 21, 2015 5:40 AM  

Christian Lafin has graciously offered his version to be posted on this forum , this unit uses the VersionInfo_Class unit posted above and makes a few calls easier.

unit Versionfunctions_Unit;
{$mode objfpc}{$H+}
//##############################################################################
// Autor: Christian Lafin ( http://lafin.de) //
// using VersionInfo_Class found here: //www.tweaking4all.com/forums/topic/lazarus-how-to-use-and-extract-version-info-cross-platform/
// Version: 0.1.0.1 //
// Changelog: //
// Update 1/2015, Version 0.1.0.1 , ProductNameAsString(), //
// FileVersionAsString(), //
// ProductVersionAsString //
//##############################################################################
interface
uses
  Classes, SysUtils, resource, VersionInfo_Class;
function ProductVersionAsString(): String;
function FileVersionAsString(): String;
function ProductNameAsString(): String;
implementation
function ProductNameAsString(): String;
var
   VerInfo: TVersionInfo;
begin
   VerInfo := TVersionInfo.Create();
   VerInfo.Load(HINSTANCE);
   Result := VerInfo.ProductName();
   VerInfo.Free();
end;
function FileVersionAsString(): String;
var
   VerInfo: TVersionInfo;
begin
   VerInfo := TVersionInfo.Create();
   VerInfo.Load(HINSTANCE);
   Result := IntToStr(VerInfo.FixedInfo.FileVersion[0]) + '.' + IntToStr(VerInfo.FixedInfo.FileVersion[1]) + '.' + IntToStr(VerInfo.FixedInfo.FileVersion[2]) + '.' + IntToStr(VerInfo.FixedInfo.FileVersion[3]);
   VerInfo.Free();
end;
function ProductVersionAsString(): String;
var
   VerInfo: TVersionInfo;
begin
   VerInfo := TVersionInfo.Create();
   VerInfo.Load(HINSTANCE);
   Result := IntToStr(VerInfo.FixedInfo.ProductVersion[0]) + '.' + IntToStr(VerInfo.FixedInfo.ProductVersion[1]) + '.' + IntToStr(VerInfo.FixedInfo.ProductVersion[2]) + '.' + IntToStr(VerInfo.FixedInfo.ProductVersion[3]);
   VerInfo.Free();
end;

end.

Thanks Christian!


ReplyQuote
Share: