Item Management

dotnet/skills/plugins/dotnet-msbuild/skills/item-management

作者 dotnet0608d8924cd3MIT5.5K 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫今天更新

Own concrete MSBuild ItemGroup and item-expression questions. USE FOR: Include, Remove, Update, item identity and metadata, transforms, filtering, batching, duplicate or overlapping items, and reviews that verify whether those operations are correct. Generated items stay in scope when the central defect is item identity, metadata, batching, duplicate declarations, or glob/Remove/Update semantics. For a generated artifact missing from compilation or output, wrong target timing/path, or FileWrites clean tracking without a broader item-semantics defect, use including-generated-files. The item operation may be broken, suspected, or already correct. Exclude property-only issues, general incrementality with no item question, broad reviews with no concrete item concern, and non-MSBuild systems.

AI 產生的概覽

說明 MSBuild ItemGroup 的 Include、Remove、Update、中繼資料、轉換、批次處理與重複項目處理。

功能
此技能提供源自 Microsoft.Common.CurrentVersion.targets 的 MSBuild 項目管理標準模式。它說明 Include、Remove、Update 三種操作、項目識別與中繼資料、轉換、Exclude 模式、條件式包含,以及使用 %(Metadata) 的批次處理。它也列出常見陷阱,例如交叉乘積批次處理、在原始碼樹中產生檔案,以及遺漏 FileWrites 項目。
適用情境
適用於具體的 MSBuild ItemGroup 或項目運算式問題,包括檢核項目操作是否正確的審查。適合涉及項目識別、中繼資料、批次處理、重複或重疊項目,以及 glob、Remove 或 Update 語意的問題。不適用於僅涉及屬性的問題、沒有項目問題的一般增量建置,或非 MSBuild 系統。
執行需求
不需要指令碼或工具,僅為說明性參考。代理不需要套件、認證或網路存取。

MSBuild Item Management Patterns

Canonical patterns for working with item groups, from Microsoft.Common.CurrentVersion.targets.

Include / Remove / Update — Three Operations

OperationPurposeWhen to use
IncludeAdd new items to the groupCreating items with identity + metadata
RemoveRemove items matching a patternExcluding files or clearing a group
UpdateModify metadata on existing itemsAdding/changing metadata without re-adding

Include — Add Items

xml
<ItemGroup>  <Compile Include="Generated\*.cs">    <AutoGen>true</AutoGen>  </Compile></ItemGroup>

Remove — Subtract Items

xml
<ItemGroup>  <!-- Remove specific items -->  <Reference Remove="$(AdditionalExplicitAssemblyReferences)" />
  <!-- Set subtraction: prior minus current -->  <_CleanOrphanFileWrites Include="@(_CleanPriorFileWrites)"      Exclude="@(_CleanCurrentFileWrites)" />
  <!-- Clear an entire group -->  <_Temporary Remove="@(_Temporary)" /></ItemGroup>

Update — Modify Existing Items

xml
<ItemGroup>  <EmbeddedResource Update="@(EmbeddedResource)"      Condition="'%(NuGetPackageId)' == 'Microsoft.CodeAnalysis.Collections'">    <GenerateSource>true</GenerateSource>    <ClassName>Microsoft.CodeAnalysis.Collections.SR</ClassName>  </EmbeddedResource></ItemGroup>

Update does not add items — it only modifies items already in the group.

Item Batching — %(Metadata)

When %(Metadata) appears in target attributes or task parameters, MSBuild batches execution per unique metadata value.

Target-level batching (Outputs)

xml
<Target Name="GenerateSatelliteAssemblies"    Inputs="$(MSBuildAllProjects);@(_SatelliteAssemblyResourceInputs)"    Outputs="$(IntermediateOutputPath)%(Culture)\$(TargetName).resources.dll">  <!-- Runs once per unique Culture value --></Target>

Task-level batching

xml
<Copy SourceFiles="@(_SourceItems)"    DestinationFiles="@(_SourceItems->'$(OutDir)%(TargetPath)')"></Copy>

Per-item filtering with Condition

xml
<ItemGroup>  <_ResxOutput Include="@(EmbeddedResource->'%(OutputResource)')"      Condition="'%(EmbeddedResource.WithCulture)' == 'false'" /></ItemGroup>

Batching rules

  • %(Metadata) in Condition or Outputs → target batches per unique value.
  • %(Metadata) in task parameters → task batches per unique value.
  • Do not mix %() from different item groups in the same expression — this causes a cross-product (see Common Pitfalls).

Item Transforms — @(Item->'expression')

Transforms create new item lists by applying an expression to each item:

xml
<!-- Transform file paths to destinations --><Copy SourceFiles="@(IntermediateAssembly)"    DestinationFiles="@(IntermediateAssembly->'$(OutDir)%(Filename)%(Extension)')"/>
<!-- Transform with separator for display --><Message Text="Files: @(Compile->'%(Filename)', ', ')" />

Exclude Pattern — Set Subtraction on Include

xml
<ItemGroup>  <Compile Include="**\*.cs" Exclude="Generated\**;Tests\**" /></ItemGroup>

Exclude only works on Include — it cannot be used with Update or Remove.

Conditional Item Inclusion

xml
<!-- Condition on ItemGroup — all or nothing --><ItemGroup Condition="'$(NetCoreBuild)' == 'true'">  <PackageReference Include="System.IO.Pipelines" /></ItemGroup>
<!-- Condition on individual items --><ItemGroup>  <PackageReference Include="System.IO.Pipelines"      Condition="'$(NetCoreBuild)' == 'true'" /></ItemGroup>

PrivateAssets on Tool/Analyzer Packages

xml
<ItemGroup>  <PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" PrivateAssets="all" />  <PackageReference Include="StyleCop.Analyzers" PrivateAssets="all" /></ItemGroup>

Common Pitfalls

Cross-product batching

Referencing %(Metadata) from two different item groups creates O(N×M) executions:

xml
<!-- BAD: Cross-product of @(Source) × @(Config) --><Exec Command="process %(Source.Identity) with %(Config.Identity)" />
<!-- GOOD: Reference one group via batching, the other via property --><Exec Command="process %(Source.Identity) with $(ConfigFile)" />

Generated files in source tree

Write to $(IntermediateOutputPath) (obj/), not the source directory. Source-tree generation pollutes version control and can cause duplicate compilation via globs.

Missing FileWrites

Every file created during a target must be added to @(FileWrites) for dotnet clean support.

來源與署名

來源:dotnet/skills位於plugins/dotnet-msbuild/skills/item-management提交0608d89

授權條款: MIT

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架