プロジェクト ファイルについて

作成者: Jason Lee

Microsoft Build Engine (MSBuild) プロジェクト ファイルは、ビルドと配置のプロセスの中心にあります。 このトピックでは、MSBuild とプロジェクト ファイルの概念の概要から始めます。 ここでは、プロジェクト ファイルで作業するときに使用する主要なコンポーネントについて説明し、プロジェクト ファイルを使用して実際のアプリケーションを配置する方法の例を示します。

ここでは、次の内容について学習します。

  • MSBuild で MSBuild プロジェクト ファイルを使用してプロジェクトをビルドする方法。
  • MSBuild と配置テクノロジの統合方法 (インターネット インフォメーション サービス (IIS) Web 配置ツール (Web 配置) など)。
  • プロジェクト ファイルの主要なコンポーネントを理解する方法。
  • プロジェクト ファイルを使用して複雑なアプリケーションをビルドおよび配置する方法。

MSBuild とプロジェクト ファイル

Visual Studio でソリューションを作成してビルドすると、Visual Studio は MSBuild を使用してソリューション内の各プロジェクトをビルドします。 すべての Visual Studio プロジェクトには、MSBuild プロジェクト ファイルが含まれています。ファイル拡張子はプロジェクトの種類を反映しています。たとえば、C# プロジェクト (.csproj)、Visual Basic .NET プロジェクト (.vbproj)、データベース プロジェクト (.dbproj) などです。 プロジェクトをビルドするには、プロジェクトに関連付けられているプロジェクト ファイルを MSBuild で処理する必要があります。 プロジェクト ファイルとは、MSBuild がプロジェクトをビルドするために必要なすべての情報と命令が含まれる XML ドキュメントのことです。これには、含めるコンテンツ、プラットフォーム要件、バージョン管理情報、Web サーバーまたはデータベース サーバーの設定、実行する必要のあるタスクなどがあります。

MSBuild プロジェクト ファイルは、MSBuild XML スキーマに基づいており、その結果、ビルド プロセスは完全にオープンで、透過的になります。 さらに、MSBuild エンジンを使用するために Visual Studio をインストールする必要はありません。MSBuild.exe 実行可能ファイルは .NET Framework の一部であり、コマンド プロンプトから実行できます。 開発者は、MSBuild XML スキーマを使用して独自の MSBuild プロジェクト ファイルを作成し、プロジェクトのビルドと配置方法を高度かつきめ細かく制御できます。 これらのカスタム プロジェクト ファイルは、Visual Studio によって自動的に生成されるプロジェクト ファイルとまったく同じように動作します。

Note

また、Team Foundation Server (TFS) のチーム ビルド サービスで MSBuild プロジェクト ファイルを使用することもできます。 たとえば、継続的インテグレーション (CI) シナリオでプロジェクト ファイルを使用して、新しいコードがチェックインされたときにテスト環境への配置を自動化できます。 詳細については、「自動 Web 配置のための Team Foundation Server の構成」を参照してください。

プロジェクト ファイルの名前付け規則

独自のプロジェクト ファイルを作成する場合は、任意のファイル拡張子を使用できます。 ただし、ソリューションを他のユーザーが理解しやすくするには、次の一般的な規則を使用する必要があります。

  • プロジェクトをビルドするプロジェクト ファイルを作成するときは、.proj 拡張子を使用します。
  • 再利用可能なプロジェクト ファイルを作成して他のプロジェクト ファイルにインポートする場合は、.targets 拡張子を使用します。 .targets 拡張子を持つファイルは、通常、それ自体は何もビルドしません。.proj ファイルにインポートできる命令が含まれています。

配置テクノロジとの統合

Visual Studio 2010 で Web アプリケーション プロジェクト (ASP.NET Web アプリケーションや ASP.NET MVC Web アプリケーションなど) を操作したことがある場合、これらのプロジェクトには、Web アプリケーションのパッケージ化とターゲット環境への展開に関する組み込みのサポートが含まれていることがわかります。 これらのプロジェクトの [プロパティ] ページには、アプリケーションのコンポーネントのパッケージ化と展開方法を構成するために使用できる [Web のパッケージ化/発行] タブと [SQL のパッケージ化/発行] タブがあります。 [Web のパッケージ化/発行] タブを示します。

The Package/Publish Web tab

これらの機能の背後にある基盤となるテクノロジは、Web 発行パイプライン (WPP) と呼ばれます。 WPP は基本的に MSBuild と Web 配置を組み合わせて、Web アプリケーションの完全なビルド、パッケージ化、配置プロセスを行います。

