333 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			333 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
Unit uversion;
 | 
						|
 | 
						|
{$mode objfpc}
 | 
						|
 | 
						|
Interface
 | 
						|
 | 
						|
(*
 | 
						|
  Building on the excellent vinfo.pas supplied by Paul Ishenin and available elsewhere on these Lazarus
 | 
						|
  Forums
 | 
						|
    - I hid the TVersionInfo class from the end user to simplify their (mine) number of required Uses...
 | 
						|
    - Added defensive code to TVersionInfo if no build info is compiled into the exe
 | 
						|
    - Deduced GetResourceStrings - works under Linux 64/GTK2 with Lazarus 0.9.30, but fails under
 | 
						|
      Win XP 32bit/Lazarus 0.9.29 - suspecting my install as the lazresexplorer example also fails
 | 
						|
      for me under Lazarus 0.9.29, but works with Lazarus 0.9.30
 | 
						|
 | 
						|
  Trawled through IDE source code, FPC source code and Lazarus supplied example program lasresexplorer
 | 
						|
  to find the other defines and lookups...
 | 
						|
 | 
						|
  End user only needs to use uVersion - no other units necessary for their project.
 | 
						|
 | 
						|
  Jedi CodeFormatter seems to fail on the {$I %VARIABLE%} references, so sticking them all in here
 | 
						|
  means end user code can be neatly formatted using Jedi CodeFormatter
 | 
						|
 | 
						|
  Other interesting includes I picked up in my travels are...
 | 
						|
  //  {$I %HOME%} = User Home Directory
 | 
						|
  //  {$I %FILE%} = Current pas file
 | 
						|
  //  {$I %LINE%} = current line number
 | 
						|
 | 
						|
  Mike Thompson - mike.cornflake@gmail.com
 | 
						|
  July 24 2011
 | 
						|
*)
 | 
						|
 | 
						|
Uses
 | 
						|
  Classes, SysUtils,FPCAdds;
 | 
						|
 | 
						|
Function GetFileVersion: String;
 | 
						|
Function GetProductVersion: String;
 | 
						|
 | 
						|
Function GetMajorProductVersion: Cardinal;
 | 
						|
Function GetMinorProductVersion: Cardinal;
 | 
						|
Function GetRevisionProductVersion: Cardinal;
 | 
						|
Function GetBuildProductVersion: Cardinal;
 | 
						|
 | 
						|
Function GetCompiledDate: String;
 | 
						|
Function GetCompilerInfo: String;
 | 
						|
Function GetTargetInfo: String;
 | 
						|
Function GetOS: String;
 | 
						|
Function GetResourceStrings(oStringList : TStringList) : Boolean;
 | 
						|
Function GetLCLVersion: String;
 | 
						|
function GetWidgetSet: string;
 | 
						|
function Reload(Inst:THandle):Boolean;
 | 
						|
function GetLocalizedBuildDate(): string;
 | 
						|
 | 
						|
Const
 | 
						|
  WIDGETSET_GTK        = 'GTK widget set';
 | 
						|
  WIDGETSET_GTK2       = 'GTK 2 widget set';
 | 
						|
  WIDGETSET_WIN        = 'Win32/Win64 widget set';
 | 
						|
  WIDGETSET_WINCE      = 'WinCE widget set';
 | 
						|
  WIDGETSET_CARBON     = 'Carbon widget set';
 | 
						|
  WIDGETSET_QT         = 'QT widget set';
 | 
						|
  WIDGETSET_fpGUI      = 'fpGUI widget set';
 | 
						|
  WIDGETSET_OTHER      = 'Other gui';
 | 
						|
 | 
						|
Implementation
 | 
						|
 | 
						|
Uses
 | 
						|
  resource, versiontypes, versionresource, LCLVersion, InterfaceBase;
 | 
						|
 | 
						|
Type
 | 
						|
  TVersionInfo = Class
 | 
						|
  private
 | 
						|
    FBuildInfoAvailable: Boolean;
 | 
						|
    FVersResource: TVersionResource;
 | 
						|
    Function GetFixedInfo: TVersionFixedInfo;
 | 
						|
    Function GetStringFileInfo: TVersionStringFileInfo;
 | 
						|
    Function GetVarFileInfo: TVersionVarFileInfo;
 | 
						|
  public
 | 
						|
    Constructor Create;
 | 
						|
    Destructor Destroy; override;
 | 
						|
 | 
						|
    Procedure Load(Instance: THandle);
 | 
						|
 | 
						|
    Property BuildInfoAvailable: Boolean Read FBuildInfoAvailable;
 | 
						|
 | 
						|
    Property FixedInfo: TVersionFixedInfo Read GetFixedInfo;
 | 
						|
    Property StringFileInfo: TVersionStringFileInfo Read GetStringFileInfo;
 | 
						|
    Property VarFileInfo: TVersionVarFileInfo Read GetVarFileInfo;
 | 
						|
  End;
 | 
						|
 | 
						|
  {The compiler generated date string is always of the form y/m/d.
 | 
						|
   This function gives it a string respresentation according to the
 | 
						|
   shortdateformat}
 | 
						|
  function GetLocalizedBuildDate(): string;
 | 
						|
  var
 | 
						|
    BuildDate: string;
 | 
						|
    SlashPos1, SlashPos2: integer;
 | 
						|
    Date: TDateTime;
 | 
						|
  begin
 | 
						|
    BuildDate := {$I %date%};
 | 
						|
    SlashPos1 := Pos('/',BuildDate);
 | 
						|
    SlashPos2 := SlashPos1 +
 | 
						|
      Pos('/', Copy(BuildDate, SlashPos1+1, Length(BuildDate)-SlashPos1));
 | 
						|
    Date := EncodeDate(StrToWord(Copy(BuildDate,1,SlashPos1-1)),
 | 
						|
      StrToWord(Copy(BuildDate,SlashPos1+1,SlashPos2-SlashPos1-1)),
 | 
						|
      StrToWord(Copy(BuildDate,SlashPos2+1,Length(BuildDate)-SlashPos2)));
 | 
						|
    Result := FormatDateTime('yyyy-mm-dd', Date);
 | 
						|
  end;
 | 
						|
