【问题标题】:How to compile a .NET solution with the Roslyn SDK如何使用 Roslyn SDK 编译 .NET 解决方案
【发布时间】:2018-10-26 14:57:44
【问题描述】:

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

换句话说:仅仅在 Visual Studio 中构建一个应用 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 core 2.1 和 .NET 4.6.1 运行它(因为 Microsoft.CodeAnalysis.Workspaces.MSBuild 被称为 .NET 4.6.1)

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

.NET 4.6.1

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

.NET 4.6.1 与 MSBUILD_EXE_PATH

Msbuild 在处理文件“custom project.vbproj.or.csproj”时失败,消息为: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.Tasks.AssignProjectConfiguration”类型的对象转换为“Microsoft.Build.Framework.ITask”类型。

.NET Core 2.1

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

.NET Core 2.1(带有 MSBUILD_EXE_PATH)

Msbuild 在处理文件 'custom project.vbproj.or.csproj' 时失败,消息为:Program Files\dotnet\sdk..\Microsoft.Common.CurrentVersion.targets: (1544, 5): The " Microsoft.Build.Tasks.ResolveNonMSBuildProjectOutput”任务无法从程序集 Microsoft.Build.Tasks.Core 加载,版本 = 15.1.0.0,文化 = 中性,PublicKeyToken = b03f5f7f11d50a3a。确认声明正确,程序集及其所有依赖项都可用,并且任务包含实现 Microsoft.Build.Framework.ITask 的公共类。

我设置路径的方式:

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

我也尝试了 true,因为有人建议这样做,但这并没有改变任何东西。

【问题讨论】:

标签: .net roslyn roslyn-code-analysis


【解决方案1】:

好的,所以这里似乎有几件事在起作用。

  1. 在调用MSBuildWorkspace.Create() 方法之前,应将其配置为使用本地计算机上的特定 msbuild 配置。这是使用 MEF 解决所有必需的依赖项所必需的。看看 Dustin Campbell 写的描述 here

    不要在您的应用程序输出中包含任何 Microsoft.Build.* 程序集,Microsoft.Build.Locator 除外。如果您的应用程序包含 Microsoft.Build.dllMicrosoft.Build.Framework.dllMicrosoft.Build.Tasks.CoreMicrosoft.Build.Utiltiies.Core,它们可能会干扰 MSBuildLocator 已安装的程序集解析处理程序。

  2. 要在您的计算机上实际本地化一个 msbuild 实例,您应该使用一个帮助器类 MSBuildLocator,它可以在 Microsoft.MSBuild.Locator nuget 包(此处)中找到。

  3. 目前这整个过程并不真正支持在 dotnet core 上运行。他们更新了上面指定的 nuget 包以添加对 dotnet 核心的支持(请参阅 this github issue),并且可以通过预览版 myget feed 获得。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-05
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-13
    • 2011-08-05
    相关资源
    最近更新 更多