16bit!

エンジニアじゃなくなっちゃった人が何かを書くブログ

【Delphi】コンパイル時にバージョン情報を付与し、フォームに表示させる

DelphiでExeのコンパイル時にファイルバージョンを付与する方法と、
付与したバージョン番号を画面に表示させる方法です。


========================================================


1.Exeのコンパイル時にバージョン情報を付与する方法
<参考>
 flow of water バージョン情報ページ

 1-1.メニューバーの「プロジェクト⇒オプション」から、「バージョン情報」タブを開く。
 1-2.「バージョン番号を含める」にチェックを入れる。
 1-3.メジャー、マイナーなどのバージョン番号を入力する。
 1-4.必要なら下部グリッドに説明やコメントなどを入れる。



これでコンパイルすれば、できたExeにはファイルバージョンが付与されているはずです。



2.Exeのバージョン情報を画面に表示する
<参考>
 Delphi Tips

 2-1.type内に、バージョン情報を扱うための構造を宣言

type
  TVerResourceKey = (
        vrComments,         // コメント
        vrCompanyName,      // 会社名
        vrFileDescription,  // 説明
        vrFileVersion,      // ファイルバージョン
        vrInternalName,     // 内部名
        vrLegalCopyright,   // 著作権
        vrLegalTrademarks,  // 商標
        vrOriginalFilename, // 正式ファイル名
        vrPrivateBuild,     // プライベートビルド情報
        vrProductName,      // 製品名
        vrProductVersion,   // 製品バージョン
        vrSpecialBuild);    // スペシャルビルド情報

 2-2.const内に、バージョン情報用StringListを宣言

const
  KeyWordStr: array [TVerResourceKey] of String = (
        'Comments',
        'CompanyName',
        'FileDescription',
        'FileVersion',
        'InternalName',
        'LegalCopyright',
        'LegalTrademarks',
        'OriginalFilename',
        'PrivateBuild',
        'ProductName',
        'ProductVersion',
        'SpecialBuild');

 2-3.バージョン情報取得用関数を作成

function GetVersionInfo(KeyWord: TVerResourceKey): string;
const
  Translation = '\VarFileInfo\Translation';
  FileInfo = '\StringFileInfo\%0.4s%0.4s\';
var
  BufSize, HWnd: DWORD;
  VerInfoBuf: Pointer;
  VerData: Pointer;
  VerDataLen: Longword;
  PathLocale: String;
begin
  // 必要なバッファのサイズを取得
  BufSize := GetFileVersionInfoSize(PChar(Application.ExeName), HWnd);
  if BufSize <> 0 then
  begin
    // メモリを確保
    GetMem(VerInfoBuf, BufSize);
    try
      GetFileVersionInfo(PChar(Application.ExeName), 0, BufSize, VerInfoBuf);
      // 変数情報ブロック内の変換テーブルを指定
      VerQueryValue(VerInfoBuf, PChar(Translation), VerData, VerDataLen);
      if not (VerDataLen > 0) then
        raise Exception.Create('情報の取得に失敗しました');
      PathLocale := Format(FileInfo + KeyWordStr[KeyWord],
        [IntToHex(Integer(VerData^) and $FFFF, 4), 
         IntToHex((Integer(VerData^) shr 16) and $FFFF, 4)]);
      VerQueryValue(VerInfoBuf, PChar(PathLocale), VerData, VerDataLen);
      if VerDataLen > 0 then
      begin
        // VerDataはゼロで終わる文字列ではないことに注意
        result := '';
        SetLength(result, VerDataLen);
        StrLCopy(PChar(result), VerData, VerDataLen);
      end;
    finally
      // 解放
      FreeMem(VerInfoBuf);
    end;
  end;
end;

 2-4.typeに宣言したキーを引数に、該当のバージョン情報を取得
 2-5.取得した文字列をCaptionなり何なりにセットする

========================================================


ふとしたことで自作ツールにバージョン情報を付与しなくてはいけなくなったので、
調べたことをついでに載せておきました。

取得関数を別のユニットに準備する場合は、
Application.ExeNameが取れないので、それも引数に加える必要があります。