unit vinfo; {$mode objfpc} interface uses Classes, SysUtils, resource, versiontypes, versionresource; type TVersionPrecision = 1..4; { TVersionInfo } TVersionInfo = class private FVersResource: TVersionResource; function GetFixedInfo: TVersionFixedInfo; function GetStringFileInfo: TVersionStringFileInfo; function GetVarFileInfo: TVersionVarFileInfo; public constructor Create; destructor Destroy; override; procedure Load(Instance: THandle); property FixedInfo: TVersionFixedInfo read GetFixedInfo; property StringFileInfo: TVersionStringFileInfo read GetStringFileInfo; property VarFileInfo: TVersionVarFileInfo read GetVarFileInfo; //Helper functions function GetProductVersionString(AMinPrecision: TVersionPrecision = 2): String; function GetCopyright(ALong: Boolean = false): String; procedure PrintStringFileInfo; end; var VersionInfo: TVersionInfo; 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; constructor TVersionInfo.Create; begin inherited Create; FVersResource := TVersionResource.Create; 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; function TVersionInfo.GetProductVersionString(AMinPrecision: TVersionPrecision = 2): String; var productVersion: TFileProductVersion; lastVersion, i: Integer; begin productVersion := FixedInfo.ProductVersion; lastVersion := 3; while (lastVersion >= AMinPrecision) and (productVersion[lastVersion] = 0) do dec(lastVersion); Result := ''; for i := 0 to lastVersion do begin Result := Result + IntToStr(productVersion[i]); if i < lastVersion then Result := Result + '.'; end; end; function TVersionInfo.GetCopyright(ALong: Boolean = False): String; begin Result := StringFileInfo[0]['LegalCopyright']; if ALong then Result := StringReplace(Result, '(c) ', 'Copyright ', []); end; procedure TVersionInfo.PrintStringFileInfo; var verStringInfo: TVersionStringFileInfo; verStringTable: TVersionStringTable; i, j: Integer; begin verStringInfo := GetStringFileInfo; for i := 0 to verStringInfo.Count - 1 do begin writeln('Version String Info ', i + 1); verStringTable := verStringInfo.Items[i]; for j := 0 to verStringTable.Count - 1 do begin writeln(' ', verStringTable.Keys[j], ' = ', verStringTable.ValuesByIndex[j]); end; end; end; initialization VersionInfo := TVersionInfo.Create; VersionInfo.Load(HINSTANCE); finalization VersionInfo.Free; end.