.NET用ビルドエンジン「MSBuild」の使い方と、簡単なサンプル。 MSBuildを使うことでコマンドラインからソリューション・プロジェクトのビルドを行ったり、高度なバッチ処理を行ったりすることができる。

§1 MSBuildの基本

MSBuildの基本的な使い方とビルド方法。

§1.1 パスを通す

まず、環境変数PATHを設定してMSBuildのパスを通す。

§1.1.1 .NET Framework

「システムのプロパティ」→「詳細設定」→「環境変数」でPathに下記のパスを追加する。

C:\Windows\Microsoft.NET\Framework\v4.0.30319

または、コマンドライン上で下記のコマンドを入力する。

@Set PATH=%PATH%;C:\Windows\Microsoft.NET\Framework\v4.0.30319

パスを通したら、MSBuildが起動するか確かめる。

MSBuildが起動するか確かめる
E:\test>msbuild /version
Microsoft (R) Build Engine バージョン 4.0.30319.17929
[Microsoft .NET Framework、バージョン 4.0.30319.18034]
Copyright (C) Microsoft Corporation. All rights reserved.

4.0.30319.17929

上記のようにバージョンが表示されれば問題なし。

§1.1.2 Mono

シェル上で下記のコマンドを入力する。 (Monoが/opt/mono/以下にインストールされている場合の例)

export PATH=/opt/mono/bin:$PATH

パスを通したら、MonoのMSBuild互換実装であるXBuildが起動するか確かめる。

XBuildが起動するか確かめる
$ xbuild /version
XBuild Engine Version 2.10.8.0
Mono, Version 2.10.8.0
Copyright (C) Marek Sieradzki 2005-2008, Novell 2008-2011.

上記のようにバージョンが表示されれば問題なし。 XBuildはコマンド名がxbuildとなっている点を除いて、コマンドラインオプションはすべてMSBuildと同じ。

§1.2 MSBuildを使ったビルド

MSBuildの引数にソリューションファイル(*.sln)やプロジェクトファイル(*.csproj, *.vbproj)を指定することでソリューション・プロジェクトのビルドを行うことができる。

ソリューションファイルをビルドする例
E:\test>msbuild sample.sln

Microsoft (R) Build Engine バージョン 4.0.30319.17929
[Microsoft .NET Framework、バージョン 4.0.30319.18034]
Copyright (C) Microsoft Corporation. All rights reserved.

このソリューション内のプロジェクトを 1 度に 1 つずつビルドします。並行ビルドを有効にするには、"/m" スイッチを追加してください。
2013/06/12 23:00:48 にビルドを開始しました。
ノード 1 上のプロジェクト "E:\test\sample.sln" (既定のターゲット)。
ValidateSolutionConfiguration:
  ソリューション構成 "Debug|Any CPU" をビルドしています。
プロジェクト "E:\test\sample.sln" (1) は、ノード 1 上に "E:\test\sample.csproj" (2) をビルドしています (既定のターゲット)。
EntityDeploy:
  Processing 0 EDMX files.
  Finished processing 0 EDMX files.
PrepareForBuild:
  ディレクトリ "bin\Debug\" を作成しています。
  md "bin\Debug\"
  ディレクトリ "obj\Debug\" を作成しています。
  md "obj\Debug\"
CoreCompile:
  C:\Windows\Microsoft.NET\Framework\v3.5\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.DataSetExtensions.dll" /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll" /debug+ /debug:full /filealign:512 /optimize- /out:obj\Debug\sample.exe /target:exe Program.cs Properties\AssemblyInfo.cs
CopyFilesToOutputDirectory:
  "obj\Debug\sample.exe" から "bin\Debug\sample.exe" へファイルをコピーしています。
  copy /y "obj\Debug\sample.exe" "bin\Debug\sample.exe"
  sample -> E:\test\bin\Debug\sample.exe
  "obj\Debug\sample.pdb" から "bin\Debug\sample.pdb" へファイルをコピーしています。
  copy /y "obj\Debug\sample.pdb" "bin\Debug\sample.pdb"
