共用方式為


比較屬性和項目

MSBuild 屬性和項目都可用於將資訊傳遞給工作、評估條件,以及儲存整個專案檔中所要參考的值。

  • 這些屬性為名稱/值組。 如需詳細資訊,請參閱 MSBuild 屬性

  • 項目 (Item) 通常是代表檔案的物件。 項目物件可以有相關聯的中繼資料集合。 中繼資料為名稱/值組。 如需詳細資訊,請參閱 MSBuild 項目

純量和向量

因為 MSBuild 屬性是只有一個字串值的名稱/值組,所以通常會描述成「純量」(Scalar)。 因為 MSBuild 項目類型是項目的清單,所以通常會描述成「向量」(Vector)。 但實際上,屬性可以代表多個值,而項目類型可以有零個或一個項目。

Dd997067.collapse_all(zh-tw,VS.110).gif目標相依性插入

若要了解屬性如何能代表多個值,請考慮通用使用模式,將目標加入至要建置的目標清單。 這份清單通常是以屬性值表示,並以分號分隔目標名稱。

<PropertyGroup>
    <BuildDependsOn>
        BeforeBuild;
        CoreBuild;
        AfterBuild
    </BuildDependsOn>
</PropertyGroup>

BuildDependsOn 屬性 (Property) 通常會做為目標 DependsOnTargets 屬性 (Attribute) 的引數,可有效地將它轉換為項目清單。 此屬性 (Property) 可予以覆寫,以加入目標或變更目標執行順序。 例如:

<PropertyGroup>
    <BuildDependsOn>
        $(BuildDependsOn);
        CustomBuild;
    </BuildDependsOn>
</PropertyGroup>

會將 CustomBuild 目標加入到目標清單,並將值 BeforeBuild;CoreBuild;AfterBuild;CustomBuild 提供給 BuildDependsOn。

從 MSBuild 4.0 開始,目標相依性插入已被取代。 請改用 AfterTargets 和 BeforeTargets 屬性。 如需詳細資訊,請參閱目標建置順序

Dd997067.collapse_all(zh-tw,VS.110).gif字串與項目清單之間的轉換

MSBuild 會視需要執行項目類型與字串之間的轉換。 若要了解項目清單如何能變成字串值,請考慮當項目類型做為 MSBuild 屬性值時會發生什麼情況:

<ItemGroup>
    <OutputDir Include="KeyFiles\;Certificates\" />
  </ItemGroup>
<PropertyGroup>
    <OutputDirList>@(OutputDir)</OutputDirList>
</PropertyGroup>

項目類型 OutputDir 具有值為 "KeyFiles\;Certificates\" 的 Include 屬性。 MSBuild 會將此字串剖析為兩個項目:KeyFiles\ 和 Certificates\。 當項目類型 OutputDir 做為 OutputDirList 屬性值時,MSBuild 會將項目類型轉換或「簡化」成以分號分隔的字串 "KeyFiles\;Certificates\"。

作業中的屬性和項目

屬性和項目會做為 MSBuild 工作的輸入和輸出。 如需詳細資訊,請參閱 MSBuild 工作

屬性 (Property) 會當做屬性 (Attribute) 傳遞至工作。 在工作內部,MSBuild 屬性是以其值可與字串互相轉換的屬性表示。 支援的屬性類型包含 boolcharDateTimeDecimalDoubleintstring,以及 ChangeType 可以處理的任何類型。

項目會當做 ITaskItem 物件傳遞至工作。 在工作內部,ItemSpec 代表項目的值,而 GetMetadata 會擷取其中繼資料。

項目類型的項目清單可以當做 ITaskItem 物件陣列傳遞。 從 .NET Framework 3.5 開始,您可以使用 Remove 屬性從目標的項目清單中移除項目。 因為可以從項目清單中移除項目,所以項目類型有可能沒有任何項目。 如果項目清單已傳遞至工作,則工作中的程式碼應檢查此種可能性。

屬性和項目評估順序

在建置的評估階段內,匯入的檔案會以其出現的順序合併到建置中。 屬性和項目會依照下列順序在三個行程中定義:

  • 屬性會依照其出現的順序進行定義及修改。

  • 項目定義會依照其出現的順序進行定義及修改。

  • 項目會依照其出現的順序進行定義及修改。

