4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Delphi】続・ビルドイベントについて

Last updated at Posted at 2025-12-15

はじめに

前回はビルドイベントにバッチファイルを指定しましたが、バッチファイルでは柔軟性に欠け、罠のような記述もあって可読性もよろしくないので、どうにかしたと思います。

image.png

ビルドコマンドにコンソールアプリケーションを使う

結局の所、Delphi でコンソールアプリケーションを作ってそれをビルドコマンドとして渡してやればいいのです (なんて Delphi 脳)。

deploy.exe

前回のバッチファイル deploy.bat と同等のものをこしらえてみます。

ビルドイベントの指定

bat が exe になっただけですね。

image.png

SET PROJECTNAME=$(PROJECTNAME)
SET INPUTDIR=$(INPUTDIR)
SET OUTPUTPATH=$(OUTPUTPATH)
"$(INPUTDIR)deploy.exe"

コンソールアプリケーションの準備

次のファイル (deploy.dpr) をプロジェクトフォルダに置き、

deploy.dpr
program deploy;
{$APPTYPE CONSOLE}
begin

end.

IDE の [プロジェクト | 既存プロジェクトを追加] で deploy.dpr を追加します。

image.png

ProjectGroup1 の所を右クリックしてコンテキストメニューから プロジェクトグループに名前を付けて保存 を選びます。

image.png

保存先は Project1 と同じ場所にします。

C:\EMBARCADERO\PROJECTS\BUILD TEST
    deploy.dpr
    deploy.dproj
    deploy.dproj.local
    Project1.dpr
    Project1.dproj
    Project1.dproj.local
    Project1.res
    ProjectGroup1.groupproj
    ProjectGroup1.groupproj.local
    Unit1.dfm
    Unit1.pas

コンソールアプリケーションを記述

内容は前回のバッチファイル deploy.bat を踏襲します。

deploy.dpr
program deploy;
{$APPTYPE CONSOLE}

uses
  System.SysUtils, System.IOUtils, System.Zip;

begin
  // 環境変数がセットされていなければ抜ける
  if GetEnvironmentVariable('OUTPUTPATH') = '' then
    Halt(1);
  try
    var PRJ := GetEnvironmentVariable('PROJECTNAME');
    var DST1 := TPath.Combine(GetEnvironmentVariable('INPUTDIR'), 'Deploy');
    var DST2 := TPath.Combine(DST1, 'work');
    var DST3 := TPath.Combine(DST2, PRJ); // TZipFile.ZipDirectoryContents() は指定フォルダそのものを格納しない
    var SRCEXE := GetEnvironmentVariable('OUTPUTPATH');
    var DSTEXE := TPath.Combine(DST3, TPath.GetFileName(SRCEXE));

    // 最新版 EXE を配布フォルダへコピー
    if not TDirectory.Exists(DST3) then
      TDirectory.CreateDirectory(DST3);
    TFile.Copy(SRCEXE, DSTEXE, True);

    // 既存の ZIP ファイルを削除
    for var FileName in TDirectory.GetFiles(DST1, '*.zip') do
      TFile.Delete(FileName);

    // ファイル名に使う日付時刻を EXE のタイムスタンプから取得 (_YYYYMMDD_HHNN)
    var ZIPNAME := PRJ + FormatDateTime('"_"YYYYMMDD"_"HHNN".zip"', TFile.GetLastWriteTime(DSTEXE));
    ZIPNAME := TPath.Combine(DST1, ZIPNAME);

    // ZIP ファイルを作成
    TZipFile.ZipDirectoryContents(ZIPNAME, DST2);
  except
    on E: Exception do
    begin
      Write(E.Message);
      ExitCode := 2;
    end;
  end;
end.

コードは次のような事をやっています:

  • EXE が Explorer からダブルクリックされるなどして実行されたら処理しない
  • Deploy\<プロジェクト名>\<プロジェクト名> フォルダをプロジェクトフォルダ内に作成
  • 以前に作成された ZIP ファイルは削除
  • 実行時にエラーが出たらメッセージを標準出力

deploy.dpr をコンパイルすると、同じ場所に deploy.exe が生成されます。

C:\EMBARCADERO\PROJECTS\BUILD TEST
    deploy.dpr
    deploy.dproj
    deploy.dproj.local
    deploy.exe
    deploy.res
    Project1.dpr
    Project1.dproj
    Project1.dproj.local
    Project1.res
    ProjectGroup1.groupproj
    ProjectGroup1.groupproj.local
    Unit1.dfm
    Unit1.pas

ビルドテスト

deploy.exe ができたら [プロジェクトマネージャ] で Project1 に切り替えます。

image.png

[プロジェクト | ビルド] を行い、正常に (Release) ビルドされたら プロジェクト名_YYYYMMDD_HHNN.zipDeploy サブフォルダにできているハズです。

image.png

C:\EMBARCADERO\PROJECTS\BUILD TEST
│  deploy.dpr
│  deploy.dproj
│  deploy.dproj.local
│  deploy.exe
│  deploy.res
│  Project1.dpr
│  Project1.dproj
│  Project1.dproj.local
│  Project1.res
│  ProjectGroup1.groupproj
│  ProjectGroup1.groupproj.local
│  Unit1.dfm
│  Unit1.pas
│
├─Deploy
│  │  Project_120251201_0246.zip
│  │
│  └─work
│      └─Project1
│              Project1.exe
│
└─Win32
    └─Release
            Project1.exe
            Unit1.dcu

バッチファイル版との違いは収集フォルダの階層が一段深い事です。これはフォルダを圧縮する TZipFile.ZipDirectoryContents() メソッドが指定フォルダそのものを格納しない仕様によるものです。

プロジェクトの切り替えが面倒?

配布用 EXE (deploy.exe) を作るのにプロジェクトを切り替えてビルドするのが面倒?

ちゃんとデバッグくらいはした方がいいとは思うのですが、スクリプトの書き替えみたいなお手軽さを求めるのであれば、ビルドイベントで配布用 EXE をビルドすればいいと思います! (なんて Delphi 脳)

image.png

先頭行で deploy.dpr をビルドして deploy.exe を生成しています。

DCC32 -cc "$(INPUTDIR)deploy.dpr"
SET PROJECTNAME=$(PROJECTNAME)
SET INPUTDIR=$(INPUTDIR)
SET OUTPUTPATH=$(OUTPUTPATH)
"$(INPUTDIR)deploy.exe"

Delphi の爆速コンパイラだとビルド時間が 0.1 秒増えた程度でしょうか?配布用 EXE をガチャガチャやって作り込んでる時はこれでもいいかもですね。最終的に仕様が固まったら先頭行を外すなりコメントアウトすればいいので。

おわりに

バッチファイルに比べれば、多少記述量は増えましたが、視認性は格段によくなりました。PowerShell を呼び出すオーバーヘッドもないので EXE 版の方が高速動作するのもメリットです。

TZipFile は XE2 以降で実装されているので、ZIP 圧縮を XE 以前の古いプロジェクトに組み込みたい場合には工夫が必要です。XE 以前ならバッチファイル版の方がお手軽でいいかもですね。

See also:

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?