Web プロジェクト用のカスタム プロジェクト ファイルを作成するときに WPP によって提供される統合ポイントを利用できます。 配置に関する命令をプロジェクト ファイルに含めることができます。これにより、1 つのプロジェクト ファイルと MSBuild への 1 回の呼び出しを使用して、プロジェクトのビルド、Web 配置パッケージの作成、リモート サーバーへのこれらのパッケージのインストールを行うことができます。 ビルド プロセスの一環として、他の実行可能ファイルを呼び出すこともできます。 たとえば、VSDBCMD.exe コマンドライン ツールを実行して、スキーマ ファイルからデータベースを配置できます。 このトピックでは、これらの機能を利用して、エンタープライズ展開シナリオの要件を満たす方法について説明します。

Note

Web アプリケーションの配置プロセスのしくみの詳細については、「ASP.NET Web アプリケーション プロジェクトの配置の概要」を参照してください。

プロジェクト ファイルの構造

ビルド プロセスを詳しく見る前に、MSBuild プロジェクト ファイルの基本的な構造を理解しておく必要があります。 このセクションでは、プロジェクト ファイルを確認、編集、または作成するときに発生する、より一般的な要素の概要について説明します。 特に、次の内容について学習します。

  • "プロパティ" を使用してビルド プロセスの変数を管理する方法。
  • コード ファイルなどの "項目" を使用してビルド プロセスへの入力を識別する方法。
  • プロジェクト ファイル内の他の場所で定義されている "プロパティ" と "項目" を使用し、"ターゲット" と "タスク"を使用して、MSBuild に実行命令を提供する方法。

これは、MSBuild プロジェクト ファイル内のキー要素間の関係を示しています。

The relationship between the key elements in an MSBuild project file.

Project 要素

Project 要素は、すべてのプロジェクト ファイルのルート要素です。 プロジェクト ファイルの XML スキーマを識別するだけでなく、Project 要素には、ビルド プロセスのエントリ ポイントを指定する属性を含めることができます。 たとえば、Contact Manager サンプル ソリューションPublish.proj ファイルでは、FullPublish という名前のターゲットを呼び出してビルドを開始する必要があることを指定します。

<Project ToolsVersion="4.0" DefaultTargets="FullPublish" 
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  
</Project>

プロパティと条件

通常、プロジェクト ファイルは、プロジェクトを正常にビルドして配置するために、さまざまな情報を提供する必要があります。 これらの情報には、サーバー名、接続文字列、資格情報、ビルド構成、ソースと宛先のファイル パス、カスタマイズをサポートするために含めるその他の情報が含まれる場合があります。 プロジェクト ファイルでは、PropertyGroup 要素内でプロパティを定義する必要があります。 MSBuild プロパティは、キーと値のペアで構成されます。 PropertyGroup 要素内では、要素名によってプロパティ キーが定義され、要素の内容によってプロパティ値が定義されます。 たとえば、ServerNameConnectionString という名前のプロパティを定義して、静的サーバー名と接続文字列を格納できます。

<PropertyGroup>    
   <ServerName>FABRIKAM\TEST1</ServerName>
   <ConnectionString>
     Data Source=FABRIKAM\TESTDB;InitialCatalog=ContactManager,...
   </ConnectionString>
</PropertyGroup>

プロパティ値を取得するには、$(PropertyName) という形式を使用します。 たとえば、ServerName プロパティの値を取得するには、次のように入力します。

$(ServerName)

Note

プロパティ値を使用する方法とタイミングの例については、このトピックの後半で説明します。

プロジェクト ファイルに静的プロパティとして情報を埋め込むことが、ビルド プロセスを管理するための理想的なアプローチであるとは限りません。 多くのシナリオで、他のソースから情報を取得したり、ユーザーがコマンド プロンプトから情報を提供できるようにすることもあります。 MSBuild を使用すると、コマンド ライン パラメーターとして任意のプロパティ値を指定できます。 たとえば、ユーザーがコマンド ラインから MSBuild.exe を実行するときに、ServerName の値を指定できます。

msbuild.exe Publish.proj /p:ServerName=FABRIKAM\TESTWEB1

Note

MSBuild.exe で使用できる引数とスイッチの詳細については、「MSBuild コマンド ライン リファレンス」を参照してください。

