MSBuild プロパティ

プロパティはビルドを設定するための名前と値のペアです。 プロパティを使用することで、タスクに値を渡したり、条件を評価したりできるだけでなく、プロジェクト ファイルで参照する値を格納しておくこともできます。

プロジェクト ファイルでプロパティを定義して参照する

プロパティを宣言するには、そのプロパティの名前を持つ要素を PropertyGroup 要素の子として作成します。 たとえば、次の XML では、BuildDir という名前のプロパティを作成し、Build を値として設定しています。

<PropertyGroup>
    <BuildDir>Build</BuildDir>
</PropertyGroup>

有効なプロパティ名は、大文字か小文字またはアンダースコア (_) で始まり、続く文字は英数字 (文字または数字)、アンダースコア、ハイフン (-) となります。

プロジェクト ファイルでプロパティを参照するには、$(<PropertyName>) という構文を使用します。 たとえば、前の例に示したプロパティを参照するには、$(BuildDir) と記述します。

プロパティ値を変更するには、プロパティを再定義します。 BuildDir プロパティに新しい値を設定するには、次の XML を使用します。

<PropertyGroup>
    <BuildDir>Alternate</BuildDir>
</PropertyGroup>

プロパティは、プロジェクト ファイルに表示される順に評価されます。 BuildDir の新しい値は、古い値が割り当てられた後で宣言する必要があります。

予約済みのプロパティ

MSBuild では、プロジェクト ファイルに関する情報や MSBuild のバイナリに関する情報を保持するために、いくつかのプロパティ名が予約されています。 これらのプロパティは、他のプロパティと同じように $ 表記を使用して参照できます。 たとえば、$(MSBuildProjectFile) は、ファイル名の拡張子を含むプロジェクト ファイルの完全なファイル名を返します。

詳細については、「方法: プロジェクト ファイルの名前または場所を参照する」および「MSBuild の予約済みおよび既知のプロパティ」をご覧ください。

MSBuild 内部プロパティ

アンダースコア (_) で始まる標準インポート ファイルで定義されているプロパティは MSBuild に対してプライベートであり、ユーザー コードで読み取り、リセット、またはオーバーライドしないでください。

環境プロパティ

プロジェクト ファイルで環境変数を参照する場合も、予約済みのプロパティを参照するときと同じ方法を使用します。 たとえば、プロジェクト ファイルで PATH 環境変数を使用するには、$(Path) と記述します。 プロジェクト ファイルに、環境プロパティと同じ名前のプロパティが定義されている場合、環境変数の値はプロジェクト内のプロパティによってオーバーライドされます。

各 MSBuild プロジェクトには、分離された環境ブロックがあります。各プロジェクトは独自のブロックに対する読み取りと書き込みのみを参照します。 プロジェクト ファイルの評価やビルドを行う前、MSBuild では、プロパティ コレクションが初期化されるときに環境変数のみを読み取ります。 その後で、環境プロパティは静的なプロパティになります。つまり、起動されたツールは、同じ名前と値で実行が開始されます。

起動されたツール内から環境変数の現在の値を取得するには、プロパティ関数 System.Environment.GetEnvironmentVariable を使用します。 ただし推奨される方法は、タスク パラメーター EnvironmentVariables を使用する方法です。 この文字列配列に設定されている環境プロパティは、起動されたツールに渡すことができます。このとき、システム環境変数は影響を受けません。

ヒント

すべての環境変数が読み取られて、初期プロパティになるわけではありません。 有効な MSBuild プロパティ名 ("386" など) を名前として持っていない環境変数は無視されます。

環境変数の使用方法の詳細については、「方法: ビルドで環境変数を使用する」をご覧ください。

レジストリのプロパティ

システム レジストリ値を読み取るには、次の構文を使用します。ここで、Hive はレジストリ ハイブ (たとえば、HKEY_LOCAL_MACHINE)、MyKey はキー名、MySubKey はサブキー名、Value はサブキーの値をそれぞれ表します。

$(registry:Hive\MyKey\MySubKey@Value)

既定のサブキー値を取得するには、Value を省略します。

$(registry:Hive\MyKey\MySubKey)

このレジストリ値を使用して、ビルド プロパティを初期化できます。 たとえば、Visual Studio の Web ブラウザーのホーム ページを表すビルド プロパティを作成するには、次のコードを使用します。

