Comment déterminer la Version de L'Application Delphi

vous voulez obtenir L'Application Delphi construisez le numéro et post dans la barre de titre

26
demandé sur Wolf 2009-11-11 23:27:28

6 réponses

Voici comment je fais. J'ai mis cela dans presque tous mes petits utilitaires:

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;
25
répondu Mick 2012-04-25 21:47:37

j'ai le plus fortement recommander de ne pas utiliser GetFileVersion lorsque vous voulez savoir la version de l'exécutable qui est actuellement en cours d'exécution! J'ai deux bonnes raisons de faire ceci:

  1. l'exécutable peut être inaccessible (disque/partage déconnecté), ou modifié (.exe renommé .bak et remplacé par un nouveau .exe sans que le processus de fonctionnement soit arrêté).
  2. la version des données que vous essayez de lire a déjà été chargée en mémoire, et est disponible pour vous en chargeant cette ressource, ce qui est toujours mieux que d'effectuer des opérations disque supplémentaires (relativement lentes).

Pour charger la version de la ressource en Delphi je utiliser un code comme ceci:

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;
21
répondu Stijn Sanders 2009-11-12 08:40:47

passer le nom complet du fichier de votre EXE à cette fonction, et il retournera une chaîne comme: 2.1.5.9, ou quelle que soit votre version #.

function GetFileVersion(exeName : string): string;
const
  c_StringInfo = 'StringFileInfo0904E4\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;

après avoir défini cela, vous pouvez l'utiliser pour définir la légende de votre formulaire comme suit:

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;
11
répondu JosephStyons 2009-12-03 13:37:43

grâce aux billets ci-dessus, j'ai créé ma propre bibliothèque à cette fin.

je crois que c'est un peu plus correcte que toutes les autres solutions ici, alors je la partage - n'hésitez pas à le réutiliser...

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.
7
répondu Jiri Krivanek 2012-06-20 08:32:45

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

Avec cette fonction, vous pouvez obtenir la version d'un fichier, qui contient une ressource de version. De cette façon, vous pouvez afficher le numéro de version de votre application dans un dialogue d'information. Pour inclure une ressource de version votre application Delphi, définissez le "Versioninfo" dans les options du projet.

2
répondu vIceBerg 2013-07-04 23:44:36

nous le faisons pour toutes nos applications mais nous utilisons un composant Raize rzversioninfo. fonctionne très bien, juste besoin d'utiliser le code suivant

sur le formulaire de créer

Légende: = RzVersioninfo1.filedescripion +': '+ RzVersionInfo1.FileVersion;

évidemment si vous ne voulez aucun des autres composants de raize utilisez l'une des options ci-dessus car il y a un coût pour les composants de raize.

1
répondu LizHanson 2009-11-12 12:24:04