同じプロパティ構文を使用して、環境変数と組み込みのプロジェクト プロパティの値を取得できます。 よく使用されるプロパティの多くが定義されており、関連するパラメーター名を含めることでそれらをプロジェクト ファイルで使用できます。 たとえば、現在のプロジェクト プラットフォーム (x86AnyCpu など) を取得するには、プロジェクト ファイルに $(Platform) プロパティ参照を含めることができます。 詳細については、ビルドのコマンドとプロパティのマクロに関するページ、「MSBuild プロジェクトの共通プロパティ」、および予約済みプロパティに関するページを参照してください。

プロパティは、多くの場合、"条件" と組み合わせて使用されます。 ほとんどの MSBuild 要素では Condition 属性をサポートしています。これにより、MSBuild で要素を評価する基準を指定できます。 たとえば、次のプロパティ定義について考えてみます。

<PropertyGroup>
   <OutputRoot Condition=" '$(OutputRoot)'=='' ">..\Publish\Out\</OutputRoot>
   ...
</PropertyGroup>

MSBuild がこのプロパティ定義を処理するときに、最初に $(OutputRoot) プロパティ値が使用可能かどうかを確認するためにチェックします。 プロパティ値が空白 (つまり、ユーザーはこのプロパティの値を指定していない) の場合、条件は true に評価され、プロパティ値は ..\Publish\Out に設定されます。ユーザーがこのプロパティの値を指定した場合、条件は false に評価され、静的プロパティ値は使用されません。

条件を指定するさまざまな方法の詳細については、「MSBuild の条件」を参照してください。

項目と項目グループ

プロジェクト ファイルの重要な役割の 1 つは、ビルド プロセスへの入力を定義することです。 通常、これらの入力はファイル (コード ファイル、構成ファイル、コマンド ファイル、およびビルド プロセスの一部として処理またはコピーする必要があるその他のファイル) です。 MSBuild プロジェクト スキーマでは、これらの入力は Item 要素によって表されます。 プロジェクト ファイルでは、ItemGroup 要素内で項目を定義する必要があります。 Property 要素と同様に、Item 要素には任意の名前を付けることができます。 ただし、項目が表すファイルまたはワイルドカードを識別するには、Include 属性を指定する必要があります。

<ItemGroup>
   <ProjectsToBuild Include="$(SourceRoot)ContactManager-WCF.sln"/>
</ItemGroup>

同じ名前の複数の Item 要素を指定することで、リソースの名前付きリストを効果的に作成できます。 これを実際に確認する適切な方法は、Visual Studio によって作成されるプロジェクト ファイルのいずれかの内容を確認することです。 たとえば、サンプル ソリューションの ContactManager.Mvc.csproj ファイルには多数の項目グループが含まれています。それぞれに、同じ名前の Item 要素がいくつか含まれています。

<ItemGroup>
   <Reference Include="Microsoft.CSharp" />
   <Reference Include="System.Runtime.Serialization" />
   <Reference Include="System.ServiceModel" />
   ...
</ItemGroup>
<ItemGroup>
   <Compile Include="Controllers\AccountController.cs" />
   <Compile Include="Controllers\ContactsController.cs" />
   <Compile Include="Controllers\HomeController.cs" />
   ...
</ItemGroup>
<ItemGroup>
   <Content Include="Content\Custom.css" />
   <Content Include="CreateDatabase.sql" />
   <Content Include="DropDatabase.sql" />
   ...
</ItemGroup>

このように、プロジェクト ファイルは MSBuild に対して、同じ方法で処理する必要があるファイルのリストを作成するように指示しています。Reference リストには、ビルドを正常に行うために配置する必要があるアセンブリが含まれています。Compile リストにはコンパイルする必要があるコード ファイルが含まれており、Content リストには変更されずにコピーする必要があるリソースが含まれています。 ビルド プロセスがこれらの項目を参照して使用する方法については、このトピックの後半で説明します。

Item 要素には、ItemMetadata 子要素を含めることもできます。 これらはユーザー定義のキーと値のペアであり、基本的にその項目に固有のプロパティを表します。 たとえば、プロジェクト ファイルの Compile 項目要素の多くには、DependentUpon 子要素が含まれています。

<Compile Include="Global.asax.cs">
   <DependentUpon>Global.asax</DependentUpon>
</Compile>

Note

ユーザーが作成した項目メタデータに加えて、すべての項目には作成時にさまざまな共通メタデータが割り当てられます。 詳細については、「既知の項目メタデータ」を参照してください。