プロジェクト "E:\test\sample.csproj" (既定のターゲット) のビルドが完了しました。
プロジェクト "E:\test\sample.sln" (既定のターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.69
プロジェクトファイルをビルドする例
E:\test>msbuild sample.csproj

Microsoft (R) Build Engine バージョン 4.0.30319.17929
[Microsoft .NET Framework、バージョン 4.0.30319.18034]
Copyright (C) Microsoft Corporation. All rights reserved.

2013/06/12 23:01:16 にビルドを開始しました。
ノード 1 上のプロジェクト "E:\test\sample.csproj" (既定のターゲット)。
EntityDeploy:
  Processing 0 EDMX files.
  Finished processing 0 EDMX files.
PrepareForBuild:
  ディレクトリ "bin\Debug\" を作成しています。
  md "bin\Debug\"
  ディレクトリ "obj\Debug\" を作成しています。
  md "obj\Debug\"
CoreCompile:
  C:\Windows\Microsoft.NET\Framework\v3.5\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.DataSetExtensions.dll" /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll" /debug+ /debug:full /filealign:512 /optimize- /out:obj\Debug\sample.exe /target:exe Program.cs Properties\AssemblyInfo.cs
CopyFilesToOutputDirectory:
  "obj\Debug\sample.exe" から "bin\Debug\sample.exe" へファイルをコピーしています。
  copy /y "obj\Debug\sample.exe" "bin\Debug\sample.exe"
  sample -> E:\test\bin\Debug\sample.exe
  "obj\Debug\sample.pdb" から "bin\Debug\sample.pdb" へファイルをコピーしています。
  copy /y "obj\Debug\sample.pdb" "bin\Debug\sample.pdb"
プロジェクト "E:\test\sample.csproj" (既定のターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.62


§1.3 MSBuildのコマンドラインオプション

§1.3.1 ビルド動作の指定 (/targetオプション)

/target(または/t)オプションを使うことでビルドの動作(ターゲット)を指定できる。 例えば、Cleanを指定すれば一時ファイルの削除、Runを指定すればビルド済みの実行可能ファイルの実行を行うことができる。 以下のようなターゲットを/target:targetsの形式で指定することができる。 ターゲットはカンマ , またはセミコロン ; で区切ることで複数することができる。 この場合、ターゲットが指定された順に動作する。 プロジェクトファイルではデフォルトのターゲットは「Build」になっているので、ターゲットを指定しない場合は「Build」の動作でプロジェクトのビルドが行われる。

/targetオプションで指定できるターゲットの例
ターゲット 動作
Build ビルド
Clean クリーン
一時ファイルやビルド済みファイルを削除する
Rebuild リビルド
(Build;Cleanを指定するのと同じ)
Run 実行
ビルド済み実行可能ファイルの実行を行う

たとえば、

Program.cs
using System;

class Program {
  static void Main(string[] args)
  {
    Console.WriteLine("Hello, world!");
  }
}

上記のようなソースを含むプロジェクトファイルをビルドする際、ターゲットを指定せずにMSBuildに渡した場合は次のような動作となる。

E:\test>msbuild sample.csproj

Microsoft (R) Build Engine バージョン 4.0.30319.17929
[Microsoft .NET Framework、バージョン 4.0.30319.18034]
Copyright (C) Microsoft Corporation. All rights reserved.

2013/06/12 23:04:48 にビルドを開始しました。
ノード 1 上のプロジェクト "E:\test\sample.csproj" (既定のターゲット)。
EntityDeploy:
  Processing 0 EDMX files.
  Finished processing 0 EDMX files.
PrepareForBuild:
  ディレクトリ "bin\Debug\" を作成しています。
  md "bin\Debug\"
  ディレクトリ "obj\Debug\" を作成しています。
  md "obj\Debug\"
CoreCompile:
  C:\Windows\Microsoft.NET\Framework\v3.5\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.DataSetExtensions.dll" /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll" /debug+ /debug:full /filealign:512 /optimize- /out:obj\Debug\sample.exe /target:exe Program.cs Properties\AssemblyInfo.cs
CopyFilesToOutputDirectory:
  "obj\Debug\sample.exe" から "bin\Debug\sample.exe" へファイルをコピーしています。
  copy /y "obj\Debug\sample.exe" "bin\Debug\sample.exe"
  sample -> E:\test\bin\Debug\sample.exe
  "obj\Debug\sample.pdb" から "bin\Debug\sample.pdb" へファイルをコピーしています。
  copy /y "obj\Debug\sample.pdb" "bin\Debug\sample.pdb"
プロジェクト "E:\test\sample.csproj" (既定のターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:01.35

一方、オプション「/target:Rebuild,Run」を指定してビルドすると次のような動作となる。

E:\test>msbuild sample.csproj /target:Rebuild,Run

Microsoft (R) Build Engine バージョン 4.0.30319.17929
[Microsoft .NET Framework、バージョン 4.0.30319.18034]
Copyright (C) Microsoft Corporation. All rights reserved.

2013/06/12 23:05:39 にビルドを開始しました。
ノード 1 上のプロジェクト "E:\test\sample.csproj" (Rebuild;Run ターゲット)。
CoreClean:
  ディレクトリ "obj\Debug\" を作成しています。
  md "obj\Debug\"
EntityClean:
  Successfully cleaned the output for 0 EDMX files.
EntityDeploy:
  Processing 0 EDMX files.
  Finished processing 0 EDMX files.
PrepareForBuild:
  ディレクトリ "bin\Debug\" を作成しています。
  md "bin\Debug\"
CoreCompile:
  C:\Windows\Microsoft.NET\Framework\v3.5\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.DataSetExtensions.dll" /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll" /debug+ /debug:full /filealign:512 /optimize- /out:obj\Debug\sample.exe /target:exe Program.cs Properties\AssemblyInfo.cs
CopyFilesToOutputDirectory:
  "obj\Debug\sample.exe" から "bin\Debug\sample.exe" へファイルをコピーしています。
  copy /y "obj\Debug\sample.exe" "bin\Debug\sample.exe"
  sample -> E:\test\bin\Debug\sample.exe
  "obj\Debug\sample.pdb" から "bin\Debug\sample.pdb" へファイルをコピーしています。
  copy /y "obj\Debug\sample.pdb" "bin\Debug\sample.pdb"
Run:
  E:\test\bin\Debug\sample.exe 
  Hello, world!
プロジェクト "E:\test\sample.csproj" (Rebuild;Run ターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.80

§1.3.2 ビルド構成・コンパイルスイッチの指定 (/propertyオプション)

/property(または/p)オプションを使うことでビルド時に使用するプロジェクトのプロパティ(ビルド構成やコンパイルスイッチなど)を指定することができる。 「/property:name=value」のように、変更したいプロパティ名とその値を指定する。

§1.3.2.1 ビルド構成の指定 (Configurationプロパティ)

Configurationプロパティを指定することで、ビルド構成を指定してビルドすることが出来る。 たとえば、

Program.cs
using System;

class Program {
  static void Main(string[] args)
  {
#if DEBUG
    Console.WriteLine("Debugビルドです");
#else
    Console.WriteLine("Releaseビルドです");
#endif
  }
}

上記のようなソースを含むプロジェクトファイルをビルドする際、「/property:Configuration=Release」を指定してビルドした場合は次のようにRelease構成でのビルドを行う動作となる。

E:\test>msbuild sample.csproj /target:Build,Run /property:Configuration=Release

    :
    :
(途中省略)
    :
    :

PrepareForBuild:
  ディレクトリ "bin\Release\" を作成しています。
  md "bin\Release\"
  ディレクトリ "obj\Release\" を作成しています。
  md "obj\Release\"
CoreCompile:
  C:\Windows\Microsoft.NET\Framework\v3.5\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:TRACE /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.DataSetExtensions.dll" /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll" /debug:pdbonly /filealign:512 /optimize+ /out:obj\Release\sample.exe /target:exe Program.cs Properties\AssemblyInfo.cs
CopyFilesToOutputDirectory:
  "obj\Release\sample.exe" から "bin\Release\sample.exe" へファイルをコピーしています。
  copy /y "obj\Release\sample.exe" "bin\Release\sample.exe"
  sample -> E:\test\bin\Release\sample.exe
  "obj\Release\sample.pdb" から "bin\Release\sample.pdb" へファイルをコピーしています。
  copy /y "obj\Release\sample.pdb" "bin\Release\sample.pdb"
Run:
  E:\test\bin\Release\sample.exe 
  Releaseビルドです
プロジェクト "E:\test\sample.csproj" (Build;Run ターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.57

「/property:Configuration=Debug」と指定すればDebug構成のビルドとなるが、デフォルトではConfigurationの値は "Debug" となっているので明示的に指定しなくてもDebug構成でのビルドが行われる。

E:\test>msbuild sample.csproj /target:Build,Run

    :
    :
(途中省略)
    :
    :

PrepareForBuild:
  ディレクトリ "bin\Debug\" を作成しています。
  md "bin\Debug\"
  ディレクトリ "obj\Debug\" を作成しています。
  md "obj\Debug\"
CoreCompile:
  C:\Windows\Microsoft.NET\Framework\v3.5\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.DataSetExtensions.dll" /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll" /debug+ /debug:full /filealign:512 /optimize- /out:obj\Debug\sample.exe /target:exe Program.cs Properties\AssemblyInfo.cs
CopyFilesToOutputDirectory:
  "obj\Debug\sample.exe" から "bin\Debug\sample.exe" へファイルをコピーしています。
  copy /y "obj\Debug\sample.exe" "bin\Debug\sample.exe"
  sample -> E:\test\bin\Debug\sample.exe
  "obj\Debug\sample.pdb" から "bin\Debug\sample.pdb" へファイルをコピーしています。
  copy /y "obj\Debug\sample.pdb" "bin\Debug\sample.pdb"
Run:
  E:\test\bin\Debug\sample.exe 
  Debugビルドです
プロジェクト "E:\test\sample.csproj" (Build;Run ターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.56

§1.3.2.2 コンパイルスイッチの指定 (DefineConstantsプロパティ)

DefineConstantsプロパティを指定することで、コンパイルスイッチを指定してビルドすることが出来る。 たとえば、

Program.cs
using System;

class Program {
  static void Main(string[] args)
  {
#if DEBUG
    Console.WriteLine("DEBUGは有効です");
#endif

#if PLATFORM_WIN32
    Console.WriteLine("PLATFORM_WIN32は有効です");
#endif

#if PLATFORM_WINNT
    Console.WriteLine("PLATFORM_WINNTは有効です");
#endif
  }
}

上記のようなソースを含むプロジェクトファイルをビルドする際、「/property:DefineConstants="DEBUG;PLATFORM_WIN32"」を指定してビルドした場合は次のような実行結果となる。

E:\test>msbuild sample.csproj /target:Build,Run /property:DefineConstants="DEBUG;PLATFORM_WIN32"

    :
    :
(途中省略)
    :
    :

CoreCompile:
  C:\Windows\Microsoft.NET\Framework\v3.5\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:DEBUG;PLATFORM_WIN32 /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.DataSetExtensions.dll" /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll" /debug+ /debug:full /filealign:512 /optimize- /out:obj\Debug\sample.exe /target:exe Program.cs Properties\AssemblyInfo.cs
CopyFilesToOutputDirectory:
  "obj\Debug\sample.exe" から "bin\Debug\sample.exe" へファイルをコピーしています。
  copy /y "obj\Debug\sample.exe" "bin\Debug\sample.exe"
  sample -> E:\test\bin\Debug\sample.exe
  "obj\Debug\sample.pdb" から "bin\Debug\sample.pdb" へファイルをコピーしています。
  copy /y "obj\Debug\sample.pdb" "bin\Debug\sample.pdb"
Run:
  E:\test\bin\Debug\sample.exe 
  DEBUGは有効です
  PLATFORM_WIN32は有効です
プロジェクト "E:\test\sample.csproj" (Build;Run ターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.58

§1.3.2.3 出力先の指定 (OutputPathプロパティ)

OutputPathプロパティを指定することで、ファイルの出力先を指定してビルドすることが出来る。

E:\test>msbuild sample.csproj /property:OutputPath="E:\test\output"

    :
    :
(途中省略)
    :
    :

PrepareForBuild:
  ディレクトリ "E:\test\output\" を作成しています。
  md "E:\test\output\"
  ディレクトリ "obj\Debug\" を作成しています。
  md "obj\Debug\"
CoreCompile:
  C:\Windows\Microsoft.NET\Framework\v3.5\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.DataSetExtensions.dll" /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll" /debug+ /debug:full /filealign:512 /optimize- /out:obj\Debug\sample.exe /target:exe Program.cs Properties\AssemblyInfo.cs
CopyFilesToOutputDirectory:
  "obj\Debug\sample.exe" から "E:\test\output\sample.exe" へファイルをコピーしています。
  copy /y "obj\Debug\sample.exe" "E:\test\output\sample.exe"
  sample -> E:\test\output\sample.exe
  "obj\Debug\sample.pdb" から "E:\test\output\sample.pdb" へファイルをコピーしています。
  copy /y "obj\Debug\sample.pdb" "E:\test\output\sample.pdb"
プロジェクト "E:\test\sample.csproj" (既定のターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.47

§1.3.3 ログ粒度の指定 (/verbosityオプション)

/verbosity(または/v)オプションを使うことでMSBuildが出力するログの詳細度を指定することができる。 指定できる詳細度には次のようなものがある(詳細度の低い順)。

  1. quiet
  2. minimal
  3. normal (指定しなかった場合のデフォルト)
  4. detailed
  5. diagnostic
/verbosity:normalの出力例
E:\test>msbuild sample.csproj /verbosity:normal

Microsoft (R) Build Engine バージョン 4.0.30319.17929
[Microsoft .NET Framework、バージョン 4.0.30319.18034]
Copyright (C) Microsoft Corporation. All rights reserved.

2013/06/12 23:23:27 にビルドを開始しました。
ノード 1 上のプロジェクト "E:\test\sample.csproj" (既定のターゲット)。
EntityDeploy:
  Processing 0 EDMX files.
  Finished processing 0 EDMX files.
PrepareForBuild:
  ディレクトリ "bin\Debug\" を作成しています。
  md "bin\Debug\"
  ディレクトリ "obj\Debug\" を作成しています。
  md "obj\Debug\"
CoreCompile:
  C:\Windows\Microsoft.NET\Framework\v3.5\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.DataSetExtensions.dll" /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll" /debug+ /debug:full /filealign:512 /optimize- /out:obj\Debug\sample.exe /target:exe Program.cs Properties\AssemblyInfo.cs
CopyFilesToOutputDirectory:
  "obj\Debug\sample.exe" から "bin\Debug\sample.exe" へファイルをコピーしています。
  copy /y "obj\Debug\sample.exe" "bin\Debug\sample.exe"
  sample -> E:\test\bin\Debug\sample.exe
  "obj\Debug\sample.pdb" から "bin\Debug\sample.pdb" へファイルをコピーしています。
  copy /y "obj\Debug\sample.pdb" "bin\Debug\sample.pdb"
プロジェクト "E:\test\sample.csproj" (既定のターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.49
/verbosity:minimalの出力例
E:\test>msbuild sample.csproj /verbosity:minimal

Microsoft (R) Build Engine バージョン 4.0.30319.17929
[Microsoft .NET Framework、バージョン 4.0.30319.18034]
Copyright (C) Microsoft Corporation. All rights reserved.

  sample -> E:\test\bin\Debug\sample.exe
/verbosity:quietの出力例
E:\test>msbuild sample.csproj /verbosity:minimal

Microsoft (R) Build Engine バージョン 4.0.30319.17929
[Microsoft .NET Framework、バージョン 4.0.30319.18034]
Copyright (C) Microsoft Corporation. All rights reserved.

/nologoオプションと併用することでバナー表示も省略できる。

/nologと併用した場合の出力例
E:\test>msbuild sample.csproj /verbosity:minimal /nologo

  sample -> E:\test\bin\Debug\sample.exe

detailedおよびdiagnosticでは非常に詳細なログが出力される。

§2 プロジェクトファイルの記述方法

MSBuildは、Visual Studioなどが生成するプロジェクトファイルだけでなく、MSBuild形式のプロジェクトファイルスキーマに則ったファイルをビルドすることができる。 プロジェクトのビルド以外にも様々なバッチ処理を記述することもできる。

§2.1 まずはHello, world! (Messageタスク)

Messageタスクを使って「Hello, world!」と表示するだけのビルドファイルを作る。 HelloWorld.msbuild.xmlというファイルを作成し、下記の内容を書き込む。

HelloWorld.msbuild.xml
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
    <Target Name="Build">
        <!-- 文字列を出力する -->
        <Message Text="Hello, world!"/>
    </Target>
</Project>

ファイルが作成できたら、msbuildに作成したファイルを渡して「ビルド」を実行させる。

E:\test>msbuild HelloWorld.msbuild.xml

すると、下記のように表示される。

2013/06/12 23:35:49 にビルドを開始しました。
ノード 1 上のプロジェクト "E:\test\HelloWorld.msbuild.xml" (既定のターゲット)。
Build:
  Hello, world!
プロジェクト "E:\test\HelloWorld.msbuild.xml" (既定のターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.06

上記のように「ビルド」の結果が表示される。 ここでの要点は次の通り。

  • XMLで書かれた「プロジェクトファイル」をMSBuildに渡すと、その内容に従って「ビルド」が行われる
    • 中身がスキーマに則ったXMLであれば、拡張子はxmlでなくてもOK(例えば.vbprojなど)
    • プロジェクトファイルはXMLの形式だが、XML宣言(?xml〜?)は無くても特にエラーとはならず正常に動作する
    • プロジェクトファイルのルート要素はProjectで、その要素の中で様々な動作を定義する
  • Target要素はビルドのターゲットを定義する要素で、ビルドの動作を定義する
    • よく使われるターゲットの例として、ビルド済みファイルの削除を行うClean、ソースファイルのコンパイルを行うBuild、ビルドした実行可能ファイルの実行を行うRunなどがある
    • この例では、Message要素を使ってメッセージを表示するターゲットにBuildという名前を付けている
    • Project要素のDefaultTargets属性でターゲットBuildを指定しているため、デフォルトでこのターゲットがビルドされる
  • Message要素を使用すると、任意の文字列を出力させることができる
    • Messageはタスクと呼ばれるもののうちの1つ
    • Messageはビルド中の動作をログに出力するために用いることができる
    • 出力させる文字列はText属性で指定することができる
    • Text属性にプロパティアイテム(一種の定数や変数)を指定することでそれらの内容を出力させることもできる

§2.2 プロパティ(PropertyGroup)

プロパティ(PropertyGroup)を使った例。 PropertyGroup要素を用いるとプロパティを宣言出来る。 プロパティは一種の定数のようなものであり、PropertyGroupの子要素として任意の名前で定義することができる。 Messageタスク等でプロパティの値を参照する場合は、「$(プロパティ名)」とすることでその値を参照できる。

PropertyGroup
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
    <!-- プロパティを宣言する -->
    <PropertyGroup>
        <AssemblyName>Test1</AssemblyName>
        <Configuration>Debug</Configuration>
        <OutputType>WinExe</OutputType>
        <OutputPath>bin\Debug</OutputPath>
        <Hoge>Hage</Hoge>
    </PropertyGroup>

    <Target Name="Build">
        <!-- プロパティの値を出力する -->
        <Message Text="AssemblyName : $(AssemblyName)"/>
        <Message Text="Configuration : $(Configuration)"/>
        <Message Text="OutputType : $(OutputType)"/>
        <Message Text="OutputPath : $(OutputPath)"/>
        <Message Text="Hoge : $(Hoge)"/>
    </Target>
</Project>
実行結果
E:\test>msbuild sample.msbuild.xml

2013/06/12 23:42:05 にビルドを開始しました。
ノード 1 上のプロジェクト "E:\test\sample.msbuild.xml" (既定のターゲット)。
Build:
  AssemblyName : Test1
  Configuration : Debug
  OutputType : WinExe
  OutputPath : bin\Debug
  Hoge : Hage
プロジェクト "E:\test\sample.msbuild.xml" (既定のターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.06

また、/propertyオプションを指定した場合もプロパティを設定できる。 プロジェクトファイルに同名のプロパティが記述されている場合でも、/propertyオプションで指定された値が優先して使用される。

/propertyオプションによるPropertyGroupの上書き
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
    <PropertyGroup>
        <Configuration>Debug</Configuration>
    </PropertyGroup>

    <Target Name="Build">
        <Message Text="Configuration : $(Configuration)"/>
        <Message Text="OutputPath : $(OutputPath)"/>
    </Target>
</Project>
実行結果
E:\test>msbuild sample.msbuild.xml /property:Configuration=Release /property:OutputPath=..\build

2013/06/12 23:42:43 にビルドを開始しました。
ノード 1 上のプロジェクト "E:\test\sample.msbuild.xml" (既定のターゲット)。
Build:
  Configuration : Release
  OutputPath : ..\build
プロジェクト "E:\test\sample.msbuild.xml" (既定のターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.06

ここでの要点は次の通り。

  • PropertyGroup要素を用いるとプロパティを宣言出来る
  • PropertyGroup要素の子要素の名前がそのままプロパティ名となる
  • プロパティは任意の名前で定義できる
  • /propertyオプションでビルド時にプロパティの値を変更できる
  • Messageタスクなどの文字列中でプロパティの値を参照する場合は、「$(プロパティ名)」とする

§2.3 ターゲット(Target)

ターゲット(Target)を使った例。 ターゲットはいくつかのタスクをひとまとめにして動作を定義するためのもの。 ターゲットを使うことで一連の手続き(タスク)をまとめて一種のメソッドのようなものを作成することができる。

Target
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>

<!-- DefaultTargetsにClean;Buildを指定したプロジェクト -->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Clean;Build">
    <Target Name="Clean">
        <Message Text="Clean"/>
    </Target>

    <Target Name="BeforeBuild">
        <Message Text="BeforeBuild"/>
    </Target>

    <Target Name="Build">
        <!-- BeforeBuildターゲットを呼び出す -->
        <CallTarget Targets="BeforeBuild"/>

        <Message Text="Build"/>

        <!-- AfterBuildターゲットを呼び出す -->
        <CallTarget Targets="AfterBuild"/>
    </Target>

    <Target Name="AfterBuild">
        <Message Text="AfterBuild"/>
    </Target>
</Project>
実行結果
E:\test>msbuild sample.msbuild.xml

2013/06/12 23:43:17 にビルドを開始しました。
ノード 1 上のプロジェクト "E:\test\sample.msbuild.xml" (既定のターゲット)。
Clean:
  Clean
BeforeBuild:
  BeforeBuild
Build:
  Build
AfterBuild:
  AfterBuild
プロジェクト "E:\test\sample.msbuild.xml" (既定のターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.07

動作させるターゲットを指定せずに実行する場合、MSBuildはデフォルトのターゲット(ProjectのDefaultTargets属性で指定されているターゲット)を実行する。 この例ではDefaultTargetsに"Clean;Build"を指定しているが、これは「Cleanの後にBuildを実行する」という意味になる。 そのため、まずCleanターゲットで定義された動作が先に動き、続いてBuildターゲットで定義された動作が動く。

さらにこのファイルでは、BuildターゲットにてCallTargetタスクを使用して別のターゲットを起動している。 そのため、Buildターゲットを動作させると

  1. BeforeBuildターゲットが呼び出される
    1. BeforeBuildターゲット内のMessageタスクが動作して文字列"BeforeBuild"を出力する
  2. BuildターゲットのMessageタスクが動作して文字列"Build"を出力する
  3. AfterBuildターゲットが呼び出される
    1. AfterBuildターゲット内のMessageタスクが動作して文字列"AfterBuild"を出力する

という動きになる。 なお、DefaultTargets属性と同様にCallTargetタスクでも複数のターゲットを指定することができる。

/targetオプションを指定して実行すると、動作させるターゲットを指定することができる。 例えば、次のようにオプション"/t:Clean"を付けて実行するとターゲットCleanだけが動作する。

実行結果
E:\test>msbuild sample.msbuild.xml /target:Clean

2013/06/12 23:43:40 にビルドを開始しました。
ノード 1 上のプロジェクト "E:\test\sample.msbuild.xml" (Clean ターゲット)。
Clean:
  Clean
プロジェクト "E:\test\sample.msbuild.xml" (Clean ターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.06

ここでの要点は下記の通り。

  • Target要素では1つ以上のタスクを記述してビルドの動作を定義する
  • /targetオプションを使用するとビルドするターゲットを指定できる
    • /target:Cleanとした場合は、ターゲットCleanのみが動作する
    • /targetを指定しなかった場合は、デフォルトのターゲットをビルドする
    • デフォルトのターゲットは、ProjectのDefaultTargetsで定義する
  • CallTargetタスクを使用すると、他のターゲットを呼び出すことが出来る
  • デフォルトのターゲットやCallTargetタスクに指定するターゲットには、「Clean;Build」のように複数のターゲットを指定することも出来る

§2.4 依存関係の定義(DependsOnTargets)

TargetのDependsOnTargets属性を使用してターゲット同士の依存関係を定義した例。

DependsOnTargets
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
    <Target Name="Clean">
        <Message Text="Clean"/>
    </Target>
    
    <Target Name="BeforeBuild">
        <Message Text="BeforeBuild"/>
    </Target>

    <!-- DependsOnTargetsにClean;BeforeBuildを指定したターゲット -->
    <Target Name="Build" DependsOnTargets="Clean;BeforeBuild">
        <Message Text="Build"/>
        <CallTarget Targets="AfterBuild"/>
    </Target>

    <Target Name="AfterBuild">
        <Message Text="AfterBuild"/>
    </Target>
</Project>
実行結果
E:\test>msbuild sample.msbuild.xml

2013/06/12 23:44:10 にビルドを開始しました。
ノード 1 上のプロジェクト "E:\test\sample.msbuild.xml" (既定のターゲット)。
Clean:
  Clean
BeforeBuild:
  BeforeBuild
Build:
  Build
AfterBuild:
  AfterBuild
プロジェクト "E:\test\sample.msbuild.xml" (既定のターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.07

これはTargetの例に似ているが、CallTargetタスクの代わりにDependsOnTargets属性を指定して依存関係を定義している。 DependsOnTargets属性に任意のターゲットが指定されている場合は、そのターゲットが先に呼び出される。 その後、Target要素の中で定義されている動作が動く。

この例では、Buildターゲットを動作させようとする場合は、依存関係にあるCleanとBeforeBuildを順に呼び出してから、Buildで定義されている動作を順に実行していく。

ここでの要点は下記の通り。

  • DependsOnTargets属性で依存関係にあるターゲットを定義することが出来る
  • 依存関係にあるターゲットは、そのターゲットで定義されている動作を実行するよりも先に呼び出される

§2.5 ターゲット・タスクを使った簡単なサンプル(Target, RemoveDir, MakeDir, Touch, Exec)

ここまでの例で使用してきたMessageタスクはメッセージを出力するものだが、これ以外にも様々なタスクが用意されている。 RemoveDir, MakeDir, Touch, Execなどのタスクを使った例。

様々なタスクを使ったサンプル
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
    <PropertyGroup>
        <!-- 出力先 -->
        <OutputPath>bin\</OutputPath>
    </PropertyGroup>

    <Target Name="Clean">
        <!-- ディレクトリを削除 -->
        <RemoveDir Directories="$(OutputPath)" />
    </Target>

    <Target Name="Build">
        <!-- 存在しない場合は出力ディレクトリを作成 -->
        <MakeDir Directories="$(OutputPath)" Condition="!Exists('$OutputPath')" />

        <!-- 出力ディレクトリにファイルTest.txtを作成 -->
        <Touch Files="$(OutputPath)Test.txt" AlwaysCreate="True" />

        <!-- DOSコマンドを実行する -->
        <Exec Command="date /t > $(OutputPath)Test.txt" />
    </Target>
</Project>

まずはターゲットを指定しないでデフォルトであるBuildターゲットを実行させた場合。

実行結果
E:\test>msbuild sample.msbuild.xml

2013/06/12 23:44:55 にビルドを開始しました。
ノード 1 上のプロジェクト "E:\test\sample.msbuild.xml" (既定のターゲット)。
Build:
  ディレクトリ "bin\" を作成しています。
  md "bin\"
  "AlwaysCreate" が指定されたため "bin\Test.txt" を作成しています。
  date /t > bin\Test.txt
プロジェクト "E:\test\sample.msbuild.xml" (既定のターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.36

続いてターゲットを指定してCleanターゲットを実行させた場合。

実行結果
E:\test>msbuild sample.msbuild.xml /target:Clean

2013/06/12 23:45:18 にビルドを開始しました。
ノード 1 上のプロジェクト "E:\test\sample.msbuild.xml" (Clean ターゲット)。
Clean:
  ディレクトリ "bin\" を削除しています。
  rd /s /q "bin\"
プロジェクト "E:\test\sample.msbuild.xml" (Clean ターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.13

この例では、Buildターゲットを動作させた場合は、出力用のディレクトリbinを作成し、bin\Test.txtにターゲットを動作させた時間を記録している。 またCleanターゲットを指定した場合は、出力用のディレクトリbinを削除するようになっている。

ここでの要点は下記の通り。

  • MakeDirタスクを使用すると、ディレクトリを作成すことが出来る
    • MakeDirタスクにて作成するディレクトリは、Directories属性で指定する
    • MakeDirタスクにてCondition属性を指定すると、Conditionで指定している条件が真と評価される場合にのみディレクトリが作成される
  • RemoveDirタスクを使用すると、ディレクトリを削除することが出来る
    • RemoveDirタスクでは、ディレクトリ内にファイルがあってもディレクトリを削除できる
  • Touchタスクを使用すると、空のファイルを作成することが出来る
    • TouchタスクにてAlwaysCreate属性にTrueを指定すると、ファイルが存在していない場合はファイルが作成される
  • Execタスクを使用すると、DOSコマンドを実行できる(この例では、現在の時刻をbin\Test.txtファイルに書き出している)

§2.6 アイテム(ItemGroup)

アイテム(ItemGroup)を使った例。

ItemGroup
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
    <!-- 入力ファイルの一覧を作成する -->
    <ItemGroup>
        <!-- カレントディレクトリにあるbackup*.txtを除くすべての*.txtをTextFilesに格納する -->
        <TextFiles Include="*.txt" Exclude="backup*.txt"/>

        <SourceFiles Include="Main.cs;Form.cs"/>

        <ResourceFiles Include="Button.bmp"/>
        <ResourceFiles Include="Background.jpg"/>
        <ResourceFiles Include="Notice.wav"/>
    </ItemGroup>

    <Target Name="Build">
        <!-- ファイルの一覧を出力する -->
        <Message Text="TextFiles : @(TextFiles)"/>
        <Message Text="SourceFiles : @(SourceFiles)"/>
        <Message Text="ResourceFiles : @(ResourceFiles)"/>

        <!-- 区切り文字を変えて出力する -->
        <Message Text="ResourceFiles : @(ResourceFiles, ', ')"/>
        <Message Text="ResourceFiles : @(ResourceFiles, '/')"/>
    </Target>
</Project>
実行結果
E:\test>msbuild sample.msbuild.xml

2013/06/12 23:47:18 にビルドを開始しました。
ノード 1 上のプロジェクト "E:\test\sample.msbuild.xml" (既定のターゲット)。
Build:
  TextFiles : test1.txt;test2.txt;test3.txt
  SourceFiles : Main.cs;Form.cs
  ResourceFiles : Button.bmp;Background.jpg;Notice.wav
  ResourceFiles : Button.bmp, Background.jpg, Notice.wav
  ResourceFiles : Button.bmp/Background.jpg/Notice.wav
プロジェクト "E:\test\sample.msbuild.xml" (既定のターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.08

ItemGroupはPropertyGroupと似ているが、こちらは主にファイルのリストなどの「アイテム」を定義するために用いる。 タスクのパラメータとして引き渡す場合に用いる他、Copyタスクで実際にコピーされたファイルの一覧を取得するなど、タスクの出力パラメータとしてもアイテムを得ることができる。

ここでの要点は下記の通り。

  • ItemGroup要素を用いるとプロパティを宣言出来る
    • ItemGroup要素の子要素の名前がそのままアイテム名となる
    • アイテムは任意の名前で定義できる
    • アイテムの値を参照する場合は、「@(アイテム名)」とする
  • Include属性でワイルドカードを指定した場合、カレントディレクトリにあるファイルのうち、ワイルドカードにマッチするファイルのみが指定される
  • Exclude属性を指定すると、ワイルドカードにマッチするファイルは除外される
  • Messageタスクで出力する際の区切り文字を変える場合は、アイテム名の後ろに使いたい区切り文字を指定する

§2.7 タスク出力の取得 (Output)

Output要素を使った例。

Output
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
    <Target Name="Build">
        <Delete Files="bar.txt">
            <Output TaskParameter="DeletedFiles" ItemName="FilesDeleted" />
        </Delete>
        <Delete Files="foo.txt">
            <Output TaskParameter="DeletedFiles" ItemName="FilesDeleted" />
        </Delete>
        <Touch Files="foo.txt;bar.txt;baz.txt" AlwaysCreate="True">
            <Output TaskParameter="TouchedFiles" ItemName="FilesUpdated" />
        </Touch>
        <Message Text="@(FilesDeleted, ', ')を削除しました。" />
        <Message Text="@(FilesUpdated, ', ')を更新しました。" />
    </Target>
</Project>
実行結果
D:\>msbuild sample.msbuild.xml

2013/06/12 23:48:02 にビルドを開始しました。
ノード 1 上のプロジェクト "E:\test\sample.msbuild.xml" (既定のターゲット)。
Build:
  "AlwaysCreate" が指定されたため "foo.txt" を作成しています。
  "AlwaysCreate" が指定されたため "bar.txt" を作成しています。
  "AlwaysCreate" が指定されたため "baz.txt" を作成しています。
  bar.txt, foo.txtを削除しました。
  foo.txt, bar.txt, baz.txtを更新しました。
プロジェクト "E:\test\sample.msbuild.xml" (既定のターゲット) のビルドが完了しました。

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.14

Output要素を用いると、タスクの出力をアイテムもしくはプロパティとして取得できる。

ここでの要点は下記の通り。

  • タスクの要素内でOutput要素を記述すると、タスクの出力を取得できる
    • Output要素のTaskParameter属性で出力する値を指定する
    • Output要素のItemName属性で出力先のアイテム名を指定する
    • ItemName属性の代わりにPropertyName属性を使うことでプロパティ名を指定することもできる

§3 具体例

§3.1 Cscタスクを使ってC#ファイルをコンパイルする

Cscタスクを用いると、cscコンパイラを使ってC#ソースファイルをコンパイルすることが出来る。 ここではいくつかのソースファイル、リソースファイルからWindows実行可能ファイルを生成するための例を示す。

C#ソースファイル、リソースファイルをコンパイルしてWindows実行可能ファイルを生成する例
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
    <!-- プロパティを設定する -->
    <PropertyGroup>
        <!-- アセンブリ名 -->
        <AssemblyName>ScreenCapturer2</AssemblyName>

        <!-- 出力ファイルの種類 -->
        <TargetType>WinExe</TargetType>

        <!-- 構成の種類(指定されていない場合はデフォルトとしてDebugを設定する) -->
        <Configuration Condition="'$(Configuration)'==''">Debug</Configuration>
    </PropertyGroup>

    <!-- Debug構成 -->
    <PropertyGroup Condition="'$(Configuration)'=='Debug'">
        <!-- 出力先ディレクトリ -->
        <OutputPath>bin\Debug\</OutputPath>

        <!-- デバッグ情報出力あり -->
        <EmitDebugInformation>true</EmitDebugInformation>

        <!-- 条件付きコンパイルに適用するシンボル -->
        <DefineConstants>DEBUG;TRACE</DefineConstants>
    </PropertyGroup>

    <!-- Release構成 -->
    <PropertyGroup Condition="'$(Configuration)'=='Release'">
        <!-- 出力先ディレクトリ -->
        <OutputPath>bin\Release\</OutputPath>

        <!-- デバッグ情報出力なし -->
        <EmitDebugInformation>false</EmitDebugInformation>
    </PropertyGroup>

    <!-- 入力ファイルの一覧を作成する -->
    <ItemGroup>
        <!-- C#ソースファイル -->
        <CSCodeFile Include="*.cs"/>

        <!-- resxファイル -->
        <ResXFile Include="*.resx"/>

        <!-- 参照に追加するアセンブリ -->
        <References Include="System.dll"/>
        <References Include="System.Drawing.dll"/>
        <References Include="System.Windows.Forms.dll"/>
    </ItemGroup>

    <!-- クリーンを行うターゲット -->
    <Target Name="Clean">
        <RemoveDir Directories="$(OutputPath)"/>
    </Target>

    <!-- リソースの変換を行うターゲット -->
    <Target Name="Resources">
        <!-- 出力ディレクトリが無ければ、作成する -->
        <MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')"/>

        <!-- GenerateResourceタスクを使用してリソースを変換する -->
        <!-- http://msdn2.microsoft.com/ja-jp/library/ms164295(VS.80).aspx -->
        <GenerateResource
            Sources="@(ResXFile)"
            OutputResources="@(ResXFile->'$(OutputPath)%(Filename).resources')">
            <Output TaskParameter="OutputResources" ItemName="Resources"/>
        </GenerateResource>

        <!-- 出力ファイル名をログに出力する -->
        <Message Text="Output file(s): @(Resources)"/>
    </Target>

    <!-- ビルドを行う -->
    <Target Name="Build" DependsOnTargets="Resources">
        <!-- 構成名をログに出力する -->
        <Message Text="Configuration: $(Configuration)"/>

        <!-- 出力ディレクトリが無ければ、作成する -->
        <MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')"/>

        <!-- Cscタスクを使用してCSCodeFileで定義されているファイルをソースとして -->
        <!-- コンパイルする -->
        <!-- http://msdn2.microsoft.com/ja-jp/library/s5c8athz(VS.80).aspx -->
        <Csc
            Sources="@(CSCodeFile)"
            Resources="@(Resources)"
            References="@(References)"
            TargetType="$(TargetType)"
            EmitDebugInformation="$(EmitDebugInformation)"
            OutputAssembly="$(OutputPath)$(AssemblyName).exe">

            <!-- 出力ファイルをOutputFileという名前で格納する -->
            <Output TaskParameter="OutputAssembly" ItemName="OutputFile"/>
        </Csc>

        <!-- 出力ファイル名をログに出力する-->
        <Message Text="Output file(s): @(OutputFile)"/>
    </Target>

    <!-- ビルド後、実行する -->
    <Target Name="Run" DependsOnTargets="Build">
        <Exec Command="$(OutputPath)$(AssemblyName).exe"/>
    </Target>
</Project>

実行結果は次の通り。

C:\Documents and Settings\smdn\My Documents\sample>msbuild sample.msbuild.xml /t:Run /p:Configuration=Release
Microsoft(R) Build Engine Version 2.0.50727.42
[Microsoft .NET Framework, Version 2.0.50727.42]
Copyright (C) Microsoft Corporation 2005. All rights reserved.

ビルドが 2007/02/11 23:17:28 を開始しました。
__________________________________________________
プロジェクト "C:\Documents and Settings\smdn\My Documents\sample\sample.msbuild.xml" (Run ターゲット):

ターゲット Resources:
    ディレクトリ "bin\Release\" を作成しています。
    リソース ファイル "MainForm.resx" を "bin\Release\MainForm.resources" に処理しています。
    Output file(s): bin\Release\MainForm.resources
ターゲット Build:
    Configuration: Release
    C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Csc.exe /debug- /out:bin\Release\ScreenCapturer2.exe
/resource:bin\Release\MainForm.resources /target:winexe AssemblyInfo.cs HotKey.cs
MainForm.cs ScreenCapturer.cs ScreenShot.cs
    Output file(s): bin\Release\ScreenCapturer2.exe
ターゲット Run:
    bin\Release\ScreenCapturer2.exe

ビルドに成功しました。
    0 警告
    0 エラー

経過時間 00:00:03.89

ビルドに成功すると、コンパイルしたバイナリが起動し、ウィンドウが現れる。 ウィンドウを閉じてバイナリを終了すると、MSBuildの完了メッセージが出力される。