function GetWidgetSet: string;
 | 
						|
begin
 | 
						|
  case WidgetSet.LCLPlatform of
 | 
						|
    lpGtk:   Result := WIDGETSET_GTK;
 | 
						|
    lpGtk2:  Result := WIDGETSET_GTK2;
 | 
						|
    lpWin32: Result := WIDGETSET_WIN;
 | 
						|
    lpWinCE: Result := WIDGETSET_WINCE;
 | 
						|
    lpCarbon:Result := WIDGETSET_CARBON;
 | 
						|
    lpQT:    Result := WIDGETSET_QT;
 | 
						|
    lpfpGUI: Result := WIDGETSET_fpGUI;
 | 
						|
  else
 | 
						|
    Result:=WIDGETSET_OTHER;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
Function GetCompilerInfo: String;
 | 
						|
begin
 | 
						|
  Result := 'FPC '+{$I %FPCVERSION%};
 | 
						|
end;
 | 
						|
 | 
						|
Function GetTargetInfo: String;
 | 
						|
begin
 | 
						|
  Result := {$I %FPCTARGETCPU%}+' - '+{$I %FPCTARGETOS%};
 | 
						|
end;
 | 
						|
 | 
						|
Function GetOS: String;
 | 
						|
Begin
 | 
						|
  Result := {$I %FPCTARGETOS%};
 | 
						|
End;
 | 
						|
 | 
						|
Function GetLCLVersion: String;
 | 
						|
begin
 | 
						|
  Result := 'LCL '+ lcl_version;
 | 
						|
end;
 | 
						|
 | 
						|
Function GetCompiledDate: String;
 | 
						|
Var
 | 
						|
  sDate, sTime: String;
 | 
						|
Begin
 | 
						|
  sDate := GetLocalizedBuildDate; //{$I %DATE%};
 | 
						|
  sTime := {$I %TIME%};
 | 
						|
 | 
						|
  Result := sDate + ' at ' + sTime;
 | 
						|
End;
 | 
						|
 | 
						|
{ Routines to expose TVersionInfo data }
 | 
						|
 | 
						|
Var
 | 
						|
  FInfo: TVersionInfo;
 | 
						|
 | 
						|
Procedure CreateInfo;
 | 
						|
Begin
 | 
						|
  If Not Assigned(FInfo) Then
 | 
						|
  Begin
 | 
						|
    FInfo := TVersionInfo.Create;
 | 
						|
    FInfo.Load(HINSTANCE);
 | 
						|
  End;
 | 
						|
End;
 | 
						|
 | 
						|
Function GetResourceStrings(oStringList: TStringList): Boolean;
 | 
						|
Var
 | 
						|
  i, j : Integer;
 | 
						|
  oTable : TVersionStringTable;
 | 
						|
begin
 | 
						|
  CreateInfo;
 | 
						|
 | 
						|
  oStringList.Clear;
 | 
						|
  Result := False;
 | 
						|
 | 
						|
  If FInfo.BuildInfoAvailable Then
 | 
						|
  Begin
 | 
						|
    Result := True;
 | 
						|
    For i := 0 To FInfo.StringFileInfo.Count-1 Do
 | 
						|
    Begin
 | 
						|
      oTable := FInfo.StringFileInfo.Items[i];
 | 
						|
 | 
						|
      For j := 0 To oTable.Count-1 Do
 | 
						|
        If Trim(oTable.ValuesByIndex[j])<>'' Then
 | 
						|
          oStringList.Values[oTable.Keys[j]] := oTable.ValuesByIndex[j];
 | 
						|
    end;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
Function ProductVersionToString(PV: TFileProductVersion): String;
 | 
						|
Begin
 | 
						|
  Result := Format('%d.%d.%d.%d', [PV[0], PV[1], PV[2], PV[3]]);
 | 
						|
End;
 | 
						|
 | 
						|
Function GetMajorProductVersion: Cardinal;
 | 
						|
