共用方式為


MSBuild 項目

MSBuild 專案是建置系統的輸入,而且通常代表檔案(檔案是在 屬性中 Include 指定)。 項目會根據其項目名稱分組為項目類型。 項目類型是可做為工作參數的專案命名清單。 工作會使用專案值來執行建置程式的步驟。

由於專案是由其所屬的項目類型來命名,因此可以交替使用「專案」和「專案值」等字詞。

在項目檔中建立專案

您可以將項目檔中的專案宣告為 ItemGroup 元素的子專案。 有效的專案名稱開頭為大寫或小寫字母或底線(_):有效的後續字元包括英數位元(字母或數位)、底線和連字元(-)。 子專案的名稱是專案的型別。 項目的 Include 屬性會指定要與該專案類型一起包含的專案(檔案)。 例如,下列 XML 會建立名為 Compile的項目類型,其中包含兩個檔案。

<ItemGroup>
    <Compile Include = "file1.cs"/>
    <Compile Include = "file2.cs"/>
</ItemGroup>

專案 file2.cs 不會取代專案 file1.cs;相反地,檔名會附加至項目類型的值 Compile 清單。

下列 XML 會在一個屬性中宣告這兩個 Include 檔案,以建立相同的項目類型。 請注意,檔名是以分號分隔。

<ItemGroup>
    <Compile Include = "file1.cs;file2.cs"/>
</ItemGroup>

屬性 Include 是相對於專案檔資料夾解譯的路徑, $(MSBuildProjectPath)即使項目位於如檔案的匯入檔案中也一 .targets 樣。

在執行期間建立專案

在組建的評估階段, 在 Target 元素外部的專案會指派值。 在後續執行階段期間,您可以透過下列方式建立或修改專案:

  • 任何工作都可以發出專案。 若要發出專案,Task 元素必須具有具有 屬性的ItemNameOutput 元素。

  • CreateItem 工作可以發出專案。 此使用方式已被取代。

  • Target 元素可能包含可能包含項目元素的 ItemGroup 元素。

參考項目檔中的專案

若要在整個項目檔中參考項目類型,請使用語法 @(ItemType)。 例如,您會使用 @(Compile)參考上一個範例中的項目類型。 藉由使用此語法,您可以將項目類型指定為該工作的參數,以將專案傳遞至工作。 如需詳細資訊,請參閱 如何:選取要建置的檔案

根據預設,專案類型的專案會以分號分隔(;)展開時。 您可以使用 語法 @(ItemType, 'separator') 來指定預設值以外的分隔符。 如需詳細資訊,請參閱 如何:顯示以逗號分隔的項目清單

使用通配符來指定專案

您可以使用 ***? 通配符,將檔案群組指定為組建的輸入,而不是個別列出每個檔案。

  • ?通配符符合單一字元。
  • *通配符符合零個或多個字元。
  • **通配符序列符合部分路徑。

例如,您可以使用項目檔中的下列元素,指定目錄中包含專案檔的所有 .cs 檔案。

<CSFile Include="*.cs"/>

下列元素會選取磁碟驅動器上D:的所有.vb檔案:

<VBFile Include="D:/**/*.vb"/>

如果您想要在沒有通配符展開的專案中包含常值 *? 字元,則必須 逸出通配符

如需通配符的詳細資訊,請參閱 如何:選取要建置的檔案

使用 Exclude 屬性

項目專案可以包含 Exclude 屬性,該屬性會從項目類型中排除特定專案(檔案)。 屬性 Exclude 通常與通配符搭配使用。 例如,下列 XML 會將目錄中的每個 .cs 檔案新增至 CSFile 項目類型,但 DoNotBuild.cs 檔案除外。

<ItemGroup>
    <CSFile  Include="*.cs"  Exclude="DoNotBuild.cs"/>
</ItemGroup>

屬性 Exclude 只會影響包含兩者之專案之專案元素中的 屬性所加入 Include 的專案。 下列範例不會排除在上述項目專案中新增的 檔案Form1.cs

<Compile Include="*.cs" />
<Compile Include="*.res" Exclude="Form1.cs">

如需詳細資訊,請參閱 如何:從組建中排除檔案

項目元數據

除了 和 Exclude 屬性中的Include資訊之外,專案也可以包含元數據。 此元數據可供需要專案的詳細資訊或批次工作和目標的工作使用。 如需詳細資訊,請參閱 Batching

元數據是項目檔中宣告為專案專案的子專案之索引鍵/值組集合。 子專案的名稱是元數據的名稱,而子專案的值則是元數據的值。

