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.
|
|
|