关于 item-management
面向 MSBuild 开发者的条目组操作参考技能,涵盖添加、移除、更新、批处理与转换,并说明常见构建陷阱。
主要功能
- 01Include、Remove 和 Update 模式
- 02基于元数据的条目批处理
- 03条目转换与排除
- 04条件式条目纳入
- 05生成文件与 FileWrites 指引
适用场景
- 01在 MSBuild target 中增改条目
- 02按条目元数据批处理任务
- 03创建转换后的条目列表
- 04避免清理与源目录构建问题
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ dotnet/ skills --skill item-management安装后在 Claude Code 中输入/item-management确认已加载。
详细介绍
MSBuild 项管理模式
来自 Microsoft.Common.CurrentVersion.targets 的项组操作规范模式。
Include / Remove / Update — 三种操作
| 操作 | 用途 | 适用场景 |
|---|---|---|
Include | 向组中添加新项 | 创建具有标识和元数据的项 |
Remove | 移除符合模式的项 | 排除文件或清空组 |
Update | 修改现有项的元数据 | 添加或更改元数据,而不重新添加项 |
Include — 添加项
<ItemGroup>
<Compile Include="Generated\*.cs">
<AutoGen>true</AutoGen>
</Compile>
</ItemGroup>
Remove — 移除项
<ItemGroup>
<Reference Remove="$(AdditionalExplicitAssemblyReferences)" />
<_CleanOrphanFileWrites Include="@(_CleanPriorFileWrites)"
Exclude="@(_CleanCurrentFileWrites)" />
<_Temporary Remove="@(_Temporary)" />
</ItemGroup>
Update — 修改现有项
<ItemGroup>
<EmbeddedResource Update="@(EmbeddedResource)"
Condition="'%(NuGetPackageId)' == 'Microsoft.CodeAnalysis.Collections'">
<GenerateSource>true</GenerateSource>
<ClassName>Microsoft.CodeAnalysis.Collections.SR</ClassName>
</EmbeddedResource>
</ItemGroup>
Update 不会添加项,只会修改组中已有的项。
项批处理 — %(Metadata)
当 %(Metadata) 出现在目标属性或任务参数中时,MSBuild 会按每个唯一的元数据值进行批处理。
目标级批处理(Outputs)
<Target Name="GenerateSatelliteAssemblies"
Inputs="$(MSBuildAllProjects);@(_SatelliteAssemblyResourceInputs)"
Outputs="$(IntermediateOutputPath)%(Culture)\$(TargetName).resources.dll">
</Target>
任务级批处理
<Copy SourceFiles="@(_SourceItems)"
DestinationFiles="@(_SourceItems->'$(OutDir)%(TargetPath)')">
</Copy>
使用 Condition 按项筛选
<ItemGroup>
<_ResxOutput Include="@(EmbeddedResource->'%(OutputResource)')"
Condition="'%(EmbeddedResource.WithCulture)' == 'false'" />
</ItemGroup>
批处理规则
Condition或Outputs中的%(Metadata)→ 目标按每个唯一值进行批处理。- 任务参数中的
%(Metadata)→ 任务按每个唯一值进行批处理。 - 不要在同一表达式中混用来自不同项组的
%(),这会导致交叉组合(请参阅“常见问题”)。
项转换 — @(Item->'expression')
转换通过对每个项应用表达式来创建新的项列表:
<Copy SourceFiles="@(IntermediateAssembly)"
DestinationFiles="@(IntermediateAssembly->'$(OutDir)%(Filename)%(Extension)')"/>
<Message Text="Files: @(Compile->'%(Filename)', ', ')" />
Exclude 模式 — 对 Include 执行集合减法
<ItemGroup>
<Compile Include="**\*.cs" Exclude="Generated\**;Tests\**" />
</ItemGroup>
Exclude 只能与 Include 配合使用,不能与 Update 或 Remove 配合使用。
条件项包含
<ItemGroup Condition="'$(NetCoreBuild)' == 'true'">
<PackageReference Include="System.IO.Pipelines" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.IO.Pipelines"
Condition="'$(NetCoreBuild)' == 'true'" />
</ItemGroup>
工具/分析器包中的 PrivateAssets
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" PrivateAssets="all" />
</ItemGroup>
常见问题
交叉组合批处理
引用来自两个不同项组的 %(Metadata) 会产生 O(N×M) 次执行:
<Exec Command="process %(Source.Identity) with %(Config.Identity)" />
<Exec Command="process %(Source.Identity) with $(ConfigFile)" />
在源代码树中生成文件
应写入 $(IntermediateOutputPath)(obj/),而不是源目录。在源代码树中生成文件会污染版本控制,并可能通过通配符导致重复编译。
缺少 FileWrites
目标创建的每个文件都必须添加到 @(FileWrites),才能支持 dotnet clean。
评论
支持 Markdown