You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Visual Studio 2017中编程运行静态代码分析并自动化获取结果?

解决方案

1. 使用EnvDte实现原生代码分析自动化

VS的EnvDte API可以直接调用代码分析命令并读取错误列表中的结果,这是最贴合你现有插件技术栈的方案:

触发代码分析

首先通过ExecuteCommand调用VS内置的代码分析命令,然后监听构建完成事件等待分析结束:

var dte = (EnvDte80.DTE2)Package.GetGlobalService(typeof(EnvDte.DTE));
// 执行解决方案级代码分析
dte.ExecuteCommand("Build.RunCodeAnalysisOnSolution");

// 监听构建完成事件,确认分析结束
dte.Events.BuildEvents.OnBuildDone += (scope, action) =>
{
    if (action == EnvDte.vsBuildAction.vsBuildActionBuild)
    {
        // 这里开始提取分析结果
        ExtractCodeAnalysisResults(dte);
    }
};
提取CA13xx警告

分析完成后,直接读取错误列表中的条目,筛选CA13开头的全球化警告:

private void ExtractCodeAnalysisResults(EnvDte80.DTE2 dte)
{
    var errorList = dte.ToolWindows.ErrorList;
    foreach (EnvDte.Error error in errorList.ErrorItems)
    {
        // 只处理CA13系列的全球化警告
        if (error.ErrorNumber.StartsWith("CA13") && error.ErrorLevel == EnvDte.vsErrorLevel.vsErrorLevelWarning)
        {
            string warningId = error.ErrorNumber;
            string description = error.Description;
            string filePath = error.FileName;
            int lineNumber = error.Line;
            
            // 这里可以将结果写入日志、生成报告或进行后续处理
            Console.WriteLine($"[{warningId}] {description} - {filePath}:{lineNumber}");
        }
    }
}

这种方案的优点是无需额外依赖,直接复用VS的原生代码分析能力,缺点是对警告的结构化解析能力较弱,只能拿到基础的文本和位置信息。

2. 使用Roslyn实现更灵活的代码分析

如果你需要更精细的控制(比如在代码层面直接分析、修改代码),Roslyn是更好的选择,它可以直接加载解决方案并运行诊断分析:

准备工作

在你的插件项目中安装以下NuGet包:

  • Microsoft.CodeAnalysis
  • Microsoft.CodeAnalysis.CSharp
  • Microsoft.CodeAnalysis.Diagnostics
  • Microsoft.CodeAnalysis.Workspaces.MSBuild
加载解决方案并分析CA13xx警告
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Diagnostics;
using System.Collections.Immutable;
using System.Linq;

// 创建MSBuild工作区
var workspace = MSBuildWorkspace.Create();
// 加载目标解决方案
var solution = await workspace.OpenSolutionAsync(@"C:\Path\To\Your\Solution.sln");

// 获取所有CA13系列的诊断规则
var globalizationDiagnostics = DiagnosticDescriptor.GetDiagnostics()
    .Where(d => d.Id.StartsWith("CA13"))
    .ToImmutableArray();

// 遍历每个项目进行分析
foreach (var project in solution.Projects)
{
    var compilation = await project.GetCompilationAsync();
    if (compilation == null) continue;

    // 运行诊断分析
    var diagnostics = await compilation.WithAnalyzers(globalizationDiagnostics)
        .GetAllDiagnosticsAsync();

    // 处理CA13xx警告
    foreach (var diag in diagnostics.Where(d => d.Id.StartsWith("CA13")))
    {
        string warningId = diag.Id;
        string message = diag.GetMessage();
        var location = diag.Location;
        string filePath = location.SourceTree?.FilePath;
        var linePosition = location.GetLineSpan().StartLinePosition;
        int lineNumber = linePosition.Line + 1; // Roslyn行号从0开始,转换为VS的1-based行号
        
        // 这里可以进行更复杂的处理,比如定位代码节点、自动修复等
        Console.WriteLine($"[{warningId}] {message} - {filePath}:{lineNumber}");
    }
}

这种方案的优势是完全脱离VS的UI层,直接操作代码语法树,你可以基于分析结果实现自动化修复(比如将硬编码字符串替换为资源文件引用),适合需要深度定制的场景。

3. 注意事项

  • 使用EnvDte时,确保所有操作在VS主线程执行,避免跨线程访问UI元素的异常。
  • Roslyn方案中,注意处理异步操作,避免阻塞插件的UI线程。
  • CA13xx系列包含多个具体规则(如CA1303:不要将文本作为本地化参数传递,CA1305:指定IFormatProvider等),你可以根据需求筛选特定的规则ID进行处理。

内容的提问来源于stack exchange,提问作者reckface

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:52:38