it-swarm-ja.tech

Delphiアプリケーションのバージョンを確認する方法

Delphiアプリケーションのビルド番号を取得してタイトルバーに投稿したい

29
Link Wilson

これが私のやり方です。私はこれを私の小さなユーティリティのほとんどすべてに入れました:

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;
26
Mick

現在実行中の実行可能ファイルのバージョンを知りたい場合は、GetFileVersionを使用しないことを強くお勧めします。これには2つの理由があります。

  1. 実行可能ファイルにアクセスできない(ドライブ/共有が切断されている)か、変更されている可能性があります(.exeの名前が.bakに変更され、実行中のプロセスを停止せずに新しい.exeに置き換えられます)。
  2. 読み取ろうとしているバージョンデータは、実際には既にメモリに読み込まれており、このリソースを読み込むことで利用できます。これは、余分な(比較的遅い)ディスク操作を実行するよりも常に優れています。

Delphiにバージョンリソースをロードするには、次のようなコードを使用します。

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;
22
Stijn Sanders

EXEの完全なファイル名をこの関数に渡すと、次のような文字列が返されます:2.1.5.9、またはバージョン番号は何でもかまいません。

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;

これを定義したら、それを使用してフォームのキャプションを次のように設定できます。

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
JosephStyons

上記の投稿のおかげで、この目的のために自分のライブラリを作成しました。

ここでの他のすべてのソリューションよりも少し正しいと思いますので、私はそれを共有します-自由に再利用してください...

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.
10
Jiri Krivanek

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

この関数を使用すると、バージョンリソースを含むファイルのバージョンを取得できます。このようにして、アプリケーションのバージョン番号を情報ダイアログに表示できます。 Delphiアプリケーションにバージョンリソースを含めるには、プロジェクトオプションで「Versioninfo」を設定します。

1
vIceBerg

すべてのアプリでこれを行いますが、RaizeコンポーネントRzVersioninfoを使用します。次のコードを使用するだけで十分に機能します

フォーム作成時

キャプション:= RzVersioninfo1.filedescripion + ':' + RzVersionInfo1.FileVersion;

raizeに他のコンポーネントが必要ない場合は、raizeコンポーネントにコストがかかるため、上記のオプションのいずれかを使用してください。

1
LizHanson