元數據與包含元數據的專案專案相關聯。 例如,下列 XML 會將具有 值的Fr元數據新增Culture專案類型的one.cstwo.cs專案CSFile

<ItemGroup>
    <CSFile Include="one.cs;two.cs">
        <Culture>Fr</Culture>
    </CSFile>
</ItemGroup>

專案可以有零個或多個元數據值。 您可以隨時變更元數據值。 如果您將元數據設定為空值,則會有效地從組建中移除它。

參考項目檔中的項目元數據

您可以使用 語法 %(ItemMetadataName),在整個項目檔中參考項目元數據。 如果存在模棱兩可,您可以使用專案類型的名稱來限定參考。 例如,您可以指定 %(ItemType.ItemMetaDataName)。 下列範例會 Display 使用元數據來批處理工作 Message 。 如需如何使用專案元數據進行批處理的詳細資訊,請參閱 工作批處理中的專案元數據

<Project>
    <ItemGroup>
        <Stuff Include="One.cs" >
            <Display>false</Display>
        </Stuff>
        <Stuff Include="Two.cs">
            <Display>true</Display>
        </Stuff>
    </ItemGroup>
    <Target Name="Batching">
        <Message Text="@(Stuff)" Condition=" '%(Display)' == 'true' "/>
    </Target>
</Project>

已知的項目元數據

當專案新增至項目類型時,該專案會指派一些已知的元數據。 例如,所有專案都有已知的元數據 %(Filename),其值為項目的檔名(不含擴展名)。 如需詳細資訊,請參閱 已知的項目元數據

使用元數據轉換項目類型

您可以使用元資料,將專案清單轉換成新的專案清單。 例如,您可以使用 表示式 @(CppFiles -> '%(Filename).obj'),將具有代表.cpp檔案的專案的項目轉換成對應的檔案清單.obj的項目類型CppFiles

下列程式代碼會CultureResource建立項目類型,其中包含具有Culture元數據的所有EmbeddedResource項目複本。 元數據 Culture 值會變成新元數據 CultureResource.TargetDirectory的值。

<Target Name="ProcessCultureResources">
    <ItemGroup>
        <CultureResource Include="@(EmbeddedResource)"
            Condition="'%(EmbeddedResource.Culture)' != ''">
            <TargetDirectory>%(EmbeddedResource.Culture) </TargetDirectory>
        </CultureResource>
    </ItemGroup>
</Target>

如需專案的詳細資訊,請參閱 MSBuild 專案函式轉換

項目定義

您可以使用 ItemDefinitionGroup 元素,將預設元數據新增至任何項目類型。 如同已知的元數據,預設元數據會與您指定之專案類型的所有專案相關聯。 您可以在項目定義中明確覆寫預設元數據。 例如,下列 XML 會 Compile 提供專案 one.cs ,並以 「Monday」 值 three.cs 元數據 BuildDay 。 此程式代碼會提供專案 two.cs 具有值 「Tuesday」 的元數據 BuildDay

<ItemDefinitionGroup>
    <Compile>
        <BuildDay>Monday</BuildDay>
    </Compile>
</ItemDefinitionGroup>
<ItemGroup>
    <Compile Include="one.cs;three.cs" />
    <Compile Include="two.cs">
        <BuildDay>Tuesday</BuildDay>
    </Compile>
</ItemGroup>

如需詳細資訊,請參閱 項目定義

目標 ItemGroup 中項目的屬性

Target 元素可能包含可能包含項目元素的 ItemGroup 元素。 當針對 中的 ItemGroup 專案指定屬性時, Target本節中的屬性是有效的。

拿掉屬性

屬性 Remove 會從專案類型中移除特定專案(檔案)。 此屬性是在 .NET Framework 3.5 中引進的(僅限目標內部)。 從 MSBuild 15.0 開始,支持內外目標。

下列範例會從Compile項目類型中移除每個.config檔案。

<Target>
    <ItemGroup>
        <Compile Remove="*.config"/>
    </ItemGroup>
</Target>

MatchOnMetadata 屬性

屬性 MatchOnMetadata 只適用於 Remove 參考其他項目的屬性(例如 Remove="@(Compile);@(Content)"),並指示 Remove 作業根據指定元數據名稱的值比對專案,而不是根據專案值比對。

比對B Remove="@(A)" MatchOnMetadata="M"規則:從中移除具有元數據M的所有專案B,其元數據值MV會比對值 元數據MV的任何A專案。

