VS2017社区版更新代码分析器后项目重复重建问题咨询
我之前也碰到过几乎一模一样的场景——核心库被上百个项目依赖,仅仅更新引用的分析器二进制文件,就触发了连锁式的重复重建,确实挺折腾的。结合VS2017 Community的特性,给你几个实用的解决方案:
问题根源
当你替换MyAnalyzer.dll后,MSBuild会检测到MyProject.csproj的依赖项(分析器文件)发生了变更,默认逻辑会判定MyProject的输出可能受影响,因此触发它的重建。而由于上百个项目都依赖MyProject,这些项目也会被依次触发重建,哪怕MyProject实际编译出的dll根本没有变化。
解决方案
1. 把分析器引用移到全局配置文件
如果你的解决方案里多数项目都需要用到这个分析器,推荐把分析器的引用从MyProject.csproj转移到解决方案根目录的Directory.Build.props文件中,让分析器全局作用于所有项目:
<!-- Directory.Build.props 示例内容 --> <Project> <ItemGroup> <Analyzer Include="你的路径\MyAnalyzer.dll" /> </ItemGroup> </Project>
之后记得移除MyProject.csproj里对应的分析器引用。这样更新MyAnalyzer.dll时,只会触发直接依赖分析器的项目检查,不会影响MyProject的依赖链,自然也就不会触发大规模重建。
2. 禁用分析器的依赖检测
如果必须保留MyProject对分析器的引用,可以在MyProject.csproj里添加配置,告诉MSBuild分析器的变化不会影响项目输出:
<PropertyGroup> <!-- 全局禁用分析器的依赖检测逻辑 --> <DisableAnalyzerDependencyDetection>true</DisableAnalyzerDependencyDetection> </PropertyGroup>
或者更精细地只针对MyAnalyzer.dll设置:
<ItemGroup> <Analyzer Update="MyAnalyzer.dll"> <!-- 标记该分析器文件变更不会触发项目重建 --> <IsDependency>False</IsDependency> </Analyzer> </ItemGroup>
这个方法不需要调整引用结构,直接修改MyProject的配置就能生效。
3. 将分析器打包为NuGet包
长期维护来看,把MyAnalyzer.dll打包成NuGet包是更规范的做法。通过NuGet引用分析器后:
- 若
MyProject的NuGet包版本没有变更,依赖它的项目不会触发重建; - 分析器的更新只会影响直接引用该NuGet包的项目,不会牵连整个依赖链。
你可以用VS2017自带的NuGet打包工具,或者手动编写.nuspec文件来创建分析器NuGet包。
4. 临时规避:手动跳过不必要的重建
如果只是临时解决问题,你可以:
- 在VS2017的「生成」菜单中选择「仅生成已修改的项目」;
- 或者用MSBuild命令行指定只构建需要更新的项目,跳过
MyProject:
msbuild 你的解决方案.sln /t:Build /p:BuildProjectReferences=false /p:ProjectsToBuild=需要构建的项目列表
不过这个方法偏手动,不太适合自动化构建流程。
内容的提问来源于stack exchange,提问作者Alex Davidson

