四方山話/MSBuildで定型作業を自動化

Last-modified: 2016-02-24 (水) 13:28:39

はじめに

吉里吉里/KAGでのゲーム制作では、定型作業を何度も繰り返す局面が多い。ここでは(.NET Framework同梱の)MSBuildを使って、定型作業(リリース*1、署名、ZIP圧縮、インストーラ作成)を自動化する方法を説明する。

なお、Inno Setup 5用MSBuildカスタムタスクについてはMSBuildを参照のこと。

使い方

事前準備

.NET Framework 4のインストール(まだインストールしていない場合)

.NET Framework 4は.NET Frameworkデベロッパーセンターからダウンロードし、インストールする。

MSBuild Extension Pack、7-Zipコンソール版、Info-Zipコンソール版、DotNetZipのインストール(必要に応じて)

ZIP圧縮する必要がある場合は、MSBuild Extension Pack 4.0.6.07-Zip 9.20Info-Zip(Zip 3.0)DotNetZip 1.9.1.8のいずれかをインストールする。*2

  • MSBuild Extension Pack 4.0.6.0の場合
    • MSBuild Extension Pack October 2012.zipを解凍し、できたMSBuild Extension Pack 4.0.6.0 Installers.zipをさらに解凍して、できたMSI形式ファイルをインストールする
  • 7-Zip 9.20の場合
    • Windows用のコマンドラインバージョン(7za920.zip)をダウンロードし、解凍してできた実行形式ファイル(7za.exe)をパスの通ったフォルダにコピーする
  • Info-Zip(Zip 3.0)の場合
    • Windows用のZip(zip300xn.zip)をダウンロードし、解凍してできた実行形式ファイル(zip.exe)をパスの通ったフォルダにコピーする
  • DotNetZip 1.9.1.8の場合
    • ランタイムのMSI形式ファイル(DotNetZip-Runtime-v1.9.msi)をダウンロードし、インストールする
      • ランタイムのZIP形式ファイルをダウンロードし、解凍してできたIonic.Zip.dllを make.proj (後述)と同じフォルダにコピーしても良い

Inno Setup 5のインストール(必要に応じて)

インストーラを作る必要がある場合は、jrsoftware.orgからInno Setup 5.5.0(Unicode版)をダウンロードし、インストールする。

後述の インストーラ作成2.bat を利用する場合は、Inno Setup 5インストール時にISPP(Inno Setup Preprocessor)の追加インストールを推奨。*3

ツールのダウンロード

下のダウンロードからツールをダウンロードし、任意のフォルダに解凍する。

Property.Targets の作成

  1. (解凍してできたフォルダ内にある) Kiri2Build.exe を実行する
  2. [吉里吉里2/KAG3の解凍先フォルダ]を指定する。ここで、解凍先フォルダとは、吉里吉里2/KAG3の圧縮アーカイブファイル(kr2_232r2.zipとか)を解凍した際に作られたフォルダのことで、gpl-2e-plain.txtやlicense.txtがあるフォルダを意味している
  3. [プロジェクト名]を指定する
  4. [プロジェクトフォルダ]でリリース対象のプロジェクトフォルダを指定する
  5. 必要に応じて[追加ファイルのあるフォルダ]を指定する。改名した吉里吉里2, *.cf, ファイル破損チェックツール.ini, README.txtなどが置いてあるフォルダを想定している
  6. [リリース先フォルダ]を指定する
  7. 必要に応じて[秘密鍵ファイル]を指定する
  8. [実行に必要な吉里吉里プラグイン]をチェックする。この項目は正しい[吉里吉里2/KAG3の解凍先フォルダ]を指定するとチェックできるようになる
  9. 必要に応じて[分割リリースする]をチェックする
  10. [作成]を選択する。成功したら Kiri2Build.exe と同じフォルダに Property.Targets が作成される(既存の Property.Targets は上書きされる)