<Project>
  <ItemGroup>
    <A Include='a1' M1='1' M2='a' M3="e"/>
    <A Include='b1' M1='2' M2='x' M3="f"/>
    <A Include='c1' M1='3' M2='y' M3="g"/>
    <A Include='d1' M1='4' M2='b' M3="h"/>

    <B Include='a2' M1='x' m2='c' M3="m"/>
    <B Include='b2' M1='2' m2='x' M3="n"/>
    <B Include='c2' M1='2' m2='x' M3="o"/>
    <B Include='d2' M1='3' m2='y' M3="p"/>
    <B Include='e2' M1='3' m2='Y' M3="p"/>
    <B Include='f2' M1='4'        M3="r"/>
    <B Include='g2'               M3="s"/>

    <B Remove='@(A)' MatchOnMetadata='M1;M2'/>
  </ItemGroup>

  <Target Name="PrintEvaluation">
    <Message Text="%(B.Identity) M1='%(B.M1)' M2='%(B.M2)' M3='%(B.M3)'" />
  </Target>
</Project>

在這裡範例中,專案值 b2c2d2 會從項目 B 中移除,因為:

  • b2c2 from B match 對 b1 on AM1=2M2=x
  • d2 from B matches from from c1A on M1=3 and M2=y

工作 Message 會輸出下列內容:

  a2 M1='x' M2='c' M3='m'
  e2 M1='3' M2='Y' M3='p'
  f2 M1='4' M2='' M3='r'
  g2 M1='' M2='' M3='s'

MSBuild 的MatchOnMetadata範例用法:

      <_TransitiveItemsToCopyToOutputDirectory Remove="@(_ThisProjectItemsToCopyToOutputDirectory)" MatchOnMetadata="TargetPath" MatchOnMetadataOptions="PathLike" />

這一行會從 _TransitiveItemsToCopyToOutputDirectory 中移除具有相同 TargetPath 元數據值的專案 _ThisProjectItemsToCopyToOutputDirectory

MatchOnMetadataOptions 屬性

指定用來 MatchOnMetadata 比對項目之間元數據值的字串比對策略(元數據名稱一律不區分大小寫)。 可能的值為 CaseSensitiveCaseInsensitivePathLike。 預設值是 CaseSensitive

PathLike 將路徑感知正規化套用至正規化斜線方向、忽略尾端斜線、消除 ...等值,並將所有相對路徑設為絕對相對於目前目錄。

KeepMetadata 屬性

如果專案是在目標內產生,則專案專案可以包含 KeepMetadata 屬性。 如果指定這個屬性,只有以分號分隔的名稱清單中指定的元數據,才會從來源專案傳送至目標專案。 這個屬性的空白值相當於不指定它。 屬性 KeepMetadata 是在 .NET Framework 4.5 中引進的。

下列範例說明如何使用 KeepMetadata 屬性。

<Project>
    <ItemGroup>
        <FirstItem Include="rhinoceros">
            <Class>mammal</Class>
            <Size>large</Size>
        </FirstItem>

    </ItemGroup>
    <Target Name="MyTarget">
        <ItemGroup>
            <SecondItem Include="@(FirstItem)" KeepMetadata="Class" />
        </ItemGroup>

        <Message Text="FirstItem: %(FirstItem.Identity)" />
        <Message Text="  Class: %(FirstItem.Class)" />
        <Message Text="  Size:  %(FirstItem.Size)"  />

        <Message Text="SecondItem: %(SecondItem.Identity)" />
        <Message Text="  Class: %(SecondItem.Class)" />
        <Message Text="  Size:  %(SecondItem.Size)"  />
    </Target>
</Project>

<!--
Output:
  FirstItem: rhinoceros
    Class: mammal
    Size:  large
  SecondItem: rhinoceros
    Class: mammal
    Size:
-->

RemoveMetadata 屬性

如果專案是在目標內產生,則專案專案可以包含 RemoveMetadata 屬性。 如果指定這個屬性,則所有元數據都會從來源專案傳輸到目標專案,但名稱包含在以分號分隔的名稱清單中以外的元數據除外。 這個屬性的空白值相當於不指定它。 屬性 RemoveMetadata 是在 .NET Framework 4.5 中引進的。

下列範例說明如何使用 RemoveMetadata 屬性。

<Project>

    <PropertyGroup>
        <MetadataToRemove>Size;Material</MetadataToRemove>
    </PropertyGroup>

    <ItemGroup>
        <Item1 Include="stapler">
            <Size>medium</Size>
            <Color>black</Color>
            <Material>plastic</Material>
        </Item1>
    </ItemGroup>

    <Target Name="MyTarget">
        <ItemGroup>
            <Item2 Include="@(Item1)" RemoveMetadata="$(MetadataToRemove)" />
        </ItemGroup>

        <Message Text="Item1: %(Item1.Identity)" />
        <Message Text="  Size:     %(Item1.Size)" />
        <Message Text="  Color:    %(Item1.Color)" />
        <Message Text="  Material: %(Item1.Material)" />
        <Message Text="Item2: %(Item2.Identity)" />
        <Message Text="  Size:     %(Item2.Size)" />
        <Message Text="  Color:    %(Item2.Color)" />
        <Message Text="  Material: %(Item2.Material)" />
    </Target>
