如何在使用 Visual Studio 2019 的解决方案中为多个项目指定自定义代码分析规则集?

How do I specify a custom code analysis ruleset for multiple projects in a solution using Visual Studio 2019?

我有一个自定义代码分析规则集,我想将其应用到我的解决方案中多个项目的所有配置,但看不到我该怎么做。

明确地说,我正在寻找一种方法(如果有的话)一步完成,而不是从 IDE.

编辑每个项目的属性

到目前为止我找到了这个指南:https://docs.microsoft.com/en-us/visualstudio/code-quality/how-to-configure-code-analysis-for-a-managed-code-project?view=vs-2019#specify-rule-sets-for-multiple-projects-in-a-solution

不过好像不太对。在 Visual Studio 2019 年,如果我转到“分析”>“配置代码分析”>“解决方案”,我会得到一个空白 属性 页面,其中包含以下消息:

注意:此 属性 页面已弃用,将在未来的产品版本中删除。

还有其他方法吗?我有很多项目:(

谢谢。

specify a rule set for a project,使用 CodeAnalysisRuleSet MSBuild 属性。

要做到这一点,您可以通过多种方式customize your build

在 Visual Studio 中没有关于是否有办法做到这一点的答案,所以我不得不求助于直接以批处理方式更改 .csproj 文件。

我发现约翰罗宾斯的这个脚本非常棒: https://www.wintellect.com/batch-updating-changing-visual-studio-projects-with-powershell/

安装后,我的用法是这样的,如果有人感兴趣的话:

dir -recurse *.csproj | Set-ProjectProperties -OverrideDefaultProperties -CustomConfigurationProperties @{ "CodeAnalysisRuleSet" = ".\SystemStandard.ruleset" }

dir -recurse *.csproj | Set-ProjectProperties -OverrideDefaultProperties -CustomConfigurationProperties @{ "RunCodeAnalysis" = "false" }

dir -recurse *.csproj | Set-ProjectProperties -OverrideDefaultProperties -CustomConfigurationProperties @{ "TreatWarningsAsErrors" = "true" } 

如果我正确理解问题,可以按照 this blog post 中列出的步骤轻松完成。

Directory.Build.props 方法

本指南的编写考虑了 StyleCop,但同一步骤适用于任何分析器。

  1. 与您的 .sln 文件一起创建一个名为 Directory.Build.props 的文件(使用这个确切的大小写),即在您的项目的 top-level 处。它的内容应该是这样的:
<Project>
  <PropertyGroup>
    <!-- This part specifies the ruleset file name. Change to something
         more appropriate if not using StyleCop. -->
    <CodeAnalysisRuleSet>$(SolutionDir)StyleCop.ruleset</CodeAnalysisRuleSet>
  </PropertyGroup>
  <!-- This part adds StyleCop as a reference in all projects + makes the 
       top-level stylecop.json file be used by all projects. Skip this
       altogether if you are not spefically using StyleCop. -->
  <ItemGroup>    
    <PackageReference Include=”StyleCop.Analyzers” Version=”1.1.1-rc.108" PrivateAssets=”all” />
    <AdditionalFiles Include=”$(SolutionDir)stylecop.json” Link=”stylecop.json” />
  </ItemGroup>
</Project>
  1. 使用您的分析器配置创建一个 StyleCop.ruleset 文件。

就是这样。下次您 运行 dotnet build 或在 Visual Studio 中构建项目时(如果您打开了解决方案,您可能必须 close/reopen ),这些规则应该适用。


作为参考,这里是我的一个项目中的 Directory.Build.props 文件:https://github.com/perlun/perlang/blob/master/Directory.Build.props

如果您的解决方案中的项目具有层次结构,这意味着它们相互引用并具有一个共同的、最抽象的基础,该基础是类似于此结构的根:

Common
├── Worker
└── Persistence
    └── API

...然后你可以在你的根项目中引用 StyleCop.Analyzers 包并将 <PrivateAssets> 标签的值设置为 none:

<ItemGroup>
  <PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    <PrivateAssets>none</PrivateAssets>
  </PackageReference>
</ItemGroup>
当您将 StyleCop.Analyzers 包引用添加到您的项目时,默认设置

all。这是什么意思?

You might be using a dependency purely as a development harness and might not want to expose that to projects that will consume your package. In this scenario, you can use the PrivateAssets metadata to control this behavior. ~ Docs

因此,默认情况下 StyleCop.Analyzers 只会在您明确引用包的项目中启用。但是在我参与过的几乎所有代码库中,都需要在解决方案中的所有项目中强制执行 StyleCode 规则(几乎所有项目,除了具有自动生成代码的项目,例如 EF 迁移)。在包引用元数据中将 all 更改为 none 将导致将样式规则传递给依赖它的所有项目。

解决方案

总而言之,根项目 Common 在将 <PrivateAssets> 设置为 none 时必须引用 StyleCop.Analyzers 包:

<ItemGroup>
  <PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    <PrivateAssets>none</PrivateAssets>
  </PackageReference>
</ItemGroup>

WorkerPersistence 或任何其他依赖项目只需引用前一层,这在任何分层中都是常见的做法架构无论如何:

<ItemGroup>
    <ProjectReference Include="..\Common\Common.csproj" />
</ItemGroup>