Roslyn代码分析从无错误的解决方案返回错误的构建错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Roslyn代码分析从无错误的解决方案返回错误的构建错误相关的知识,希望对你有一定的参考价值。

我尝试使用Roslyn分析一个非常简单的C#解决方案,一个具有简单框架程序的控制台应用程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CA5
{
    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}

上面的代码在VS 2019 Preview中构建时没有任何错误。对于这样一个简单的解决方案/程序,我希望Roslyn CA可以正常工作,但是Roslyn编译会返回错误,大多数与无法识别的类型有关。

我的CA代码是这样:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.MSBuild;

namespace CA5X
{
    class Program
    {
        static void Main(string[] args)
        {
            const string path = @"C:UtilsCA5CA5.sln";

            var props = new Dictionary<string, string>();
            props["CheckForSystemRuntimeDependency"] = "true";
            MSBuildWorkspace buildWorkspace = MSBuildWorkspace.Create(props);

            Solution solutionToAnalyze = buildWorkspace.OpenSolutionAsync(path).Result;
            foreach (Microsoft.CodeAnalysis.Project sProject in solutionToAnalyze.Projects)
            {
                Compilation sCompilation = sProject.GetCompilationAsync().Result;
                var errors = sCompilation.GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error); 

                Console.WriteLine("COUNT:  " + errors.Count().ToString());

                foreach (Microsoft.CodeAnalysis.Diagnostic diagnostic in errors)
                {
                    Console.WriteLine(diagnostic.GetMessage());
                }

            }
        }
    }
}

编译后检索到的诊断是:

The type or namespace name 'AssemblyTitleAttribute' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyTitle' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyDescriptionAttribute' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyDescription' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyConfigurationAttribute' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyConfiguration' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyCompanyAttribute' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyCompany' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyProductAttribute' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyProduct' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyCopyrightAttribute' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyCopyright' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyTrademarkAttribute' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyTrademark' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyCultureAttribute' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyCulture' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'ComVisibleAttribute' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'ComVisible' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'GuidAttribute' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'Guid' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyVersionAttribute' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyVersion' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyFileVersionAttribute' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'AssemblyFileVersion' could not be found (are you missing a using directive or an assembly reference?)
Predefined type 'System.String' is not defined or imported
The type or namespace name 'System' could not be found (are you missing a using directive or an assembly reference?)
Predefined type 'System.Object' is not defined or imported
Predefined type 'System.String' is not defined or imported
Predefined type 'System.Void' is not defined or imported
'object' does not contain a constructor that takes 0 arguments

我只能猜测这是由于某些配置问题而发生的,但是由于具有许多.NET版本和许多VS版本,因此无法尝试所有组合。

答案

如果您将项目设置为使用如下所示的MSBuildLocator,则它应该能够加载您的项目:

SampleRoslynTool.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net472</TargetFramework>
    <LangVersion>Latest</LangVersion>
  </PropertyGroup>

   <ItemGroup>
    <PackageReference Include="Microsoft.Build.Locator" Version="1.2.6" />
    <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="2.9.7" PrivateAssets="all" />
    <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.3.1" />
    <PackageReference Include="Microsoft.CodeAnalysis.VisualBasic.Workspaces" Version="3.3.1" />
    <PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="3.3.1" />
  </ItemGroup>

</Project>

Program.cs:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Build.Locator;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.MSBuild;
using Microsoft.CodeAnalysis.Text;

namespace SampleRoslynTool
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // Attempt to set the version of MSBuild.
            var visualStudioInstances = MSBuildLocator.QueryVisualStudioInstances().ToArray();
            var instance = visualStudioInstances.Length == 1
                // If there is only one instance of MSBuild on this machine, set that as the one to use.
                ? visualStudioInstances[0]
                // Handle selecting the version of MSBuild you want to use.
                : SelectVisualStudioInstance(visualStudioInstances);

            Console.WriteLine($"Using MSBuild at '{instance.MSBuildPath}' to load projects.");

            // NOTE: Be sure to register an instance with the MSBuildLocator 
            //       before calling MSBuildWorkspace.Create()
            //       otherwise, MSBuildWorkspace won't MEF compose.
            MSBuildLocator.RegisterInstance(instance);

            using (var workspace = MSBuildWorkspace.Create())
            {
                // Print message for WorkspaceFailed event to help diagnosing project load failures.
                workspace.WorkspaceFailed += (o, e) => Console.WriteLine(e.Diagnostic.Message);

                var solutionPath = args[0];
                Console.WriteLine($"Loading solution '{solutionPath}'");

                // Attach progress reporter so we print projects as they are loaded.
                var solution = await workspace.OpenSolutionAsync(solutionPath, new ConsoleProgressReporter());
                Console.WriteLine($"Finished loading solution '{solutionPath}'");

                // TODO: Do analysis on the projects in the loaded solution
            }
        }

        private static VisualStudioInstance SelectVisualStudioInstance(VisualStudioInstance[] visualStudioInstances)
        {
            Console.WriteLine("Multiple installs of MSBuild detected please select one:");
            for (int i = 0; i < visualStudioInstances.Length; i++)
            {
                Console.WriteLine($"Instance {i + 1}");
                Console.WriteLine($"    Name: {visualStudioInstances[i].Name}");
                Console.WriteLine($"    Version: {visualStudioInstances[i].Version}");
                Console.WriteLine($"    MSBuild Path: {visualStudioInstances[i].MSBuildPath}");
            }

            while (true)
            {
                var userResponse = Console.ReadLine();
                if (int.TryParse(userResponse, out int instanceNumber) &&
                    instanceNumber > 0 &&
                    instanceNumber <= visualStudioInstances.Length)
                {
                    return visualStudioInstances[instanceNumber - 1];
                }
                Console.WriteLine("Input not accepted, try again.");
            }
        }

        private class ConsoleProgressReporter : IProgress<ProjectLoadProgress>
        {
            public void Report(ProjectLoadProgress loadProgress)
            {
                var projectDisplay = Path.GetFileName(loadProgress.FilePath);
                if (loadProgress.TargetFramework != null)
                {
                    projectDisplay += $" ({loadProgress.TargetFramework})";
                }

                Console.WriteLine($"{loadProgress.Operation,-15} {loadProgress.ElapsedTime,-15:m\:ss\.fffffff} {projectDisplay}");
            }
        }
    }
}

以上是关于Roslyn代码分析从无错误的解决方案返回错误的构建错误的主要内容,如果未能解决你的问题,请参考以下文章

如何从无服务器 lambda 内部抛出错误

查看解决方案中的所有“建议”

错误集锦1. 编译错误 在编译向该请求提供服务所需资源的过程中出现错误。请检查下列特定错误详细信息并适当地修改源代码

从 Roslyn 代码分析器调用分析程序集的方法

使用 Roslyn 代码分析在引用的程序集中查找符号

错误 MSB3027:无法将“C:\pagefile.sys”复制到“bin\roslyn\pagefile.sys”。重试次数超过 10。失败