在建置的執行階段內,已定義於目標內的屬性和項目會以其出現的順序在單一階段中一起進行評估。

不過,情況並非完全如此。 定義屬性、項目定義或項目後,就會評估其值。 運算式評估工具會展開可指定此值的字串。 字串展開須視建置階段而定。 以下是更詳細的屬性和項目評估順序:

  • 在建置的評估階段內:

    • 屬性會依照其出現的順序進行定義及修改。 系統會執行屬性函式。 格式為 $(PropertyName) 的屬性值會在運算式內部展開。 屬性值會設為展開的運算式。

    • 項目定義會依照其出現的順序進行定義及修改。 屬性函式已經在運算式內部展開。 中繼資料值會設為展開的運算式。

    • 項目類型會依照其出現的順序進行定義及修改。 系統會展開格式為 @(ItemType) 的項目值, 也會展開項目轉換。 屬性函式和值已經在運算式內部展開。 項目清單和中繼資料值會設為展開的運算式。

  • 在建置的執行階段內:

    • 已定義於目標內的屬性和項目會以其出現的順序一起進行評估。 系統會在運算式內部執行屬性函式及展開屬性值。 此外,還會展開項目值和項目轉換。 屬性值、項目類型值和中繼資料值會設為展開的運算式。

Dd997067.collapse_all(zh-tw,VS.110).gif評估順序的細微影響

在建置的評估階段中,屬性評估必須在項目評估之前。 儘管如此,屬性的值似乎相依於項目值。 請考慮下列指令碼。

<ItemGroup>
    <KeyFile Include="KeyFile.cs">
        <Version>1.0.0.3</Version>
    </KeyFile>
</ItemGroup>
<PropertyGroup>
    <KeyFileVersion>@(KeyFile->'%(Version)')</KeyFileVersion>
</PropertyGroup>
<Target Name="AfterBuild">
    <Message Text="KeyFileVersion: $(KeyFileVersion)" />
</Target>

執行 Message 工作會顯示下列訊息:

KeyFileVersion: 1.0.0.3

這是因為 KeyFileVersion 的值實際上就是字串 "@(KeyFile->'%(Version)')"。 起初定義屬性時,並未展開項目和項目轉換,所以會將未展開字串的值指派給 KeyFileVersion 屬性。

在建置的執行階段內處理 Message 工作時,MSBuild 會展開字串 "@(KeyFile->'%(Version)')" 以產生 "1.0.0.3"。

請注意,即使屬性和項目群組的順序相反,仍會出現同樣的訊息。

在第二個範例中,請考慮當屬性和項目群組位於目標內部時會發生什麼情況:

<Target Name="AfterBuild">
    <PropertyGroup>
        <KeyFileVersion>@(KeyFile->'%(Version)')</KeyFileVersion>
    </PropertyGroup>
    <ItemGroup>
        <KeyFile Include="KeyFile.cs">
            <Version>1.0.0.3</Version>
        </KeyFile>
    </ItemGroup>
    <Message Text="KeyFileVersion: $(KeyFileVersion)" />
</Target>

Message 工作會顯示下列訊息:

KeyFileVersion: 

這是因為在建置的執行階段內,已定義於目標內的屬性和項目群組會同時由上至下進行評估。 定義 KeyFileVersion 時,KeyFile 不明。 因此,項目轉換會展開為空字串。

在此情況下,反轉屬性和項目群組的順序會還原原始訊息:

<Target Name="AfterBuild">
    <ItemGroup>
        <KeyFile Include="KeyFile.cs">
            <Version>1.0.0.3</Version>
        </KeyFile>
    </ItemGroup>
    <PropertyGroup>
        <KeyFileVersion>@(KeyFile->'%(Version)')</KeyFileVersion>
    </PropertyGroup>
    <Message Text="KeyFileVersion: $(KeyFileVersion)" />
</Target>

KeyFileVersion 的值會設為 "1.0.0.3" 而非 "@(KeyFile->'%(Version)')"。 Message 工作會顯示下列訊息:

KeyFileVersion: 1.0.0.3

請參閱

其他資源

MSBuild 進階概念