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

标签 c# .net roslyn roslyn-code-analysis

我尝试使用 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:\Utils\CA5\CA5.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>

程序.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}");
            }
        }
    }
}

关于c# - Roslyn 代码分析从无错误解决方案中返回错误的构建错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58698247/

相关文章:

c# - 如何将 Visual Studio 设置为使用 K&R 样式包围?

c# - 从 C# 中通过引用传递,通过 C.L.I.到非托管 C++

c# - 两组网格之间的快速 bool 运算

visual-studio-2010 - 有没有办法更改 Roslyn CTP 中 C# 交互窗口的字体和颜色?

Visual Studio 之外的 C# REPL

c# - 在 roslyn 中解析 C# 条件编译语句

c# - 在 Mongo .NET 2.0 驱动程序中捕获 MongoAuthenticationException

c# - 在 C# .NET Web 服务中保留对象

.net - F# 函数返回值

.net - 在我的析构函数中释放 Excel 对象