</Project>

<!--
Output:
  Item1: stapler
    Size:     medium
    Color:    black
    Material: plastic
  Item2: stapler
    Size:
    Color:    black
    Material:
-->

如需專案的詳細資訊,請參閱 MSBuild 專案函式

KeepDuplicates 屬性

如果專案是在目標內產生,則專案專案可以包含 KeepDuplicates 屬性。 KeepDuplicates 是屬性 Boolean ,指定如果專案與現有專案完全重複,是否應該將專案加入目標群組。

如果來源和目標專案具有相同 Include 的值,但不同的元數據,即使 KeepDuplicates 設定為 false,也會加入專案。 這個屬性的空白值相當於不指定它。 屬性 KeepDuplicates 是在 .NET Framework 4.5 中引進的。

下列範例說明如何使用 KeepDuplicates 屬性。

<Project>

    <ItemGroup>
        <Item1 Include="hourglass;boomerang" />
        <Item2 Include="hourglass;boomerang" />
    </ItemGroup>

    <Target Name="MyTarget">
        <ItemGroup>
            <Item1 Include="hourglass" KeepDuplicates="false" />
            <Item2 Include="hourglass" />
        </ItemGroup>

        <Message Text="Item1: @(Item1)" />
        <Message Text="  %(Item1.Identity)  Count: @(Item1->Count())" />
        <Message Text="Item2: @(Item2)" />
        <Message Text="  %(Item2.Identity)  Count: @(Item2->Count())" />
    </Target>
</Project>

<!--
Output:
  Item1: hourglass;boomerang
    hourglass  Count: 1
    boomerang  Count: 1
  Item2: hourglass;boomerang;hourglass
    hourglass  Count: 2
    boomerang  Count: 1
-->

KeepDuplicates因為 屬性除了專案值之外,也會考慮專案的元數據,因此請務必知道元數據發生的情況。 例如,請參閱 使用元數據專案函式時偵測重複專案

更新 Target 外部 ItemGroup 中專案的元數據

目標以外的專案可以透過 Update 屬性更新其現有的元數據。 這個屬性 不適用於 目標下的專案。

<Project>
    <PropertyGroup>
        <MetadataToUpdate>pencil</MetadataToUpdate>
    </PropertyGroup>

    <ItemGroup>
        <Item1 Include="stapler">
            <Size>medium</Size>
            <Color>black</Color>
            <Material>plastic</Material>
        </Item1>
        <Item1 Include="pencil">
            <Size>small</Size>
            <Color>yellow</Color>
            <Material>wood</Material>
        </Item1>
        <Item1 Include="eraser">
            <Color>red</Color>
        </Item1>
        <Item1 Include="notebook">
            <Size>large</Size>
            <Color>white</Color>
            <Material>paper</Material>
        </Item1>

        <Item2 Include="notebook">
            <Size>SMALL</Size>
            <Color>YELLOW</Color>
        </Item2>

        <!-- Metadata can be expressed either as attributes or as elements -->
        <Item1 Update="$(MetadataToUpdate);stapler;er*r;@(Item2)" Price="10" Material="">
            <Color>RED</Color>
        </Item1>
    </ItemGroup>

    <Target Name="MyTarget">
        <Message Text="Item1: %(Item1.Identity)
    Size: %(Item1.Size)
    Color: %(Item1.Color)
    Material: %(Item1.Material)
    Price: %(Item1.Price)" />
    </Target>
</Project>

<!--  
Item1: stapler
    Size: medium
    Color: RED
    Material:
    Price: 10
Item1: pencil
    Size: small
    Color: RED
    Material:
    Price: 10
Item1: eraser
    Size:
    Color: RED
    Material:
    Price: 10
Item1: notebook
    Size: large
    Color: RED
    Material:
    Price: 10
-->

在 MSBuild 16.6 版和更新版本中, Update 屬性支援合格的元數據參考,以利從兩個或多個專案匯入元數據。