なお、フォルダ、ファイルは隣の[...]ボタンから選択することも、エクスプローラからドラッグ&ドロップすることもできる。

定型作業の自動化

準備が済んだら、以降、バッチファイルを実行するだけで定型作業を自動化できる。

実行(ビルドあり)

  • エクスプローラから 実行(ビルドあり).bat を実行する。

[プロジェクトフォルダ]をリリースし、[リリース先フォルダ]内でゲームが実行できる状態にし、ゲームを実行する。

実行(ビルドなし)

  • エクスプローラから 実行(ビルドなし).bat を実行する。

吉里吉里を起動し、[プロジェクトフォルダ]を実行させる(リリースはしない)。ゲーム制作中はもっとも実行回数が多いだろう。

ビルド

  • エクスプローラから ビルド.bat を実行する。

[プロジェクトフォルダ]をリリースし、[リリース先フォルダ]内でゲームが実行できる状態にする。

署名

  • エクスプローラから 署名.bat を実行する。

ビルド後、署名ファイル(.sig)を作成し、ファイル破損チェックができる状態にする。この状態のファイルを(圧縮アーカイブにするなりインストーラにするなりして)配布することになる。

署名後タイムスタンプ変更

  • エクスプローラから 後タイムスタンプ変更.bat を実行する。

ビルド後、署名ファイル(.sig)を作成し、ファイルのタイムスタンプを0時に変更する(.exe、.dll、.tpmファイルを除く)。

クリーンアップ

  • エクスプローラから クリーンアップ.bat を実行する

[リリース先フォルダ]内のファイルを全て削除する。なお、[リリース先フォルダ]下にsavedataフォルダやpluginフォルダなどがあった場合、これも削除の対象となる。

リビルド

  • エクスプローラから リビルド.bat を実行する

クリーンアップ後、ビルドを行う。

圧縮

[リリース先フォルダ]以下をZIP圧縮する。圧縮アーカイブファイルは Compression フォルダ下にできる。

MSBuild Extension Packの場合

  • エクスプローラから 圧縮(ExtPack).bat を実行する

7-Zipの場合

  • エクスプローラから 圧縮(7-Zip).bat を実行する

Info-Zipの場合

  • エクスプローラから 圧縮(Info-Zip).bat を実行する

DotNetZipの場合

  • エクスプローラから 圧縮(DotNetZip).bat を実行する

インストーラ作成

Inno Setupスクリプト(.iss)を作成し、コンパイルする。.issファイルおよび.guidファイル(AppIdを保持している)は Installer フォルダ下に、インストーラは Installer\Output フォルダ下にできる。

簡易版インストーラ作成

  • エクスプローラから インストーラ作成.bat を実行する。

詳細設定版インストーラ作成

  • エクスプローラから インストーラ作成2.bat を実行する。

事前に、 SetupHeader.txt を各自のアプリケーションの仕様に合わせて修正すること(修正しないとエラー終了するようにしてある)。なお、同梱の SetupHeader.txt はISPP(Inno Setup Preprocessor)の追加インストールを前提とした作りになっているので注意のこと。

パッチ作成

  • エクスプローラから パッチ作成.bat を実行する。この時、更新版プロジェクトフォルダの入力を促すのでパスを入力のこと。

更新版プロジェクトフォルダとの差分ファイルを抽出し、patch.xp3を作成する。patch.xp3は Patch フォルダ下に、差分ファイルは Patch\Update フォルダ下にできる。

ダウンロード

