Added: App.FileName property
Changed: moved version reading to TX2AppVersion, which can then be used stand-alone
This commit is contained in:
parent
863e817675
commit
d96cbe45a4
234
X2UtApp.pas
234
X2UtApp.pas
@ -87,10 +87,19 @@ type
|
|||||||
FSpecial: Boolean;
|
FSpecial: Boolean;
|
||||||
FPrivate: Boolean;
|
FPrivate: Boolean;
|
||||||
FStrings: TX2AppVersionStrings;
|
FStrings: TX2AppVersionStrings;
|
||||||
|
protected
|
||||||
|
procedure GetVersion(const AFileName: String); virtual;
|
||||||
public
|
public
|
||||||
constructor Create();
|
constructor Create(const AFileName: String);
|
||||||
destructor Destroy(); override;
|
destructor Destroy(); override;
|
||||||
|
|
||||||
|
//:$ Returns the formatted version information
|
||||||
|
//:: If ABuild is False, the return value will not include the
|
||||||
|
//:: application's Build number. If AProductName is True, the
|
||||||
|
//:: product name will be included as well.
|
||||||
|
function FormatVersion(const ABuild: Boolean = True;
|
||||||
|
const AProductName: Boolean = False): String;
|
||||||
|
|
||||||
//:$ Contains the application's Major version
|
//:$ Contains the application's Major version
|
||||||
//:! Defaults to 0 if no version information is available
|
//:! Defaults to 0 if no version information is available
|
||||||
property Major: Integer read FMajor write FMajor;
|
property Major: Integer read FMajor write FMajor;
|
||||||
@ -130,13 +139,13 @@ type
|
|||||||
TX2App = class(TObject)
|
TX2App = class(TObject)
|
||||||
private
|
private
|
||||||
FVersion: TX2AppVersion;
|
FVersion: TX2AppVersion;
|
||||||
|
FFileName: String;
|
||||||
FPath: String;
|
FPath: String;
|
||||||
FMainPath: String;
|
FMainPath: String;
|
||||||
FUserPath: String;
|
FUserPath: String;
|
||||||
protected
|
protected
|
||||||
function GetModule(const AModule: THandle): String; virtual;
|
function GetModule(const AModule: THandle): String; virtual;
|
||||||
procedure GetPath(); virtual;
|
procedure GetPath(); virtual;
|
||||||
procedure GetVersion(); virtual;
|
|
||||||
public
|
public
|
||||||
constructor Create();
|
constructor Create();
|
||||||
destructor Destroy(); override;
|
destructor Destroy(); override;
|
||||||
@ -148,6 +157,13 @@ type
|
|||||||
function FormatVersion(const ABuild: Boolean = True;
|
function FormatVersion(const ABuild: Boolean = True;
|
||||||
const AProductName: Boolean = False): String;
|
const AProductName: Boolean = False): String;
|
||||||
|
|
||||||
|
//:$ Contains the filename of the current module
|
||||||
|
//:! In DLL's and BPL's, this points to the filename of the current library.
|
||||||
|
//:! Note that for packages using X2Utils.bpl, this will point to the path
|
||||||
|
//:! of X2Utils.bpl, not the calling package! If you want the main
|
||||||
|
//:! executable's path, use the MainPath property.
|
||||||
|
property FileName: String read FFileName;
|
||||||
|
|
||||||
//:$ Contains the path to the current module
|
//:$ Contains the path to the current module
|
||||||
//:! In DLL's and BPL's, this points to the path of the current library.
|
//:! In DLL's and BPL's, this points to the path of the current library.
|
||||||
//:! Note that for packages using X2Utils.bpl, this will point to the path
|
//:! Note that for packages using X2Utils.bpl, this will point to the path
|
||||||
@ -242,11 +258,12 @@ end;
|
|||||||
{========================== TX2AppVersion
|
{========================== TX2AppVersion
|
||||||
Initialization
|
Initialization
|
||||||
========================================}
|
========================================}
|
||||||
constructor TX2AppVersion.Create;
|
constructor TX2AppVersion.Create(const AFileName: String);
|
||||||
begin
|
begin
|
||||||
inherited;
|
inherited Create();
|
||||||
|
|
||||||
FStrings := TX2AppVersionStrings.Create();
|
FStrings := TX2AppVersionStrings.Create();
|
||||||
|
GetVersion(AFileName);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TX2AppVersion.Destroy;
|
destructor TX2AppVersion.Destroy;
|
||||||
@ -257,20 +274,115 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TX2AppVersion.FormatVersion(const ABuild,
|
||||||
|
AProductName: Boolean): String;
|
||||||
|
var
|
||||||
|
sBuild: String;
|
||||||
|
|
||||||
|
begin
|
||||||
|
sBuild := '';
|
||||||
|
|
||||||
|
if ABuild then
|
||||||
|
sBuild := Format(' build %d', [Build]);
|
||||||
|
|
||||||
|
Result := '';
|
||||||
|
if AProductName then
|
||||||
|
Result := Strings.ProductName + ' ';
|
||||||
|
|
||||||
|
Result := Result + Format('v%d.%d.%d%s', [Major, Minor, Release, sBuild]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TX2AppVersion.GetVersion(const AFileName: String);
|
||||||
|
type
|
||||||
|
PLongInt = ^LongInt;
|
||||||
|
|
||||||
|
var
|
||||||
|
pInfo: PVSFixedFileInfo;
|
||||||
|
dInfo: Cardinal;
|
||||||
|
dSize: Cardinal;
|
||||||
|
dVer: Cardinal;
|
||||||
|
dTemp: Cardinal;
|
||||||
|
pBuffer: PChar;
|
||||||
|
pFile: PChar;
|
||||||
|
iCount: Integer;
|
||||||
|
iSize: Integer;
|
||||||
|
iProp: Integer;
|
||||||
|
pProps: PPropList;
|
||||||
|
pCode: PLongInt;
|
||||||
|
pValue: PChar;
|
||||||
|
aCode: array[0..1] of Word;
|
||||||
|
cName: array[0..25] of Char;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Major := 0;
|
||||||
|
Minor := 0;
|
||||||
|
Release := 0;
|
||||||
|
Build := 0;
|
||||||
|
|
||||||
|
pFile := PChar(AFileName);
|
||||||
|
dSize := GetFileVersionInfoSize(pFile, dTemp);
|
||||||
|
|
||||||
|
if dSize <> 0 then begin
|
||||||
|
GetMem(pBuffer, dSize);
|
||||||
|
|
||||||
|
try
|
||||||
|
if GetFileVersionInfo(pFile, dTemp, dSize, pBuffer) then
|
||||||
|
// Get version numbers
|
||||||
|
if VerQueryValue(pBuffer, '\', Pointer(pInfo), dInfo) then begin
|
||||||
|
Major := HiWord(pInfo^.dwFileVersionMS);
|
||||||
|
Minor := LoWord(pInfo^.dwFileVersionMS);
|
||||||
|
Release := HiWord(pInfo^.dwFileVersionLS);
|
||||||
|
Build := LoWord(pInfo^.dwFileVersionLS);
|
||||||
|
Debug := ((pInfo^.dwFileFlags and VS_FF_DEBUG) = VS_FF_DEBUG);
|
||||||
|
Prerelease := ((pInfo^.dwFileFlags and VS_FF_PRERELEASE) = VS_FF_PRERELEASE);
|
||||||
|
Special := ((pInfo^.dwFileFlags and VS_FF_SPECIALBUILD) = VS_FF_SPECIALBUILD);
|
||||||
|
Private := ((pInfo^.dwFileFlags and VS_FF_PRIVATEBUILD) = VS_FF_PRIVATEBUILD);
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Get additional version information using RTTI
|
||||||
|
VerQueryValue(pBuffer, '\VarFileInfo\Translation', Pointer(pCode), dVer);
|
||||||
|
if dVer <> 0 then begin
|
||||||
|
aCode[0] := HiWord(pCode^);
|
||||||
|
aCode[1] := LoWord(pCode^);
|
||||||
|
|
||||||
|
FillChar(cName, SizeOf(cName), #0);
|
||||||
|
wvsprintf(cName, '\StringFileInfo\%8.8lx', @aCode);
|
||||||
|
|
||||||
|
iCount := GetPropList(Strings.ClassInfo, tkStrings, nil);
|
||||||
|
iSize := iCount * SizeOf(TPropInfo);
|
||||||
|
GetMem(pProps, iSize);
|
||||||
|
|
||||||
|
try
|
||||||
|
GetPropList(Strings.ClassInfo, tkStrings, pProps);
|
||||||
|
|
||||||
|
for iProp := 0 to iCount - 1 do begin
|
||||||
|
if VerQueryValue(pBuffer, PChar(cName + '\' + pProps^[iProp]^.Name),
|
||||||
|
Pointer(pValue), dVer) then
|
||||||
|
SetStrProp(Strings, pProps[iProp], pValue);
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FreeMem(pProps, iSize);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FreeMem(pBuffer, dSize);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{================================= TX2App
|
{================================= TX2App
|
||||||
Initialization
|
Initialization
|
||||||
========================================}
|
========================================}
|
||||||
constructor TX2App.Create;
|
constructor TX2App.Create();
|
||||||
begin
|
begin
|
||||||
inherited;
|
inherited;
|
||||||
|
|
||||||
FVersion := TX2AppVersion.Create();
|
|
||||||
|
|
||||||
GetPath();
|
GetPath();
|
||||||
GetVersion();
|
FVersion := TX2AppVersion.Create(FFileName);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TX2App.Destroy;
|
destructor TX2App.Destroy();
|
||||||
begin
|
begin
|
||||||
FreeAndNil(FVersion);
|
FreeAndNil(FVersion);
|
||||||
|
|
||||||
@ -306,7 +418,8 @@ var
|
|||||||
cPath: array[0..MAX_PATH] of Char;
|
cPath: array[0..MAX_PATH] of Char;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
FPath := FixPath(ExtractFilePath(GetModule(SysInit.HInstance)));
|
FFileName := GetModule(SysInit.HInstance);
|
||||||
|
FPath := FixPath(ExtractFilePath(FFileName));
|
||||||
FMainPath := FixPath(ExtractFilePath(GetModule(0)));
|
FMainPath := FixPath(ExtractFilePath(GetModule(0)));
|
||||||
|
|
||||||
SHGetMalloc(ifMalloc);
|
SHGetMalloc(ifMalloc);
|
||||||
@ -325,105 +438,10 @@ end;
|
|||||||
{================================= TX2App
|
{================================= TX2App
|
||||||
Version
|
Version
|
||||||
========================================}
|
========================================}
|
||||||
function TX2App.FormatVersion;
|
function TX2App.FormatVersion(const ABuild: Boolean = True;
|
||||||
var
|
const AProductName: Boolean = False): String;
|
||||||
sBuild: String;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
sBuild := '';
|
Result := FVersion.FormatVersion(ABuild, AProductName);
|
||||||
|
|
||||||
if ABuild then
|
|
||||||
sBuild := Format(' build %d', [FVersion.Build]);
|
|
||||||
|
|
||||||
Result := '';
|
|
||||||
if AProductName then
|
|
||||||
Result := FVersion.Strings.ProductName + ' ';
|
|
||||||
|
|
||||||
with FVersion do
|
|
||||||
Result := Result + Format('v%d.%d.%d%s', [Major, Minor, Release, sBuild]);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure TX2App.GetVersion;
|
|
||||||
type
|
|
||||||
PLongInt = ^LongInt;
|
|
||||||
|
|
||||||
var
|
|
||||||
pInfo: PVSFixedFileInfo;
|
|
||||||
dInfo: Cardinal;
|
|
||||||
dSize: Cardinal;
|
|
||||||
dVer: Cardinal;
|
|
||||||
dTemp: Cardinal;
|
|
||||||
pBuffer: PChar;
|
|
||||||
pFile: PChar;
|
|
||||||
iCount: Integer;
|
|
||||||
iSize: Integer;
|
|
||||||
iProp: Integer;
|
|
||||||
pProps: PPropList;
|
|
||||||
pCode: PLongInt;
|
|
||||||
pValue: PChar;
|
|
||||||
aCode: array[0..1] of Word;
|
|
||||||
cName: array[0..25] of Char;
|
|
||||||
|
|
||||||
begin
|
|
||||||
with FVersion do begin
|
|
||||||
Major := 0;
|
|
||||||
Minor := 0;
|
|
||||||
Release := 0;
|
|
||||||
Build := 0;
|
|
||||||
end;
|
|
||||||
|
|
||||||
pFile := PChar(GetModule(SysInit.HInstance));
|
|
||||||
dSize := GetFileVersionInfoSize(pFile, dTemp);
|
|
||||||
|
|
||||||
if dSize <> 0 then begin
|
|
||||||
GetMem(pBuffer, dSize);
|
|
||||||
|
|
||||||
try
|
|
||||||
if GetFileVersionInfo(pFile, dTemp, dSize, pBuffer) then
|
|
||||||
// Get version numbers
|
|
||||||
with FVersion do begin
|
|
||||||
if VerQueryValue(pBuffer, '\', Pointer(pInfo), dInfo) then begin
|
|
||||||
Major := HiWord(pInfo^.dwFileVersionMS);
|
|
||||||
Minor := LoWord(pInfo^.dwFileVersionMS);
|
|
||||||
Release := HiWord(pInfo^.dwFileVersionLS);
|
|
||||||
Build := LoWord(pInfo^.dwFileVersionLS);
|
|
||||||
Debug := ((pInfo^.dwFileFlags and VS_FF_DEBUG) = VS_FF_DEBUG);
|
|
||||||
Prerelease := ((pInfo^.dwFileFlags and VS_FF_PRERELEASE) = VS_FF_PRERELEASE);
|
|
||||||
Special := ((pInfo^.dwFileFlags and VS_FF_SPECIALBUILD) = VS_FF_SPECIALBUILD);
|
|
||||||
Private := ((pInfo^.dwFileFlags and VS_FF_PRIVATEBUILD) = VS_FF_PRIVATEBUILD);
|
|
||||||
end;
|
|
||||||
|
|
||||||
// Get additional version information using RTTI
|
|
||||||
VerQueryValue(pBuffer, '\VarFileInfo\Translation', Pointer(pCode), dVer);
|
|
||||||
if dVer <> 0 then begin
|
|
||||||
aCode[0] := HiWord(pCode^);
|
|
||||||
aCode[1] := LoWord(pCode^);
|
|
||||||
|
|
||||||
FillChar(cName, SizeOf(cName), #0);
|
|
||||||
wvsprintf(cName, '\StringFileInfo\%8.8lx', @aCode);
|
|
||||||
|
|
||||||
iCount := GetPropList(FVersion.Strings.ClassInfo, tkStrings, nil);
|
|
||||||
iSize := iCount * SizeOf(TPropInfo);
|
|
||||||
GetMem(pProps, iSize);
|
|
||||||
|
|
||||||
try
|
|
||||||
GetPropList(FVersion.Strings.ClassInfo, tkStrings, pProps);
|
|
||||||
|
|
||||||
for iProp := 0 to iCount - 1 do begin
|
|
||||||
if VerQueryValue(pBuffer, PChar(cName + '\' + pProps^[iProp]^.Name),
|
|
||||||
Pointer(pValue), dVer) then
|
|
||||||
SetStrProp(FVersion.Strings, pProps[iProp], pValue);
|
|
||||||
end;
|
|
||||||
finally
|
|
||||||
FreeMem(pProps, iSize);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
finally
|
|
||||||
FreeMem(pBuffer, dSize);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user