Begin
 | 
						|
  CreateInfo;
 | 
						|
 | 
						|
  If FInfo.BuildInfoAvailable Then
 | 
						|
    Result := FInfo.FixedInfo.ProductVersion[0]
 | 
						|
  Else
 | 
						|
    Result := 0;
 | 
						|
End;
 | 
						|
 | 
						|
Function GetMinorProductVersion: Cardinal;
 | 
						|
Begin
 | 
						|
  CreateInfo;
 | 
						|
 | 
						|
  If FInfo.BuildInfoAvailable Then
 | 
						|
    Result := FInfo.FixedInfo.ProductVersion[1]
 | 
						|
  Else
 | 
						|
    Result := 0;
 | 
						|
End;
 | 
						|
Function GetRevisionProductVersion: Cardinal;
 | 
						|
Begin
 | 
						|
  CreateInfo;
 | 
						|
 | 
						|
  If FInfo.BuildInfoAvailable Then
 | 
						|
    Result := FInfo.FixedInfo.ProductVersion[2]
 | 
						|
  Else
 | 
						|
    Result := 0;
 | 
						|
End;
 | 
						|
Function GetBuildProductVersion: Cardinal;
 | 
						|
Begin
 | 
						|
  CreateInfo;
 | 
						|
 | 
						|
  If FInfo.BuildInfoAvailable Then
 | 
						|
    Result := FInfo.FixedInfo.ProductVersion[3]
 | 
						|
  Else
 | 
						|
    Result := 0;
 | 
						|
End;
 | 
						|
 | 
						|
Function GetProductVersion: String;
 | 
						|
Begin
 | 
						|
  CreateInfo;
 | 
						|
 | 
						|
  If FInfo.BuildInfoAvailable Then
 | 
						|
    Result := ProductVersionToString(FInfo.FixedInfo.ProductVersion)
 | 
						|
  Else
 | 
						|
    Result := 'No build information available';
 | 
						|
End;
 | 
						|
{%H-}Function Reload(Inst:THandle):Boolean;
 | 
						|
begin
 | 
						|
     FreeAndNil(FInfo);
 | 
						|
     If Not Assigned(FInfo) Then
 | 
						|
     Begin
 | 
						|
          FInfo := TVersionInfo.Create;
 | 
						|
          FInfo.Load(Inst);
 | 
						|
     End;
 | 
						|
end;
 | 
						|
 | 
						|
Function GetFileVersion: String;
 | 
						|
Begin
 | 
						|
  CreateInfo;
 | 
						|
 | 
						|
  If FInfo.BuildInfoAvailable Then
 | 
						|
    Result := ProductVersionToString(FInfo.FixedInfo.FileVersion)
 | 
						|
  Else
 | 
						|
    Result := 'No build information available';
 | 
						|
End;
 | 
						|
 | 
						|
{ 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;
 | 
						|
 | 
						|
Constructor TVersionInfo.Create;
 | 
						|
Begin
 | 
						|
  Inherited Create;
 | 
						|
 | 
						|
  FVersResource := TVersionResource.Create;
 | 
						|
  FBuildInfoAvailable := False;
 | 
						|
End;
 | 
						|
 | 
						|
Destructor TVersionInfo.Destroy;
 | 
						|
Begin
 | 
						|
  FVersResource.Free;
 | 
						|
 | 
						|
  Inherited Destroy;
 | 
						|
End;
 | 
						|
 | 
						|
Procedure TVersionInfo.Load(Instance: THandle);
 | 
						|
Var
 | 
						|
  Stream: TResourceStream;
 | 
						|
  ResID: Integer;
 | 
						|
  Res: TFPResourceHandle;
 | 
						|
Begin
 | 
						|
  FBuildInfoAvailable := False;
 | 
						|
  ResID := 1;
 | 
						|
 | 
						|
  // Defensive code to prevent failure if no resource available...
 | 
						|
  Res := FindResource(Instance, {%H-}PChar(PtrInt(ResID)), {%H-}PChar(RT_VERSION));
 | 
						|
  If Res = 0 Then
 | 
						|
    Exit;
 | 
						|
 | 
						|
  Stream := TResourceStream.CreateFromID(Instance, ResID, PChar(RT_VERSION));
 | 
						|
  Try
 | 
						|
    FVersResource.SetCustomRawDataStream(Stream);
 | 
						|
 | 
						|
    // access some property to load from the stream
 | 
						|
    FVersResource.FixedInfo;
 | 
						|
 | 
						|
    // clear the stream
 | 
						|
    FVersResource.SetCustomRawDataStream(nil);
 | 
						|
 | 
						|
    FBuildInfoAvailable := True;
 | 
						|
  Finally
 | 
						|
    Stream.Free;
 | 
						|
  End;
 | 
						|
End;
 | 
						|
 | 
						|
Initialization
 | 
						|
  FInfo := nil;
 | 
						|
 | 
						|
Finalization
 | 
						|
  If Assigned(FInfo) Then
 | 
						|
    FInfo.Free;
 | 
						|
End.
 | 
						|
 |