圧縮アーカイブファイルには、以下のファイルが含まれている。

  • InnoSetup5Task.dll … Inno Setup 5用カスタムタスク
  • InnoSetup5Task.targets … make.projから呼び出されるプロジェクトファイル
  • Kiri2Build.exe … Property.Targets を生成するツール
  • MSBuild.bat … MSBuildを起動するバッチファイル
  • Krkr2Task.dll … 吉里吉里用MSBuildカスタムタスク
  • Krkr2Task.targets … make.projから呼び出されるプロジェクトファイル
  • ZipTask.targets … make.projから呼び出されるプロジェクトファイル
  • SetupHeader.txt
  • インストーラ作成.bat
  • インストーラ作成2.bat
  • クリーンアップ.bat
  • パッチ作成.bat
  • ビルド.bat
  • リビルド.bat
  • 圧縮(7-Zip).bat
  • 圧縮(DotNetZip).bat
  • 圧縮(ExtPack).bat
  • 圧縮(Info-Zip).bat
  • 実行(ビルドあり).bat
  • 実行(ビルドなし).bat
  • 署名.bat
  • 署名後タイムスタンプ変更.bat
  • make.proj … MSBuildが読み込むプロジェクトファイル
  • Krkr2Task フォルダ … Kiri2Build.exe のソースファイル(Visual C# .NET / SharpDevelop 4.2.2)
  • Kiri2Build フォルダ以下 … Kiri2Build.exe のソースファイル(Visual Basic .NET / SharpDevelop 4.2)

Krkr2Task.Targets

Krkr2Task.Targets / Krkr2Task.dll はMSBuildに以下のタスクを追加する。

Krkr2Relタスク

吉里吉里Releaser(krkrrel.exe)を実行し、プロジェクトフォルダをリリースする。

属性読込書込説明備考
DirectoryString×指定必須。吉里吉里2/KAG3のプロジェクトフォルダ名を指定する
Xp3ArchiveString×リリース後のXP3アーカイブファイル名を指定する省略時はdefault.rpfの設定に従ってリリースする
ProfileString×リリース時に読み込むプロファイル名を指定する
WriteProfileBoolean×リリース終了時にdefault.rpfを書き出すならTrue、書き出さないならFalseを指定する省略時はTrue
ExitCodeInt32×Krkr2Relタスクの出力パラメータとして、krkrrel.exeの終了コードを返す

Krkr2Signタスク

キー・署名ツール(krkrsign.exe)を実行し、署名対象ファイルを秘密鍵で署名する。

明示的に除去しなければ、.sig, .ksd, .kdt, .cfu, .kep, .bmpファイルも署名してしまうので注意。

属性参照更新説明備考
FileString×指定必須。署名対象のファイルのパスを指定する
SecretKeyString×指定必須。キー・署名ツールで作成した秘密鍵ファイル名を指定する

FindUpdatedFilesタスク

新旧のプロジェクトフォルダを比較し、追加・更新されたファイルを抽出するインラインタスク。

属性読込書込説明
OldDirectoryString×指定必須。吉里吉里2/KAG3の旧プロジェクトフォルダ名を指定する
NewDirectoryString×指定必須。吉里吉里2/KAG3の新プロジェクトフォルダ名を指定する
UpdatedFilesITaskItem[]×FindUpdatedFilesタスクの出力パラメータとして、追加・更新されたファイルを返す
<?xml version="1.0" encoding="UTF-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- プロパティの設定(この値を変更してください) -->
  <PropertyGroup>
    <!-- 吉里吉里2/KAG3圧縮アーカイブファイルの解凍先フォルダ -->
    <KRKR2_HOME>C:\kirikiri_kag</KRKR2_HOME>
    <!--
      Krkr2Task.dllが実行するkrkrrel.exe, krkrsign.exeは以下の順番で決まる:
      ①プロパティKRKR2_HOMEが設定されている場合、$(KRKR2_HOME)\kirikiri2\toolsフォルダのkrkrrel.exe, krkrsign.exeを実行する
      ②環境変数KRKR2_HOMEが設定されている場合、%KRKR2_HOME%\kirikiri2\toolsフォルダのkrkrrel.exe, krkrsign.exeを実行する
      ③どちらも設定されていない場合、環境変数PATHの設定に従ってkrkrrel.exe, krkrsign.exeを実行する
    -->
    <!-- Krkr2Task.dllのあるフォルダ -->
    <KRKR2TASK_FOLDER>C:\CustomTask</KRKR2TASK_FOLDER>
    <!-- プロジェクトフォルダ -->
    <PROJECT_FOLDER>C:\MyProject</PROJECT_FOLDER>
    <!-- リリース先フォルダ -->
    <RELEASE_FOLDER>C:\Release</RELEASE_FOLDER>
    <!-- 秘密鍵ファイル -->
    <PRIVATE_KEY>C:\Sign\private_key.txt</PRIVATE_KEY>
    <!-- XP3アーカイブファイル -->
    <ARCHIVE_FILE>$(RELEASE_FOLDER)\data.xp3</ARCHIVE_FILE>
  </PropertyGroup>
  <!-- 使用するアセンブリとタスク名を宣言 -->
  <UsingTask AssemblyFile="$(KRKR2TASK_FOLDER)\Krkr2Task.dll" TaskName="Krkr2Rel"/>
  <UsingTask AssemblyFile="$(KRKR2TASK_FOLDER)\Krkr2Task.dll" TaskName="Krkr2Sign"/>
  <!-- Buildターゲット -->
  <Target Name="Build">
    <!-- リリース -->
    <Krkr2Rel Directory="$(PROJECT_FOLDER)" Xp3Archive="$(ARCHIVE_FILE)" />
    <!-- 署名 -->
    <ItemGroup>
      <SIGN_FILES Include="$(RELEASE_FOLDER)\**\*.*" Exclude="$(RELEASE_FOLDER)\savedata\*.*" />
    </ItemGroup>
    <Krkr2Sign File="%(SIGN_FILES.Identity)" SecretKey="$(PRIVATE_KEY)" />
  </Target>
</Project>

プロパティKRKR2_HOME、環境変数KRKR2_HOME

Krkr2Task.dllが実行するkrkrrel.exe, krkrsign.exeは以下の順番で決まる:

  1. プロパティKRKR2_HOMEが設定されている場合、$(KRKR2_HOME)\kirikiri2\toolsフォルダのkrkrrel.exe, krkrsign.exeを実行する
  2. 環境変数KRKR2_HOMEが設定されている場合、%KRKR2_HOME%\kirikiri2\toolsフォルダのkrkrrel.exe, krkrsign.exeを実行する
  3. どちらも設定されていない場合、環境変数PATHの設定に従ってkrkrrel.exe, krkrsign.exeを実行する

ここでKRKR2_HOMEとは吉里吉里2/KAG3の解凍先フォルダを示す。

使用例

以下のXMLファイル(ファイル名はkrkr2task.proj)を例に説明する。プロパティの値(KRKR2_HOME~ARCHIVE_FILE)は各自の環境に合わせて修正のこと。

<?xml version="1.0" encoding="UTF-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- プロパティの設定(この値を変更してください) -->
  <PropertyGroup>
    <!-- 吉里吉里2/KAG3圧縮アーカイブファイルの解凍先フォルダ -->
    <KRKR2_HOME>C:\kirikiri_kag</KRKR2_HOME>
    <!--
      Krkr2Task.dllが実行するkrkrrel.exe, krkrsign.exeは以下の順番で決まる:
      ①プロパティKRKR2_HOMEが設定されている場合、$(KRKR2_HOME)\kirikiri2\toolsフォルダのkrkrrel.exe, krkrsign.exeを実行する
      ②環境変数KRKR2_HOMEが設定されている場合、%KRKR2_HOME%\kirikiri2\toolsフォルダのkrkrrel.exe, krkrsign.exeを実行する
      ③どちらも設定されていない場合、環境変数PATHの設定に従ってkrkrrel.exe, krkrsign.exeを実行する
    -->
    <!-- Krkr2Task.dllのあるフォルダ -->
    <KRKR2TASK_FOLDER>C:\CustomTask</KRKR2TASK_FOLDER>
    <!-- プロジェクトフォルダ -->
    <PROJECT_FOLDER>C:\MyProject</PROJECT_FOLDER>
    <!-- リリース先フォルダ -->
    <RELEASE_FOLDER>C:\Release</RELEASE_FOLDER>
    <!-- 秘密鍵ファイル -->
    <PRIVATE_KEY>C:\Sign\private_key.txt</PRIVATE_KEY>
    <!-- XP3アーカイブファイル -->
    <ARCHIVE_FILE>$(RELEASE_FOLDER)\data.xp3</ARCHIVE_FILE>
  </PropertyGroup>
  <!-- 使用するアセンブリとタスク名を宣言 -->
  <UsingTask AssemblyFile="$(KRKR2TASK_FOLDER)\Krkr2Task.dll" TaskName="Krkr2Rel"/>
  <UsingTask AssemblyFile="$(KRKR2TASK_FOLDER)\Krkr2Task.dll" TaskName="Krkr2Sign"/>
  <!-- Buildターゲット -->
  <Target Name="Build">
    <!-- リリース -->
    <Krkr2Rel Directory="$(PROJECT_FOLDER)" Xp3Archive="$(ARCHIVE_FILE)" />
    <!-- 署名 -->
    <ItemGroup>
      <SIGN_FILES Include="$(RELEASE_FOLDER)\**\*.*" Exclude="$(RELEASE_FOLDER)\savedata\*.*" />
    </ItemGroup>
    <Krkr2Sign Files="@(SIGN_FILES)" SecretKey="$(PRIVATE_KEY)" />
  </Target>
</Project>

コマンドプロンプトを起動し、以下のコマンドラインを実行すれば、リリースと署名が実行される。

msbuild krkr2task.proj

InnoSetup5Task.targets

InnoSetup5Task.targets / InnoSetup5Task.dll はMSBuildに以下のタスクを追加する。

ISCCタスク

MSBuildを参照。

GenerateISSタスク

吉里吉里2/KAG3製ゲーム用の簡易なInno Setupスクリプト(.iss)を生成するインラインタスク。

属性読込書込説明
AppContactString×SetupセクションのAppContactと同じ
AppIdString×SetupセクションのAppIdと同じ
AppNameString×指定必須。SetupセクションのAppNameと同じ
AppPublisherString×SetupセクションのAppPublisherと同じ
AppPublisherURLString×SetupセクションのAppPublisherURLと同じ
AppSupportURLString×SetupセクションのAppSupportURLと同じ
AppVersionString×指定必須。SetupセクションのAppVersionと同じ
CreateUninstallRegKeyString×SetupセクションのCreateUninstallRegKeyと同じ
DefaultDirNameString×指定必須。SetupセクションのDefaultDirNameと同じ
DefaultGroupNameString×指定必須。SetupセクションのDefaultGroupNameと同じ
DiskSpanningString×SetupセクションのDiskSpanningと同じ
LicenseFileString×SetupセクションのLicenseFileと同じ
MinVersionString×SetupセクションのMinVersionと同じ
OutputBaseFilenameString×SetupセクションのOutputBaseFilenameと同じ
OutputDirString×SetupセクションのOutputDirと同じ
ScriptFileString×指定必須。生成するInno Setupスクリプトファイル(.iss)のパスを指定する
SetupIconFileString×SetupセクションのSetupIconFileと同じ
SlicesPerDiskString×SetupセクションのSlicesPerDiskと同じ
SourceDirectoryString×指定必須。インストール対象ファイルのあるフォルダのパスを指定する
UpdateUninstallLogAppNameString×SetupセクションのUpdateUninstallLogAppNameと同じ
WizardImageFileString×SetupセクションのWizardImageFileと同じ
WizardSmallImageFileString×SetupセクションのWizardSmallImageFileと同じ
  • SourceDirectory内のsavedataフォルダ以下のファイルはInno Setupスクリプト(.iss)内に登録されない
  • AppNameと同じ名前の実行形式ファイルがあると、追加タスク「デスクトップにショートカットを作成」を登録する

GenerateISS2タスク

吉里吉里2/KAG3製ゲーム用のInno Setupスクリプト(.iss)を生成するインラインタスク。GenerateISSタスクより詳細な設定を行う場合に使用する。

属性読込書込説明
AppNameString×指定必須。SetupセクションのAppNameと同じ
HeaderFileString×指定必須。ScriptFileに挿入するテキストファイルのパスを指定する
ScriptFileString×指定必須。生成するInno Setupスクリプトファイル(.iss)のパスを指定する
SourceDirectoryString×指定必須。インストール対象ファイルのあるフォルダのパスを指定する
  • SourceDirectory内のsavedataフォルダ以下のファイルはInno Setupスクリプト(.iss)内に登録されない
  • AppNameと同じ名前の実行形式ファイルがあると、追加タスク「デスクトップにショートカットを作成」を登録する

ZipTask.targets

DotNetZipのアセンブリIonic.Zip.dllを使ってZIP圧縮/解凍を行うインラインタスク。

Ionic.Zip.dllは以下の順番で検索・ロードされる:

  1. %ProgramFiles%Dino Chiesa\DotNetZip Runtime 1.9\Ionic.Zip.dll
  2. カレントフォルダにあるIonic.Zip.dll

追加されるタスク

Zipタスク

指定したフォルダをZIP圧縮する。

属性読込書込説明備考
DirectoryString×指定必須。圧縮対象フォルダのパスを指定する
ZipFileNameString×指定必須。作成するZIP形式ファイル名のパス既存のファイルは上書きする
EncodingString×ファイル名の文字コードを指定する省略時はshift_jis

UnZipタスク

ZIP形式ファイルを指定したフォルダに解凍する。

属性読込書込説明備考
ZipFileNameString×指定必須。解凍するZIP形式ファイル名のパス
DirectoryString×指定必須。解凍先フォルダのパスを指定する既存のファイルは上書きする
EncodingString×ファイル名の文字コードを指定する省略時はshift_jis

使用例

以下のXMLファイル(ファイル名はziptask.proj)を例に説明する。プロパティの値(SOURCE_FOLDER~DESTINATION_FOLDER)は各自の環境に合わせて修正のこと。

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Compress" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildProjectDirectory)\ZipTask.Targets" />
  <PropertyGroup>
    <SOURCE_FOLDER><![CDATA[C:\SRC]]></SOURCE_FOLDER>
    <ZIP_PATH><![CDATA[$(MSBuildProjectDirectory)\foo.zip]]></ZIP_PATH>
    <DESTINATION_FOLDER><![CDATA[C:\DST]]></DESTINATION_FOLDER>
  </PropertyGroup>
  <Target Name="Compress">
    <Zip Directory="$(SOURCE_FOLDER)" ZipFileName="$(ZIP_PATH)" />
    <UnZip ZipFileName="$(ZIP_PATH)" Directory="$(DESTINATION_FOLDER)" />
  </Target>
</Project>

コマンドプロンプトを起動し、以下のコマンドラインを実行すれば、ZIP圧縮・解凍が行われる。

msbuild ziptask.proj

動作環境

  • Windows XP SP3 / Windows Vista SP2
  • .NET Framework 4
  • MSBuild Extension Pack 4.0.6.0 / 7-Zip 9.20 / Info-Zip(Zip 3.0) / DotNetZip 1.9.1.8
  • Inno Setup 5.5.0

参考


*1 ここでは「ビルド」と呼称している。
*2 MSBuild Community Tasks 1.4.0.42でZIP圧縮するとZIPファイルが壊れる(?)場合がある(1.2.0.306なら問題ない様だが現在は公開されていない)。
*3 ISPPを追加インストールしていると、コンパイル時に一部の日本語リソースが不足しているという警告メッセージが出る。煩わしければISCCタスクのQuiet属性(後述)で抑止すると良い。