<PropertyGroup>
  <VisualStudioWebBrowserHomePage>
    $(registry:HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\14.0\WebBrowser@HomePage)
  </VisualStudioWebBrowserHomePage>
<PropertyGroup>

警告

MSBuild の .NET SDK バージョン (dotnet build) では、レジストリ プロパティはサポートされていません。

実行時にプロパティを作成する

Target 要素の外側にあるプロパティには、ビルドの評価フェーズで値が割り当てられます。 その後の実行フェーズでプロパティを作成または変更するには、次のようにします。

  • プロパティはどのタスクでも生成できます。 プロパティを生成するには、Task 要素の子要素として、PropertyName 属性を持つ Output 要素を持つ必要があります。

  • プロパティは CreateProperty タスクによって生成できます。 この使用法は非推奨とされます。

  • プロパティ宣言を格納できる Target 要素を PropertyGroup 要素に含めることができます。

グローバル プロパティ

MSBuild では、-property (または -p) スイッチを使用してコマンド ラインからプロパティを設定できます。 これらのグローバル プロパティ値は、プロジェクト ファイルで設定されたプロパティ値をオーバーライドします。 これには環境プロパティは含まれますが、予約済みのプロパティは含まれません。予約済みのプロパティは変更できません。

グローバルな Configuration プロパティを DEBUG に設定する例を次に示します。

msbuild.exe MyProj.proj -p:Configuration=DEBUG

グローバル プロパティは、MSBuild タスクの Properties 属性を使用することで、複数プロジェクトのビルドに含まれる子プロジェクトに対して設定または変更することもできます。 グローバル プロパティは、MSBuild タスクの RemoveProperties 属性が転送しないプロパティの一覧を指定するために使用されていなければ、子プロジェクトにも転送されます。 詳細については、「MSBuild タスク」を参照してください。

ローカル プロパティ

ローカル プロパティは、プロジェクト内でリセットできます。 グローバル プロパティはできません。 ローカル プロパティをコマンド ラインで -p オプションを指定して設定すると、プロジェクト ファイルでの設定がコマンド ラインより優先されます。

ローカル プロパティは、プロジェクト タグの TreatAsLocalProperty 属性を使って指定します。

次のコードでは、2 つのプロパティがローカルであることを指定しています。

<Project Sdk="Microsoft.Net.Sdk" TreatAsLocalProperty="Prop1;Prop2">

複数プロジェクトのビルドでは、ローカル プロパティは子プロジェクトに転送されません。 コマンド ラインで -p オプションを使って値を指定した場合、子プロジェクトには、親プロジェクトで変更されたローカル値ではなくグローバル プロパティの値が渡されますが、子プロジェクト (またはそのいずれかのインポート) で独自の TreatAsLocalProperty を使ってそれを変更することもできます。

ローカル プロパティを使用した例

次のコード例では、TreatAsLocalProperty の影響を示します。

<!-- test1.proj -->
<Project TreatAsLocalProperty="TreatedAsLocalProp">
    <PropertyGroup>
        <TreatedAsLocalProp>LocalOverrideValue</TreatedAsLocalProp>
    </PropertyGroup>

    <Target Name="Go">
        <MSBuild Projects="$(MSBuildThisFileDirectory)\test2.proj" Targets="Go2" Properties="Inner=true" />
    </Target>

    <Target Name="Go2" BeforeTargets="Go">
        <Warning Text="TreatedAsLocalProp($(MSBuildThisFileName)): $(TreatedAsLocalProp)" />
    </Target>
</Project>
<!-- test2.proj -->
<Project TreatAsLocalProperty="TreatedAsLocalProp">
    <Target Name="Go2">
        <Warning Text="TreatedAsLocalProp($(MSBuildThisFileName)): $(TreatedAsLocalProp)" />
    </Target>
</Project>

test1.proj コマンド ラインをビルドし、TreatedAsLocalProperty にグローバル値 GlobalOverrideValue を指定するとします。

dotnet msbuild .\test1.proj -p:TreatedAsLocalProp=GlobalOverrideValue

出力は次のようになります。

test1.proj(11,9): warning : TreatedAsLocalProp(test): LocalOverrideValue
test2.proj(3,9): warning : TreatedAsLocalProp(test2): GlobalOverrideValue

