MSBuild 屬性

屬性是名稱/值組,可以用來設定組建。 屬性可用於將值傳遞給工作、評估條件,以及儲存將在整個專案檔中參考的值。

定義和參考專案檔中的屬性

宣告屬性的方式是建立具有屬性名稱的項目,做為 PropertyGroup 項目的子項目。 例如,下列 XML 會建立名為 BuildDir 並具有 Build 值的屬性。

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

有效的屬性名稱以大寫或小寫字母或底線 (_) 開頭;有效的後續字元包括英數字元 (字母或數字)、底線和連字號 (-)。

在整個專案檔中,可使用語法 $(<PropertyName>) 來參考屬性。 例如,使用 $(BuildDir) 來參考上述範例中的屬性。

您可以藉由重新定義屬性來變更屬性值。 您可以使用下列 XML,為 BuildDir 屬性指定新值:

<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 (dotnet build) 的 .NET SDK 版本中,不支援登錄屬性。

在執行期間建立屬性

位於 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 屬性來指定區域屬性。

下列程式碼指定兩個屬性是區域屬性:

<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 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>