チュートリアル: MSBuild を使用する
MSBuild は Microsoft および Visual Studio のビルド プラットフォームです。 このチュートリアルでは、MSBuild のビルド ブロックについて説明し、MSBuild プロジェクトを記述、操作、デバッグする方法について説明します。 内容は次のとおりです。
プロジェクト ファイルの作成と操作
ビルド プロパティの使用方法。
ビルド項目の使用方法
MSBuild は、Visual Studio から実行することも、コマンド ウィンドウから実行することもできます。 このチュートリアルでは、Visual Studio を使用して MSBuild プロジェクト ファイルを作成します。 そのプロジェクト ファイルを Visual Studio で編集した後、コマンド ウィンドウを使用してプロジェクトをビルドして、結果を確認します。
MSBuild をインストールする
Visual Studio をご利用の場合、既に MSBuild がインストールされています。 Visual Studio 2019 以降の場合、Visual Studio のインストール フォルダーの下にインストールされます。 Windows 10 での一般的な既定のインストールの場合、MSBuild\Current\Bin のインストール フォルダーの下に MSBuild.exe が置かれます。
インストーラーで、使用するワークロード向けの MSBuild ツールが選択されていることを確認し、[インストール] を選択します。
Visual Studio のないシステムに MSBuild をインストールするには、Build Tools for Visual Studio 2019 にアクセスするか、.NET SDK をインストールしてください。
Visual Studio をご利用の場合、既に MSBuild がインストールされています。 Visual Studio 2022 の場合、Visual Studio のインストール フォルダーの下にインストールされます。 Windows 10 での一般的な既定のインストールの場合、MSBuild\Current\Bin のインストール フォルダーの下に MSBuild.exe が置かれます。
Visual Studio インストーラーで、[個別のコンポーネント] に移動し、[MSBuild] のチェックボックスを見つけます。 インストールするその他のワークロードのいずれかを選択すると、これは自動的にオンになります。
Visual Studio のないシステムに MSBuild をインストールするには、ダウンロード ページの「Build Tools for Visual Studio 2022」にアクセスしてください。 MSBuild を入手するもう 1 つの方法は、.NET SDK をインストールすることです。
MSBuild プロジェクトの作成
Visual Studio プロジェクト システムは MSBuild に基づいています。 Visual Studio を使用すると、新しいプロジェクト ファイルを簡単に作成できます。 このセクションでは、C# プロジェクト ファイルを作成します。 代わりに、Visual Basic プロジェクト ファイルを作成することもできます。 このチュートリアルのコンテキストでは、2 つのプロジェクト ファイルにはわずかな違いしかありません。
プロジェクト ファイルを作成するには
Visual Studio を開き、プロジェクトを作成します。
検索ボックスに「
winforms
」と入力して、[新しい Windows フォーム アプリの作成 (.NET Framework)] を選択します。 表示されたダイアログ ボックスで、 [作成] を選択します。[プロジェクト名] ボックスに「
BuildApp
」と入力します。 [場所] ボックスにソリューションの場所を入力します (「D:\」など)。[OK] または [作成] をクリックして、プロジェクト ファイルを作成します。
プロジェクト ファイルを確認する
前のセクションでは、Visual Studio を使用して C# プロジェクト ファイルを作成しました。 このプロジェクト ファイルは、BuildApp という名前のプロジェクト ノードとしてソリューション エクスプローラーに表示されます。 Visual Studio Code エディターを使用してこのプロジェクト ファイルを確認できます。
プロジェクト ファイルを確認するには
ソリューション エクスプローラーで、BuildApp というプロジェクト ノードをクリックします。
プロパティ ブラウザーで、[プロジェクト ファイル] プロパティが BuildApp.csproj になっていることを確認します。 プロジェクト ファイルはすべて、名前に proj というサフィックスが付いています。 Visual Basic プロジェクトを作成した場合は、プロジェクト ファイルの名前が BuildApp.vbproj になります。
プロジェクト ノードを再度右クリックし、[BuildApp.csproj の編集] をクリックします。
コード エディターにプロジェクト ファイルが表示されます。
Note
C++ など、プロジェクト タイプによっては、プロジェクト ファイルを開いて編集する前にプロジェクトをアップロードする必要があります (プロジェクト ファイルを右クリックし、[プロジェクトのアンロード] を選択します)。
ターゲットとタスク
プロジェクト ファイルは XML 形式のファイルで、ルート ノードは Project です。
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
ほとんどの .NET プロジェクトには Sdk
属性があります。 これらのプロジェクトは SDK スタイルのプロジェクトと呼ばれます。
<Project Sdk="Microsoft.NET.Sdk">
特別な用途のために、.NET SDK にはさまざまなバリエーションがあります。これらは .NET Project SDK で説明されています。
アプリケーションをビルドする作業は、Target 要素と Task 要素を使用して行われます。
タスクとは、作業の最小単位であり、ビルドの "原子" のようなものです。 タスクは独立した実行可能コンポーネントで、入力と出力を含むことができます。 現在このプロジェクト ファイルで参照または定義されているタスクはありません。 以下のセクションで、このプロジェクト ファイルにタスクを追加します。 詳細については、タスクに関する記事を参照してください。
ターゲットとは、一連のタスクに名前を付けたものです。 一連のタスクに名前を付けたものかもしれませんが、構築するか完了する何かを表します。これは非常に重要なことです。そのため、目標をはっきりさせて定義してください。 詳細については、ターゲット を参照してください。
既定のターゲットは、このプロジェクト ファイルでは定義されていません。 代わりに、インポートされるプロジェクトで指定されています。 Import 要素は、インポートされたプロジェクトを指定します。 たとえば、C# プロジェクトでは、既定のターゲットが Microsoft.CSharp.targets ファイルからインポートされます。
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
インポートされたファイルは、実質的には、プロジェクト ファイルで参照されている場所に挿入されます。
SDK スタイルのプロジェクトでは、このインポート要素が表示されません。SDK 属性によってこのファイルが暗黙的にインポートされるためです。
MSBuild ではビルドのターゲットが追跡されるため、個々のターゲットが複数回ビルドされることはありません。
ターゲットとタスクを追加する
プロジェクト ファイルにターゲットを追加し、 そのターゲットに、メッセージを出力するタスクを追加します。
ターゲットとタスクを追加するには
プロジェクト ファイルの Import ステートメント、または Project の開始要素の直後に、以下の行を追加します。
<Target Name="HelloWorld"> </Target>
このコードで、HelloWorld というターゲットが作成されます。 プロジェクト ファイルの編集時には IntelliSense がサポートされます。
セクションが次のようになるように、HelloWorld ターゲットに行を追加します。
<Target Name="HelloWorld"> <Message Text="Hello"></Message> <Message Text="World"></Message> </Target>
プロジェクト ファイルを保存します。
Message
タスクは、MSBuild に含まれている数多くのタスクの 1 つです。 使用可能なすべてのタスクと使用法については、「タスク リファレンス」をご覧ください。
Message
タスクでは、Text 属性の文字列値を入力として受け取り、それを出力デバイスに表示します (あるいは、該当する場合、1 つまたは複数のログに書き込みます)。 HelloWorld ターゲットでは、Message タスクが 2 回実行されます。1 回目の実行で "Hello" と表示され、2 回目の実行で "World" と表示されます。
ターゲットをビルドする
Visual Studio からこのプロジェクトを構築する場合、定義したターゲットは構築されません。 Visual Studio では、インポートされた .targets
ファイルに含まれたままの、既定のターゲットが選択されるためです。
Visual Studio の開発者コマンド プロンプトから MSBuild を実行して、前に定義した HelloWorld ターゲットをビルドします。 ターゲットを選択するには、コマンドライン スイッチの -target または -t を使用します。
Note
以下のセクションでは、開発者コマンド プロンプトをコマンド ウィンドウと呼びます。
ターゲットをビルドするには:
コマンド ウィンドウを開きます。
タスクバーの検索ボックスに、
dev
やdeveloper command prompt
など、ツールの名前を入力します。 検索パターンに一致する、インストールされているアプリの一覧が表示されます。手動で検索する必要がある場合、ファイルは {Visual Studio インストール フォルダー}\Common7\Tools フォルダー内の LaunchDevCmd.bat です。
コマンド ウィンドウで、プロジェクト ファイルを含むフォルダー (この場合は D:\BuildApp\BuildApp) に移動します。
コマンド スイッチ
-t:HelloWorld
を使用して msbuild を実行します。 このコマンドで HelloWorld ターゲットが選択されてビルドされます。msbuild buildapp.csproj -t:HelloWorld
コマンド ウィンドウで出力を確認します。 "Hello" と "World" の 2 つの行が表示されます。
Hello World
Note
"The target "HelloWorld" does not exist in the project
" と表示される場合は、コード エディターでプロジェクト ファイルが保存されていない可能性があります。 ファイルを保存して、やり直してください。
コード エディターとコマンド ウィンドウを交互に使用すると、プロジェクト ファイルを変更してすばやく結果を確認できます。
ビルド プロパティ
ビルド プロパティは、ビルドを制御する名前と値のペアです。 このプロジェクト ファイルの先頭には、既にいくつかのビルド プロパティが定義されています。
<PropertyGroup>
...
<ProductVersion>10.0.11107</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{30E3C9D5-FD86-4691-A331-80EA5BA7E571}</ProjectGuid>
<OutputType>WinExe</OutputType>
...
</PropertyGroup>
すべてのプロパティは、PropertyGroup 要素の子要素です。 子要素の名前がプロパティの名前になり、子要素のテキスト要素がプロパティの値になります。 たとえば、 にします。
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
ここでは、TargetFrameworkVersion という名前のプロパティを定義して、文字列値 "v4.5" を割り当てています。
ビルド プロパティはいつでも再定義できます。 次の場合
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
上の行が、プロジェクト ファイルの後半に含まれていたり、プロジェクト ファイルの後半でインポートされるファイルに含まれていたりした場合は、TargetFrameworkVersion に "v3.5" という新しい値が割り当てられます。
プロパティ値を確認する
プロパティの値を取得するには、次の構文を使用します。ここで、PropertyName
はプロパティの名前です。
$(PropertyName)
この構文を使用して、プロジェクト ファイルのいくつかのプロパティを確認します。
プロパティ値を確認するには
コード エディターで、HelloWorld ターゲットを次のコードに置き換えます。
<Target Name="HelloWorld"> <Message Text="Configuration is $(Configuration)" /> <Message Text="MSBuildToolsPath is $(MSBuildToolsPath)" /> </Target>
プロジェクト ファイルを保存します。
コマンド ウィンドウで、次の行を入力して実行します。
msbuild buildapp.csproj -t:HelloWorld
出力を調べます。 次の 2 つの行が表示されます (出力は異なる場合があります)。
Configuration is Debug MSBuildToolsPath is C:\Program Files\Microsoft Visual Studio\2022\MSBuild\Current\Bin\amd64
Configuration is Debug MSBuildToolsPath is C:\Program Files (x86)\Microsoft Visual Studio\2019\MSBuild\16.0\Bin
条件付きプロパティ
Configuration
など、多くのプロパティは、Condition
属性を使用して条件付きで定義されます。 条件付きプロパティは、条件が "true" と評価された場合にのみ定義 (または再定義) されます。未定義のプロパティには、既定値として空の文字列が割り当てられます。 たとえば、 にします。
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
これは、"Configuration プロパティが定義されていない場合に、それを定義して値を 'Debug' に設定する" という意味になります。
Condition 属性は MSBuild のほぼすべての要素に設定できます。 Condition 属性の使用の詳細については、「MSBuild Conditions (MSBuild の条件)」をご覧ください。
予約済みのプロパティ
MSBuild では、プロジェクト ファイルに関する情報や MSBuild のバイナリに関する情報を保持するために、いくつかのプロパティ名が予約されています。 たとえば、MSBuildToolsPath も予約済みのプロパティの 1 つです。 予約済みのプロパティは、他のプロパティと同じように $ 表記で参照できます。 詳細については、「方法: プロジェクト ファイルの名前または場所を参照する」および「MSBuild の予約済みおよび既知のプロパティ」をご覧ください。
環境変数
プロジェクト ファイルで環境変数を参照する場合も、ビルド プロパティを参照するときと同じ方法を使用します。 たとえば、プロジェクト ファイルで PATH 環境変数を使用するには、$(Path) と記述します。 プロジェクト ファイルに、環境変数と同じ名前のプロパティが定義されている場合、環境変数の値はプロジェクト内のプロパティによってオーバーライドされます。 環境変数の使用方法の詳細については、「方法: ビルドで環境変数を使用する」をご覧ください。
コマンドラインからプロパティを設定する
プロパティは、コマンド ライン スイッチの -property または -p を使用してコマンド ラインで定義することもできます。 プロジェクト ファイルに設定されたプロパティ値や環境変数として設定されたプロパティ値は、コマンド ラインから渡されたプロパティ値によってオーバーライドされます。
コマンド ラインからプロパティ値を設定するには:
コマンド ウィンドウで、次の行を入力して実行します。
msbuild buildapp.csproj -t:HelloWorld -p:Configuration=Release
出力を調べます。 次の行が表示されます。
Configuration is Release.
MSBuild で Configuration プロパティが作成され、値が "Release" に設定されます。
特殊文字
MSBuild プロジェクト ファイルでは、特定の文字が特殊な意味を持ちます。 そのような文字の例として、セミコロン (;) およびアスタリスク (*) があります。 これらの特殊文字をプロジェクト ファイル内でリテラルとして使用するには、構文 %<xx> でそれらの文字を指定する必要があります。<xx> は文字の ASCII 16 進値を表します。
Message タスクに変更を加えて、特殊文字を使用して Configuration プロパティの値を読みやすくします。
Message タスクで特殊文字を使用するには:
コード エディターで、両方の Message タスクを次の行に置き換えます。
<Message Text="%24(Configuration) is %22$(Configuration)%22" />
プロジェクト ファイルを保存します。
コマンド ウィンドウで、次の行を入力して実行します。
msbuild buildapp.csproj -t:HelloWorld
出力を調べます。 次の行が表示されます。
$(Configuration) is "Debug"
詳細については、「MSBuild の特殊文字」をご覧ください。
ビルド項目
項目とは、ファイル名など、ビルド システムへの入力として使用される情報です。 たとえば、ソース ファイルを表す項目のコレクションを Compile という名前のタスクに渡して、アセンブリにコンパイルする場合などがあります。
すべての項目は、ItemGroup 要素の子要素です。 子要素の名前が項目の名前になり、子要素の Include 属性の値が項目の値になります。 同じ名前を持つ項目の値は、その名前の項目の種類に収集されます。 たとえば、次のように入力します。
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
ここでは、2 つの項目を含む項目グループを定義しています。 項目の種類 Compile には、Program.cs と Properties\AssemblyInfo.cs の 2 つの値があります。
次のコードでは、両方のファイルをセミコロンで区切って 1 つの Include
属性で宣言することで、同じ項目の種類を作成しています。
<ItemGroup>
<Compile Include="Program.cs;Properties\AssemblyInfo.cs" />
</ItemGroup>
詳細については、「MSBuild 項目」をご覧ください。
Note
プロジェクト ファイルがインポートされたプロジェクト ファイルであっても、ファイル パスは、MSBuild プロジェクト ファイルが含まれるフォルダーからの相対パスになります。 これには例外がいくつかあります。Import 要素や UsingTask 要素の使用時などです。
項目の種類の値を確認する
項目の種類の値を取得するには、次の構文を使用します。ここで、ItemType
は項目の種類の名前です。
@(ItemType)
この構文を使用して、プロジェクト ファイルの項目の種類 Compile
を確認します。
項目の種類の値を確認するには:
コード エディターで、HelloWorld ターゲット タスクを次のコードに置き換えます。
<Target Name="HelloWorld"> <Message Text="Compile item type contains @(Compile)" /> </Target>
プロジェクト ファイルを保存します。
コマンド ウィンドウで、次の行を入力して実行します。
msbuild buildapp.csproj -t:HelloWorld
出力を調べます。 次の長い行が表示されます。
Compile item type contains Form1.cs;Form1.Designer.cs;Program.cs;Properties\AssemblyInfo.cs;Properties\Resources.Designer.cs;Properties\Settings.Designer.cs
項目の種類の値は、既定ではセミコロンで区切られます。
項目の種類の区切り記号を変更するには、次の構文を使用します。ここで、ItemType は項目の種類、Separator は 1 文字以上の区切り記号です。
@(ItemType, Separator)
Message タスクに変更を加えて、復帰と改行 (%0A%0D) を使用して Compile 項目を 1 行に 1 つずつ表示します。
項目の種類の値を 1 行に 1 つずつ表示するには
コード エディターで、Message タスクを次の行に置き換えます。
<Message Text="Compile item type contains @(Compile, '%0A%0D')" />
プロジェクト ファイルを保存します。
コマンド ウィンドウで、次の行を入力して実行します。
msbuild buildapp.csproj -t:HelloWorld
出力を調べます。 次の行が表示されます。
Compile item type contains Form1.cs Form1.Designer.cs Program.cs Properties\AssemblyInfo.cs Properties\Resources.Designer.cs Properties\Settings.Designer.cs
Include、Exclude、およびワイルドカード
Include 属性でワイルドカード ("*"、"**"、および "?") を使用して、項目を項目の種類に追加できます。 たとえば、次のように入力します。
<Photos Include="images\*.jpeg" />
この例では、images フォルダーにある拡張子が .jpeg のすべてのファイルが項目の種類 Photos に追加されます。もう 1 つ例を見てましょう。
<Photos Include="images\**\*.jpeg" />
この例では、images フォルダーとそのすべてのサブフォルダーにある拡張子が .jpeg のすべてのファイルが項目の種類 Photos に追加されます。 例については、「方法: ビルドするファイルを選択する」をご覧ください。
項目を宣言すると、それらが項目の種類に追加されます。 たとえば、 にします。
<Photos Include="images\*.jpeg" />
<Photos Include="images\*.gif" />
この例では、image フォルダーにある拡張子が .jpeg
または .gif
のすべてのファイルを含む、Photos という名前の項目の種類が作成されます。 これらの行は次の行と同じです。
<Photos Include="images\*.jpeg;images\*.gif" />
項目の種類から項目を除外するには、Exclude
属性を使用します。 たとえば、 にします。
<Compile Include="*.cs" Exclude="*Designer*">
この例では、拡張子が .cs のすべてのファイルが項目の種類 Compile に追加されますが、名前に文字列 Designer が含まれているファイルは除外されます。 例については、「方法: ビルドからファイルを除外する」をご覧ください。
Exclude
属性は、同一の項目要素内にある Include 属性によって追加された項目のみに作用します。 たとえば、 にします。
<Compile Include="*.cs" />
<Compile Include="*.res" Exclude="Form1.cs">
この例では、Form1.cs ファイルは前の項目要素で追加されているため、除外されません。
項目を追加および除外するには
コード エディターで、Message タスクを次の行に置き換えます。
<Message Text="XFiles item type contains @(XFiles)" />
Import 要素の直後に次の項目グループを追加します。
<ItemGroup> <XFiles Include="*.cs;properties/*.resx" Exclude="*Designer*" /> </ItemGroup>
プロジェクト ファイルを保存します。
コマンド ウィンドウで、次の行を入力して実行します。
msbuild buildapp.csproj -t:HelloWorld
出力を調べます。 次の行が表示されます。
XFiles item type contains Form1.cs;Program.cs;Properties/Resources.resx
項目メタデータ
項目には、Include
および Exclude
属性から収集された情報に加えて、メタデータを含めることができます。 このメタデータは、項目の値だけでなく項目に関する詳細情報を必要とするタスクで使用できます。
アイテム メタデータは、そのメタデータ名を名前に持つ要素を、項目の子として作成することにより、プロジェクト ファイルで宣言します。 項目には 0 以上のメタデータ値を指定できます。 たとえば、次の CSFile 項目には、値 "Fr" の Culture メタデータがあります。
<ItemGroup>
<CSFile Include="main.cs">
<Culture>Fr</Culture>
</CSFile>
</ItemGroup>
項目の種類のメタデータ値を取得するには、次の構文を使用します。ここで、ItemType
は項目の種類の名前、MetaDataName はメタデータの名前です。
%(ItemType.MetaDataName)
項目メタデータを確認するには:
コード エディターで、Message タスクを次の行に置き換えます。
<Message Text="Compile.DependentUpon: %(Compile.DependentUpon)" />
プロジェクト ファイルを保存します。
コマンド ウィンドウで、次の行を入力して実行します。
msbuild buildapp.csproj -t:HelloWorld
出力を調べます。 次の行が表示されます。
Compile.DependentUpon: Compile.DependentUpon: Form1.cs Compile.DependentUpon: Resources.resx Compile.DependentUpon: Settings.settings
"Compile.DependentUpon" というフレーズが何回か出現しています。 ターゲット内でメタデータを使用する際にこの構文を使用すると、"バッチ処理" が行われます。バッチ処理では、ターゲット内のタスクが各メタデータ値について 1 回だけ実行されます。 バッチ処理は、一般的なプログラミング構造の "foreach ループ" に相当する MSBuild スクリプトです。 詳細については、「MSBuild バッチ」をご覧ください。
既知のメタデータ
項目リストに追加した項目には、既知のメタデータが割り当てられます。 たとえば、項目のファイル名を返す %(Filename) などです。 すべての既知のメタデータの一覧については、「MSBuild 既知のアイテム メタデータ」をご覧ください。
既知のメタデータを確認するには:
コード エディターで、Message タスクを次の行に置き換えます。
<Message Text="Compile Filename: %(Compile.Filename)" />
プロジェクト ファイルを保存します。
コマンド ウィンドウで、次の行を入力して実行します。
msbuild buildapp.csproj -t:HelloWorld
出力を調べます。 次の行が表示されます。
Compile Filename: Form1 Compile Filename: Form1.Designer Compile Filename: Program Compile Filename: AssemblyInfo Compile Filename: Resources.Designer Compile Filename: Settings.Designer
この例を前の 2 つの例と比較すると、DependentUpon メタデータは項目の種類 Compile のすべての項目には含まれていないのに対し、既知のメタデータ Filename はすべての項目に含まれていることがわかります。
メタデータの変換
既存の項目リストを新しい項目リストに変換できます。 項目リストを変換するには、次の構文を使用します。ここで、<ItemType> は項目の種類の名前、<MetadataName> はメタデータの名前です。
@(ItemType -> '%(MetadataName)')
たとえば、@(SourceFiles -> '%(Filename).obj')
のような式を使用すると、ソース ファイルの項目リストをオブジェクト ファイルのコレクションに変換できます。 詳細については、「MSBuild 変換」をご覧ください。
メタデータを使用して項目を変換するには:
コード エディターで、Message タスクを次の行に置き換えます。
<Message Text="Backup files: @(Compile->'%(filename).bak')" />
プロジェクト ファイルを保存します。
コマンド ウィンドウで、次の行を入力して実行します。
msbuild buildapp.csproj -t:HelloWorld
出力を調べます。 次の行が表示されます。
Backup files: Form1.bak;Form1.Designer.bak;Program.bak;AssemblyInfo.bak;Resources.Designer.bak;Settings.Designer.bak
この構文で表されるメタデータではバッチ処理は行われないことに注意してください。
次のステップ
Windows で簡単なプロジェクト ファイルを 1 ステップずつ作成する方法については、「MSBuild プロジェクト ファイルのゼロからの作成」を参照してください。
主に .NET SDK を使用している場合は、続けて「.NET SDK プロジェクトの MSBuild リファレンス」に目を通してください。