如何通过MSBuild预构建步骤检查引用项目命名(禁以.Execute结尾)
问题
我的仓库里有多个项目,部分项目通过标准方式引用其他项目,标准的.csproj文件示例如下:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFrameworks>net7.0-windows</TargetFrameworks> <OutputType>Library</OutputType> <ProjectGuid>{6b123456-412f-7941-cfcc-f021137c2341}</ProjectGuid> </PropertyGroup> <ItemGroup> <Compile ... /> <Compile ... /> ... </ItemGroup> <ItemGroup> <ProjectReference Include="..\Project1\Project1.csproj" /> <ProjectReference Include="..\Project2\Project2.csproj" /> </ItemGroup> </Project>
我想要添加一个MSBuild预构建步骤,确保所有被引用的项目符合特定规范:项目名称不能以.Execute结尾。我已经开始定义Target,但不知道如何:
- 检索项目的依赖列表
- 遍历这些依赖
当前的代码如下:
<Target Name="EnsureNonExecute" BeforeTargets="Build"> <!-- How to iterate over the list of referenced projects? --> </Target>
解决方案
你可以利用MSBuild的内置项和任务实现需求,具体实现如下:
核心思路
- 直接使用
ProjectReference项集合获取所有直接引用的项目;若需包含间接依赖,可改用ResolvedProjectReferences项。 - 通过
MSBuild任务调用子Target获取每个引用项目的名称,再遍历检查名称是否符合规范。
完整代码
<Target Name="EnsureNonExecute" BeforeTargets="Build"> <!-- 调用每个引用项目的GetProjectName Target,获取项目名称 --> <MSBuild Projects="@(ProjectReference)" Targets="GetProjectName" Properties="Configuration=$(Configuration)" Outputs="%(ProjectReference.Identity).ProjectName"> <Output TaskParameter="TargetOutputs" ItemName="ReferencedProjectNames" /> </MSBuild> <!-- 用于提取项目名称的临时Target --> <Target Name="GetProjectName"> <CreateItem Include="$(MSBuildProjectName)"> <Output TaskParameter="Include" ItemName="ProjectNameOutput" /> </CreateItem> </Target> <!-- 检查项目名称规范,违反则抛出构建错误 --> <Error Text="引用的项目 '%(ReferencedProjectNames.Identity)' 违反规范:项目名称不能以'.Execute'结尾" Condition="EndsWith('%(ReferencedProjectNames.Identity)', '.Execute')" /> </Target>
代码说明
<MSBuild>任务:触发每个引用项目的GetProjectNameTarget,通过MSBuildProjectName内置属性获取项目名称,并将结果输出到ReferencedProjectNames项集合中。GetProjectNameTarget:将当前项目的名称封装为输出项,供主Target调用。<Error>任务:遍历所有引用项目名称,若名称以.Execute结尾则抛出错误,直接终止构建流程。
如果需要检查间接依赖(即引用项目的嵌套引用),只需将代码中的@(ProjectReference)替换为@(ResolvedProjectReferences)即可。
内容的提问来源于stack exchange,提问作者LA.27
相关产品推荐
相关产品推荐

