Page 1 of 1

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

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

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.
Examples: "MacOS X - Your question", "MS Word - Your Tip or Trick".

Please note that switching to another language when reading a post will not work!
Posts will not have a translated counterpart.




RSS Feed

Home Forums Software Development Delphi, Lazarus, Free Pascal Lazarus – How to use (and extract) version info cross platform

This topic contains 2 replies, has 1 voice, and was last updated by  hans 2 years, 6 months ago.

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • 1722

    hans
    Keymaster

    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[i];
    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.

    2198

    hans
    Keymaster

    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[i];
          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.

    4088

    hans
    Keymaster

    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!

Viewing 3 posts - 1 through 3 (of 3 total)



You must be logged in to reply to this topic.