How to determine Delphi Application Version

后端 未结 6 890
悲哀的现实
悲哀的现实 2020-12-08 04:31

Want to obtain Delphi Application build number and post into title bar

相关标签:
6条回答
  • 2020-12-08 04:57

    We do this for all our apps but we use a Raize component RzVersioninfo. works quite well just need to use the following code

    on form create

    Caption := RzVersioninfo1.filedescripion + ': ' + RzVersionInfo1.FileVersion;

    obviously if you don't want any of the other components from raize use one of the options above as there is a cost to the raize components.

    0 讨论(0)
  • 2020-12-08 05:06

    Thanks to the posts above, I made my own library for this purpose.

    I believe that it is a little bit more correct than all other solutions here, so I share it - feel free to reuse it...

    unit KkVersion;
    
    interface
    
    function FileDescription: String;
    function LegalCopyright: String;
    function DateOfRelease: String; // Proprietary
    function ProductVersion: String;
    function FileVersion: String;
    
    implementation
    
    uses
      Winapi.Windows, System.SysUtils, System.Classes, Math;
    
    (*
      function GetHeader(out AHdr: TVSFixedFileInfo): Boolean;
    
      var
      BFixedFileInfo: PVSFixedFileInfo;
      RM: TMemoryStream;
      RS: TResourceStream;
      BL: Cardinal;
    
      begin
      Result := False;
      RM := TMemoryStream.Create;
      try
      RS := TResourceStream.CreateFromID(HInstance, 1, RT_VERSION);
      try
      RM.CopyFrom(RS, RS.Size);
      finally
      FreeAndNil(RS);
      end;
    
      // Extract header
      if not VerQueryValue(RM.Memory, '\\', Pointer(BFixedFileInfo), BL) then
      Exit;
    
      // Prepare result
      CopyMemory(@AHdr, BFixedFileInfo, Math.Min(sizeof(AHdr), BL));
      Result := True;
      finally
      FreeAndNil(RM);
      end;
      end;
    *)
    
    function GetVersionInfo(AIdent: String): String;
    
    type
      TLang = packed record
        Lng, Page: WORD;
      end;
    
      TLangs = array [0 .. 10000] of TLang;
    
      PLangs = ^TLangs;
    
    var
      BLngs: PLangs;
      BLngsCnt: Cardinal;
      BLangId: String;
      RM: TMemoryStream;
      RS: TResourceStream;
      BP: PChar;
      BL: Cardinal;
      BId: String;
    
    begin
      // Assume error
      Result := '';
    
      RM := TMemoryStream.Create;
      try
        // Load the version resource into memory
        RS := TResourceStream.CreateFromID(HInstance, 1, RT_VERSION);
        try
          RM.CopyFrom(RS, RS.Size);
        finally
          FreeAndNil(RS);
        end;
    
        // Extract the translations list
        if not VerQueryValue(RM.Memory, '\\VarFileInfo\\Translation', Pointer(BLngs), BL) then
          Exit; // Failed to parse the translations table
        BLngsCnt := BL div sizeof(TLang);
        if BLngsCnt <= 0 then
          Exit; // No translations available
    
        // Use the first translation from the table (in most cases will be OK)
        with BLngs[0] do
          BLangId := IntToHex(Lng, 4) + IntToHex(Page, 4);
    
        // Extract field by parameter
        BId := '\\StringFileInfo\\' + BLangId + '\\' + AIdent;
        if not VerQueryValue(RM.Memory, PChar(BId), Pointer(BP), BL) then
          Exit; // No such field
    
        // Prepare result
        Result := BP;
      finally
        FreeAndNil(RM);
      end;
    end;
    
    function FileDescription: String;
    begin
      Result := GetVersionInfo('FileDescription');
    end;
    
    function LegalCopyright: String;
    begin
      Result := GetVersionInfo('LegalCopyright');
    end;
    
    function DateOfRelease: String;
    begin
      Result := GetVersionInfo('DateOfRelease');
    end;
    
    function ProductVersion: String;
    begin
      Result := GetVersionInfo('ProductVersion');
    end;
    
    function FileVersion: String;
    begin
      Result := GetVersionInfo('FileVersion');
    end;
    
    end.
    
    0 讨论(0)
  • 2020-12-08 05:07

    Pass the full file name of your EXE to this function, and it will return a string like: 2.1.5.9, or whatever your version # is.

    function GetFileVersion(exeName : string): string;
    const
      c_StringInfo = 'StringFileInfo\040904E4\FileVersion';
    var
      n, Len : cardinal;
      Buf, Value : PChar;
    begin
      Result := '';
      n := GetFileVersionInfoSize(PChar(exeName),n);
      if n > 0 then begin
        Buf := AllocMem(n);
        try
          GetFileVersionInfo(PChar(exeName),0,n,Buf);
          if VerQueryValue(Buf,PChar(c_StringInfo),Pointer(Value),Len) then begin
            Result := Trim(Value);
          end;
        finally
          FreeMem(Buf,n);
        end;
      end;
    end;
    

    After defining that, you can use it to set your form's caption like so:

    procedure TForm1.FormShow(Sender: TObject);
    begin 
      //ParamStr(0) is the full path and file name of the current application
      Form1.Caption := Form1.Caption + ' version ' + GetFileVersion(ParamStr(0));
    end;
    
    0 讨论(0)
  • 2020-12-08 05:20

    Here is how I do it. I put this in almost all of my small utilities:

    procedure GetBuildInfo(var V1, V2, V3, V4: word);
    var
      VerInfoSize, VerValueSize, Dummy: DWORD;
      VerInfo: Pointer;
      VerValue: PVSFixedFileInfo;
    begin
      VerInfoSize := GetFileVersionInfoSize(PChar(ParamStr(0)), Dummy);
      if VerInfoSize > 0 then
      begin
          GetMem(VerInfo, VerInfoSize);
          try
            if GetFileVersionInfo(PChar(ParamStr(0)), 0, VerInfoSize, VerInfo) then
            begin
              VerQueryValue(VerInfo, '\', Pointer(VerValue), VerValueSize);
              with VerValue^ do
              begin
                V1 := dwFileVersionMS shr 16;
                V2 := dwFileVersionMS and $FFFF;
                V3 := dwFileVersionLS shr 16;
                V4 := dwFileVersionLS and $FFFF;
              end;
            end;
          finally
            FreeMem(VerInfo, VerInfoSize);
          end;
      end;
    end;
    
    function GetBuildInfoAsString: string;
    var
      V1, V2, V3, V4: word;
    begin
      GetBuildInfo(V1, V2, V3, V4);
      Result := IntToStr(V1) + '.' + IntToStr(V2) + '.' +
        IntToStr(V3) + '.' + IntToStr(V4);
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      Form1.Caption := Form1.Caption + ' - v' + GetBuildInfoAsString;
    end;
    
    0 讨论(0)
  • 2020-12-08 05:20

    I most strongly recommend not to use GetFileVersion when you want to know the version of the executable that is currently running! I have two pretty good reasons to do this:

    1. The executable may be unaccessible (disconnected drive/share), or changed (.exe renamed to .bak and replaced by a new .exe without the running process being stopped).
    2. The version data you're trying to read has actually already been loaded into memory, and is available to you by loading this resource, which is always better than to perform extra (relatively slow) disk operations.

    To load the version resource in Delphi I use code like this:

    uses Windows,Classes,SysUtils;
    var
      verblock:PVSFIXEDFILEINFO;
      versionMS,versionLS:cardinal;
      verlen:cardinal;
      rs:TResourceStream;
      m:TMemoryStream;
      p:pointer;
      s:cardinal;
    begin
      m:=TMemoryStream.Create;
      try
        rs:=TResourceStream.CreateFromID(HInstance,1,RT_VERSION);
        try
          m.CopyFrom(rs,rs.Size);
        finally
          rs.Free;
        end;
        m.Position:=0;
        if VerQueryValue(m.Memory,'\',pointer(verblock),verlen) then
          begin
            VersionMS:=verblock.dwFileVersionMS;
            VersionLS:=verblock.dwFileVersionLS;
            AppVersionString:=Application.Title+' '+
              IntToStr(versionMS shr 16)+'.'+
              IntToStr(versionMS and $FFFF)+'.'+
              IntToStr(VersionLS shr 16)+'.'+
              IntToStr(VersionLS and $FFFF);
          end;
        if VerQueryValue(m.Memory,PChar('\\StringFileInfo\\'+
          IntToHex(GetThreadLocale,4)+IntToHex(GetACP,4)+'\\FileDescription'),p,s) or
            VerQueryValue(m.Memory,'\\StringFileInfo\\040904E4\\FileDescription',p,s) then //en-us
              AppVersionString:=PChar(p)+' '+AppVersionString;
      finally
        m.Free;
      end;
    end;
    
    0 讨论(0)
  • 2020-12-08 05:20

    From http://www.martinstoeckli.ch/delphi/delphi.html#AppVersion

    With this function you can get the version of a file, which contains a version resource. This way you can display the version number of your application in an information dialog. To include a version resource to your Delphi application, set the "Versioninfo" in the project options.

    0 讨论(0)
提交回复
热议问题