子プロジェクトはグローバル値を継承しますが、親プロジェクトではローカルに設定されたプロパティが使われます。

ローカル プロパティとインポート

インポートされるプロジェクトで TreatAsLocalProperty 属性を使う場合、プロパティが取得する値を考えるときは、順序が重要になります。

次のコード例では、インポートされるプロジェクトでの TreatAsLocalProperty の影響を示します。

<!-- importer.proj -->
<Project>
    <PropertyGroup>
        <TreatedAsLocalProp>FirstOverrideValue</TreatedAsLocalProp>
    </PropertyGroup>

    <Import Project="import.props" />

    <PropertyGroup>
        <TreatedAsLocalProp Condition=" '$(TrySecondOverride)' == 'true' ">SecondOverrideValue</TreatedAsLocalProp>
    </PropertyGroup>

    <Target Name="Go">
        <Warning Text="TreatedAsLocalProp($(MSBuildThisFileName)): $(TreatedAsLocalProp)" />
    </Target>
</Project>
<!-- import.proj -->
<Project TreatAsLocalProperty="TreatedAsLocalProp">
    <PropertyGroup>
        <TreatedAsLocalProp>ImportOverrideValue</TreatedAsLocalProp>
    </PropertyGroup>

    <!-- Here, TreatedAsLocalProp has the value "ImportOverrideValue"-->
</Project>

importer.proj をビルドし、次のように TreatedAsLocalProp にグローバル値を設定するとします。

dotnet msbuild .\importer.proj -p:TreatedAsLocalProp=GlobalOverrideValue

出力は次のようになります。

importer.proj(9,9): warning : TreatedAsLocalProp(importer.proj): GlobalOverrideValue

次に、TrySecondOverride から true するプロパティを使用してビルドするとします:

dotnet msbuild .\importer.proj -p:TreatedAsLocalProp=GlobalOverrideValue -p:TrySecondOverride=true

出力は次のようになります。

importer.proj(13,9): warning : TreatedAsLocalProp(importer.proj): SecondOverrideValue

この例は、プロパティが、インポートされたファイル内だけでなく、TreatAsLocalProperty 属性が使われているインポートされたプロジェクトの "後" で、ローカルとして扱われることを示しています。 プロパティの値はグローバル オーバーライドの値によって影響を受けますが、TreatAsLocalProperty が使われているインポートされたプロジェクトの "前" だけです。

詳細については、「Project 要素 (MSBuild)」および「方法: 同じソース ファイルを異なるオプションでビルドする」をご覧ください。

プロパティ関数

.NET Framework Version 4 以降では、プロパティ関数を使用して MSBuild スクリプトを評価できるようになりました。 MSBuild タスクを使用しなくても、システム時刻の読み取り、文字列の比較、正規表現の照合、その他のさまざまな処理をビルド スクリプト内で実行できます。

文字列 (インスタンス) メソッドを使用してプロパティ値を操作したり、各種システム クラスの静的メソッドを呼び出したりできます。 たとえば、ビルド プロパティを今日の日付に設定するには、次のようにします。

<Today>$([System.DateTime]::Now.ToString("yyyy.MM.dd"))</Today>

プロパティ関数の詳細と、プロパティ関数の一覧については、「プロパティ関数」を参照してください。

プロパティに XML を格納する

プロパティには、タスクに値を渡したり、ログ情報を表示したりするための任意の XML を格納できます。 次の例では、ConfigTemplate プロパティの値に、XML や他のプロパティ参照が使用されています。 このプロパティ参照は、MSBuild により、対応するプロパティ値を使用して置き換えられます。 プロパティ値は表示される順に割り当てられます。 したがって、この例では、$(MySupportedVersion)$(MyRequiredVersion)、および $(MySafeMode) は既に定義されています。

<PropertyGroup>
    <ConfigTemplate>
        <Configuration>
            <Startup>
                <SupportedRuntime
                    ImageVersion="$(MySupportedVersion)"
                    Version="$(MySupportedVersion)"/>
                <RequiredRuntime
                    ImageVersion="$(MyRequiredVersion)"
                    Version="$(MyRequiredVersion)"
                    SafeMode="$(MySafeMode)"/>
            </Startup>
        </Configuration>
    </ConfigTemplate>
</PropertyGroup>