ItemGroup 要素は、ルート レベルの Project 要素内または特定の Target 要素内に作成できます。 ItemGroup 要素は Condition 属性もサポートしています。これにより、プロジェクトの構成やプラットフォームなどの条件に応じて、ビルド プロセスに対する入力を調整できます。

ターゲットとタスク

MSBuild スキーマでは、Task 要素は個々のビルド命令 (つまりタスク) を表します。 MSBuild には、多数の定義済みタスクが含まれています。 次に例を示します。

  • Copy タスクは、ファイルを新しい場所にコピーします。
  • Csc タスクは、Visual C# コンパイラを呼び出します。
  • Vbc タスクは、Visual Basic コンパイラを呼び出します。
  • Exec タスクは、指定されたプログラムを実行します。
  • Message タスクは、ロガーにメッセージを書き込みます。

Note

すぐに使用できるタスクの詳細については、「MSBuild タスク リファレンス」を参照してください。 独自のカスタム タスクの作成方法など、タスクの詳細については、「MSBuild タスク」を参照してください。

タスクは常に Target 要素内に含まれている必要があります。 Target 要素は、順番に実行される 1 つ以上の一連のタスクであり、プロジェクト ファイルには複数のターゲットを含めることができます。 タスクまたは一連のタスクを実行する場合は、タスクを含むターゲットを呼び出します。 たとえば、メッセージをログに記録する単純なプロジェクト ファイルがあるとします。

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Target Name="LogMessage">
      <Message Text="Hello world!" />
   </Target>
</Project>

/t スイッチを使用してターゲットを指定することで、コマンド ラインからターゲットを呼び出すことができます。

msbuild.exe Publish.proj /t:LogMessage

または、DefaultTargets 属性を Project 要素に追加して、呼び出すターゲットを指定することもできます。

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 
         DefaultTargets="FullPublish">
   <Target Name="LogMessage">
      <Message Text="Hello world!" />
   </Target>
</Project>

この場合、コマンド ラインからターゲットを指定する必要はありません。 プロジェクト ファイルを指定するだけで、MSBuild によって FullPublish ターゲットが呼び出されます。

msbuild.exe Publish.proj

ターゲットとタスクの両方に Condition 属性を含めることができます。 そのため、特定の条件が満たされている場合は、ターゲット全体または個々のタスクを省略することができます。

一般に、便利なタスクとターゲットを作成するときは、プロジェクト ファイル内の他の場所で定義したプロパティと項目を参照する必要があります。

  • プロパティ値を使用するには、「$(PropertyName)」と入力します。ここで、PropertyNameProperty 要素の名前またはパラメーターの名前です。
  • 項目を使用するには、「@(ItemName)」と入力します。ここで、ItemNameItem 要素の名前です。

Note

同じ名前で複数の項目を作成する場合は、リストを作成します。 一方、同じ名前で複数のプロパティを作成すると、指定した最後のプロパティ値によって、同じ名前の以前のプロパティが上書きされます。プロパティには 1 つの値のみを含めることができます。

たとえば、サンプル ソリューションの Publish.proj ファイルで、BuildProjects ターゲットを確認します。

<Target Name="BuildProjects" Condition=" '$(BuildingInTeamBuild)'!='true' ">
   <MSBuild Projects="@(ProjectsToBuild)"           
            Properties="OutDir=$(OutputRoot);
                        Configuration=$(Configuration);
                        DeployOnBuild=true;
                        DeployTarget=Package"
            Targets="Build" />
</Target>

このサンプルでは、次の重要な点を確認できます。

  • BuildingInTeamBuild パラメーターが指定され、値が true の場合、このターゲット内のタスクは実行されません。

  • ターゲットには、MSBuild タスクの 1 つのインスタンスが含まれています。 このタスクを使用すると、他の MSBuild プロジェクトをビルドできます。

  • ProjectsToBuild 項目がタスクに渡されます。 この項目は、プロジェクトまたはソリューション ファイルの一覧を表します。すべて、項目グループ内の ProjectsToBuild 項目要素によって定義されます。 この場合、ProjectsToBuild 項目は 1 つのソリューション ファイルを参照します。

    <ItemGroup>
       <ProjectsToBuild Include="$(SourceRoot)ContactManager-WCF.sln"/>
    </ItemGroup>
    
  • MSBuild タスクに渡されるプロパティ値には、OutputRootConfiguration という名前のパラメーターが含まれます。 パラメーター値が指定されている場合はパラメーター値に設定され、指定されていない場合は静的プロパティ値に設定されます。

    <PropertyGroup>
       ... 
       <Configuration Condition=" '$(Configuration)'=='' ">Release
       </Configuration>
       <OutputRoot Condition=" '$(OutputRoot)'=='' ">..\Publish\Out\
       </OutputRoot>
       ...
    </PropertyGroup>
    