<Project>
    <ItemGroup>
        <Item1 Include="stapler">
            <Size>medium</Size>
            <Color>black</Color>
            <Material>plastic</Material>
        </Item1>
        <Item1 Include="pencil">
            <Size>small</Size>
            <Color>yellow</Color>
            <Material>wood</Material>
        </Item1>
        <Item1 Include="eraser">
            <Size>small</Size>
            <Color>red</Color>
            <Material>gum</Material>
        </Item1>
        <Item1 Include="notebook">
            <Size>large</Size>
            <Color>white</Color>
            <Material>paper</Material>
        </Item1>

        <Item2 Include="pencil">
            <Size>MEDIUM</Size>
            <Color>RED</Color>
            <Material>PLASTIC</Material>
            <Price>10</Price>
        </Item2>

        <Item3 Include="notebook">
            <Size>SMALL</Size>
            <Color>BLUE</Color>
            <Price>20</Price>
        </Item3>

        <!-- Metadata can be expressed either as attributes or as elements -->
        <Item1 Update="@(Item2);er*r;@(Item3)" Size="%(Size)" Color="%(Item2.Color)" Price="%(Item3.Price)" Model="2020">
            <Material Condition="'%(Item2.Material)' != ''">Premium %(Item2.Material)</Material>
        </Item1>
    </ItemGroup>

    <Target Name="MyTarget">
        <Message Text="Item1: %(Item1.Identity)
    Size: %(Item1.Size)
    Color: %(Item1.Color)
    Material: %(Item1.Material)
    Price: %(Item1.Price)
    Model: %(Item1.Model)" />
    </Target>
</Project>

<!--  
Item1: stapler
    Size: medium
    Color: black
    Material: plastic
    Price:
    Model:
Item1: pencil
    Size: small
    Color: RED
    Material: Premium PLASTIC
    Price:
    Model: 2020
Item1: eraser
    Size: small
    Color:
    Material: gum
    Price:
    Model: 2020
Item1: notebook
    Size: large
    Color:
    Material: paper
    Price: 20
    Model: 2020
-->

備註:

  • 未限定的元數據 (%(MetadataName)) 會系結至正在更新的項目類型(Item1 在上述範例中)。 限定元數據 (%(Item2.Color)) 會系結在 Update 運算式中擷取的相符項目類型集合內。
  • 如果專案在多個參考專案內和之間符合多次:
    • 會擷取每個參考專案類型的最後一個出現專案(因此每個專案類型都會擷取一個專案)。
    • 這符合目標下的工作專案批處理行為。
  • 其中可以放置 %() 參考:
    • 後設資料
    • 元數據條件
  • 元數據名稱比對不區分大小寫。

更新目標 ItemGroup 中專案的元數據

元數據也可以透過比 以下 Update的表達性語法修改目標內:

<Project>
    <ItemGroup>
        <Item1 Include="stapler">
            <Size>medium</Size>
            <Color>black</Color>
            <Material>plastic</Material>
        </Item1>
        <Item1 Include="pencil">
            <Size>small</Size>
            <Color>yellow</Color>
            <Material>wood</Material>
        </Item1>
        <Item1 Include="eraser">
            <Size>small</Size>
            <Color>red</Color>
            <Material>gum</Material>
        </Item1>
        <Item1 Include="notebook">
            <Size>large</Size>
            <Color>white</Color>
            <Material>paper</Material>
        </Item1>

        <Item2 Include="pencil">
            <Size>MEDIUM</Size>
            <Color>RED</Color>
            <Material>PLASTIC</Material>
            <Price>10</Price>
        </Item2>

        <Item2 Include="ruler">
            <Color>GREEN</Color>
        </Item2>

    </ItemGroup>

    <Target Name="MyTarget">
        <ItemGroup>
            <!-- Metadata can be expressed either as attributes or as elements -->
            <Item1 Size="GIGANTIC" Color="%(Item2.Color)">
                <Material Condition="'%(Item2.Material)' != ''">Premium %(Item2.Material)</Material>
            </Item1>
        </ItemGroup>

        <Message Text="Item1: %(Item1.Identity)
    Size: %(Item1.Size)
    Color: %(Item1.Color)
    Material: %(Item1.Material)
    Price: %(Item1.Price)
    Model: %(Item1.Model)" />
    </Target>
</Project>

<!--  
Item1: stapler
    Size: GIGANTIC
    Color: GREEN
    Material: Premium PLASTIC
    Price:
    Model:
Item1: pencil
    Size: GIGANTIC
    Color: GREEN
    Material: Premium PLASTIC
    Price:
    Model:
Item1: eraser
    Size: GIGANTIC
    Color: GREEN
    Material: Premium PLASTIC
    Price:
    Model:
Item1: notebook
    Size: GIGANTIC
    Color: GREEN
    Material: Premium PLASTIC
    Price:
    Model:
-->