对于多个(非常高级)分析,我想要Roslyn SDK:1 . 仅对“新”代码应用诊断(保留过时的代码)2 . 检测死代码(对于公共方法,定义应用程序的入口点)3 . 批量修复代码

换句话说:仅仅在视觉工作室中构建一个 DiagnosticAnalyzer 是不够的 . 我成功构建了这些,并为它们编写了单元测试(受到Sonar的启发) . 但是,这只是一次性分析一个(或最多一小部分)文件 .

所以这是我的问题:我已经尝试了几种方法来加载完整的.NET解决方案并编译它(我自己),但都失败了 .

public static async Task Main(string[] args)
{
    var analyzers = (new DiagnosticAnalyzer[] { new MyCustomAnalyzer }).ToImmutableArray();

    var file = new FileInfo(@"c:\path\my_solution.sln");

    using (var workspace = MSBuildWorkspace.Create())
    {
        workspace.WorkspaceFailed += OnWorkspaceFailed;

        var solution = await workspace.OpenSolutionAsync(solutionFile.FullName);
        var dependencyGraph = solution.GetProjectDependencyGraph();
        var projectIds = dependencyGraph.GetTopologicallySortedProjects();

        foreach (var projectId in projectIds)
        {
            using (var cancel = new CancellationTokenSource())
            {
                var project = solution.GetProject(projectId);

                var compilation = (await project.GetCompilationAsync(cancel.Token))
                    .WithOptions(project.CompilationOptions)
                    .WithAnalyzers(array, cancellationToken: cancel.Token);

                foreach (var diagnostic in await compilation.GetAllDiagnosticsAsync())
                {
                    (diagnostic.Severity >= DiagnosticSeverity.Error
                        ? Console.Error
                        : Console.Out).WriteLine(diagnostic);
                    // Do magic
                }
            }
        }
    }
}

这是我包含的包列表:

<PackageReference Include="Microsoft.Build" Version="15.8.166" />
<PackageReference Include="Microsoft.Build.Framework" Version="15.8.166" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="15.8.166" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.8.166" />
<PackageReference Include="Microsoft.CodeAnalysis" Version="2.9.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="2.9.0" />

我尝试使用.NET核心2.1和.NET 4.6.1运行它(因为Microsoft.CodeAnalysis.Workspaces.MSBuild被追溯为.NET 4.6.1)

我得到的错误(基于不同的设置):

.NET 4.6.1

使用以下消息处理文件'cusotom project.vbproj.or.csproj'时Msbuild失败:C:\ Program Files(x86)\ Microsoft Visual Studio \ 2017 \ Enterprise \ MSBuild \ 15.0 \ Bin \ Microsoft.Common.CurrentVersion.targets:(1657,5):"GetReferenceNearestTargetFrameworkTask"任务无法从程序集"C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\NuGet\NuGet.Build.Tasks.dll"实例化 . 请验证任务程序集是否已使用与计算机上安装的Microsoft.Build.Framework程序集相同的Microsoft.Build.Framework程序集构建,并且主机应用程序未缺少Microsoft.Build.Framework的绑定重定向 . 无法将'NuGet.Build.Tasks.GetReferenceNearestTargetFrameworkTask'类型的对象强制转换为'Microsoft.Build.Framework.ITask'类型 .

.NET 4.6.1 与MSBUILD_EXE_PATH

使用以下消息处理文件'cusotom project.vbproj.or.csproj'时Msbuild失败:C:\ Program Files(x86)\ MSBuild \ 14.0 \ bin \ Microsoft.Common.CurrentVersion.targets:(1407,5):无法从程序集"Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"实例化"AssignProjectConfiguration"任务 . 请验证任务程序集是否已使用与计算机上安装的Microsoft.Build.Framework程序集相同的Microsoft.Build.Framework程序集构建,并且主机应用程序未缺少Microsoft.Build.Framework的绑定重定向 . 无法将'Microsoft.Build.Tasks.AssignProjectConfiguration'类型的对象强制转换为'Microsoft.Build.Framework.ITask'类型 .

.NET Core 2.1

使用消息处理文件'cusotom project.vbproj.or.csproj'时Msbuild失败:找不到导入的项目“\ bin \ Debug \ netcoreapp2.1 \ Microsoft..targets” . 确认声明中的路径是否正确,以及该文件是否存在于磁盘上 . *

.NET Core 2.1 (使用MSBUILD_EXE_PATH)

使用以下消息处理文件'cusotom project.vbproj.or.csproj'时Msbuild失败:Program Files \ dotnet \ sdk .. \ Microsoft.Common.CurrentVersion.targets:(1544,5):无法从程序集Microsoft.Build.Tasks.Core加载"Microsoft.Build.Tasks.ResolveNonMSBuildProjectOutput"任务,Version = 15.1.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a . 确认声明是否正确,程序集及其所有依赖项是否可用,以及该任务是否包含实现Microsoft.Build.Framework.ITask的公共类 .

我设置路径的方式:

Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", @"Program Files\dotnet\sdk\..\MSBuild.dll");

我也尝试过,因为那是在某处提出的,但这并没有改变任何东西 .