また、MSBuild タスクによって Build という名前のターゲットが呼び出されることがわかります。 これは、Visual Studio プロジェクト ファイルで広く使用され、BuildCleanRebuildPublish などのカスタム プロジェクト ファイルで使用できる、いくつかの組み込みターゲットの 1 つです。 ターゲットとタスクを使用してビルド プロセスを制御する方法と、特にこのトピックで後述する MSBuild タスクについて詳しく学習します。

Note

ターゲットの詳細については、「MSBuild ターゲット」を参照してください。

複数の環境をサポートするプロジェクト ファイルの分割

テスト サーバー、ステージング プラットフォーム、運用環境など、複数の環境にソリューションを展開できるようにするとします。 構成は、これらの環境によって (サーバー名、接続文字列などだけでなく、資格情報、セキュリティ設定、その他多くの要因の観点からも) 大きく異なる場合があります。 これを定期的に行う必要がある場合は、ターゲット環境を切り替えるたびにプロジェクト ファイル内の複数のプロパティを編集することは実際には効率的ではありません。 また、ビルド プロセスに対して、プロパティ値のリストをエンドレスに提供することを求めるのは理想的なソリューションではありません。

幸いなことに、代替手段があります。 MSBuild を使用すると、ビルド構成を複数のプロジェクト ファイルに分割できます。 このしくみを確認するには、サンプル ソリューションに次の 2 つのカスタム プロジェクト ファイルがあることに注意してください。

  • Publish.proj。すべての環境に共通のプロパティ、項目、およびターゲットが含まれています。
  • Env-Dev.proj。開発者環境に固有のプロパティが含まれています。

Publish.proj ファイルの、Project 開始タグのすぐ下に Import 要素が含まれているということに注目してください。

<Import Project="$(TargetEnvPropsFile)"/>

Import 要素は、別の MSBuild プロジェクト ファイルの内容を現在の MSBuild プロジェクト ファイルにインポートするために使用されます。 この場合、TargetEnvPropsFile パラメーターは、インポートするプロジェクト ファイルのファイル名を提供します。 MSBuild を実行するときに、このパラメーターの値を指定できます。

msbuild.exe Publish.proj /p:TargetEnvPropsFile=EnvConfig\Env-Dev.proj

これにより、2 つのファイルの内容が 1 つのプロジェクト ファイルに効果的にマージされます。 この方法を使用すると、ユニバーサル ビルド構成を含む 1 つのプロジェクト ファイルと、環境固有のプロパティを含む複数の補助プロジェクト ファイルを作成できます。 その結果、別のパラメーター値を指定してコマンドを実行するだけで、ソリューションを別の環境に展開できます。

Running a command with a different parameter value lets you deploy your solution to a different environment.

この方法でプロジェクト ファイルを分割することをお勧めします。 これにより、開発者は 1 つのコマンドを実行して複数の環境に展開でき、複数のプロジェクト ファイル間でのユニバーサル ビルド プロパティの重複を回避できます。

Note

独自のサーバー環境用に合わせた環境固有のプロジェクト ファイルをカスタマイズする方法のガイダンスについては、「ターゲット環境の展開プロパティを構成する」を参照してください。

まとめ

このトピックでは、MSBuild プロジェクト ファイルの一般的な概要と、独自のカスタム プロジェクト ファイルを作成してビルド プロセスを制御する方法について説明しました。 また、プロジェクト ファイルをユニバーサル ビルド命令と環境固有のビルド プロパティに分割して、プロジェクトを簡単にビルドして複数の宛先に配置できるようにするという概念についても紹介しました。

次のトピック「ビルド プロセスについて」では、現実的なレベルの複雑さでのソリューションの展開について説明することで、プロジェクト ファイルを使用してビルドと展開を制御する方法について詳しく説明します。

もっと読む

プロジェクト ファイルと WPP の詳細な概要については、『Microsoft Build Engine: Using MSBuild and Team Foundation Build』 (Sayed Ibrahim Hashimi and William Bartholomew, ISBN: 978-0-7356-4524-0) を参照してください。