【问题标题】:Diagnostic error while loading solution and projects with MSBuildWorkspace使用 MSBuildWorkspace 加载解决方案和项目时出现诊断错误
【发布时间】:2020-12-12 18:50:37
【问题描述】:

我正在尝试使用 Roslyn 编译器在 .Net Core 中编写一个类来编译我的项目并将该项目中的 ClassDefinitions 返回给我。我将使用该信息使用 T4 生成代码。

这是一个 .Net Core 3.1 项目。

我找不到任何关于我应该使用哪些软件包来完成此任务的好的文档。

在加载解决方案后的解决方案吸气剂中,我在 Documents 属性中没有收到任何文档,并且它尝试加载的每个项目都有 1 条诊断消息:

System.ApplicationException: 'Msbuild failed when processing the file 'C:\Projects\FB-IT\grouptool\sources\Wur.Grouptool\Wur.GroupTool.Web\Wur.GroupTool.Web.csproj' with message: The SDK resolver type "WorkloadSdkResolver" failed to load. Could not load file or assembly 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.  C:\Projects\FB-IT\grouptool\sources\Wur.Grouptool\Wur.GroupTool.Web\Wur.GroupTool.Web.csproj
Msbuild failed when processing the file 'C:\Projects\FB-IT\grouptool\sources\Wur.Grouptool\Wur.GroupTool.Core\Wur.GroupTool.Core.csproj' with message: The SDK resolver type "WorkloadSdkResolver" failed to load. Could not load file or assembly 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.  C:\Projects\FB-IT\grouptool\sources\Wur.Grouptool\Wur.GroupTool.Core\Wur.GroupTool.Core.csproj
Msbuild failed when processing the file 'C:\Projects\FB-IT\grouptool\sources\Wur.Grouptool\Wur.GroupTool.Core.Tests\Wur.GroupTool.Core.Tests.csproj' with message: The SDK resolver type "WorkloadSdkResolver" failed to load. Could not load file or assembly 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.  C:\Projects\FB-IT\grouptool\sources\Wur.Grouptool\Wur.GroupTool.Core.Tests\Wur.GroupTool.Core.Tests.csproj
Msbuild failed when processing the file 'C:\Projects\FB-IT\grouptool\sources\Wur.Grouptool\Wur.Roslyn.Metadata\Wur.Roslyn.Metadata.csproj' with message: The SDK resolver type "WorkloadSdkResolver" failed to load. Could not load file or assembly 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.  C:\Projects\FB-IT\grouptool\sources\Wur.Grouptool\Wur.Roslyn.Metadata\Wur.Roslyn.Metadata.csproj
Msbuild failed when processing the file 'C:\Projects\FB-IT\grouptool\sources\Wur.Grouptool\Wur.Roslyn.Metadata.Tests\Wur.Roslyn.Metadata.Tests.csproj' with message: The SDK resolver type "WorkloadSdkResolver" failed to load. Could not load file or assembly 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.  C:\Projects\FB-IT\grouptool\sources\Wur.Grouptool\Wur.Roslyn.Metadata.Tests\Wur.Roslyn.Metadata.Tests.csproj
'

我已经安装了这些软件包(是的,甚至尝试过预发布):

还必须在“排除资产”属性中设置“运行时”:

这是我的课:

using Microsoft.Build.Locator;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.MSBuild;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Wur.Roslyn.Metadata
{
    public class RoslynProjectProvider
    {
        public string PathToSolution { get; private set; }
        public string ProjectName { get; private set; }

        public RoslynProjectProvider(string pathToSolution, string projectName)
        {
            PathToSolution = pathToSolution;
            ProjectName = projectName;
        }

        private MSBuildWorkspace _Workspace;

        public MSBuildWorkspace Workspace
        {
            get
            {
                if (_Workspace == null)
                {
                    MSBuildLocator.RegisterDefaults();

                    _Workspace = MSBuildWorkspace.Create();
                }

                return _Workspace;
            }
        }

        private Solution _Solution;

        public Solution Solution
        {
            get
            {
                if (_Solution == null)
                {
                    _Solution = Workspace.OpenSolutionAsync(PathToSolution).Result;

                    if(Workspace.Diagnostics.Count > 0)
                    {
                        StringBuilder sb = new StringBuilder();

                        foreach (var diagnostic in Workspace.Diagnostics)
                        {
                            sb.Append(diagnostic.Message).Append(Environment.NewLine);
                        }

                        throw new ApplicationException(sb.ToString());
                    }
                }

                return _Solution;
            }
        }

        private Project _Project;

        /// <summary>
        /// Singleton Project in a solution
        /// </summary>
        public Project Project
        {
            get
            {
                if (_Project == null)
                {
                    _Project = Solution.Projects.FirstOrDefault(p => p.Name.Equals(ProjectName, StringComparison.InvariantCultureIgnoreCase));

                    if (_Project == null)
                    {
                        throw new ApplicationException($"Cannot find project {ProjectName}");
                    }
                }

                return _Project;
            }
        }

        private Compilation _Compilation;

        /// <summary>
        /// Singleton compilation of the project
        /// </summary>
        public Compilation ProjectCompilation
        {
            get
            {
                if (_Compilation == null)
                {
                    _Compilation = Project.GetCompilationAsync().Result;
                }

                return _Compilation;
            }
        }

        private List<ClassDeclarationSyntax> _Classes;

        public List<ClassDeclarationSyntax> Classes
        {
            get
            {
                if (_Classes == null)
                {
                    _Classes = new List<ClassDeclarationSyntax>();

                    foreach (var document in Project.Documents)
                    {
                        var tree = document.GetSyntaxTreeAsync().Result;

                        var semanticModel = ProjectCompilation.GetSemanticModel(tree);

                        foreach (var type in tree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>())
                        {
                            _Classes.Add(type);
                        }
                    }
                }

                return _Classes;
            }
        }
    }
}

还有一个单元测试来测试这个类:

public class UnitTest1
{
    [Fact]
    public void Test1()
    {
        var provider = new RoslynProjectProvider(@"C:\Projects\FB-IT\grouptool\sources\Wur.Grouptool\Wur.Grouptool.sln", "Wur.GroupTool.Core");

        var classes = provider.Classes;
    }
}

== 编辑 ==

它要求版本 5.0.0.0 但 System.Runtime 的版本较低。会不会是这里的问题?

== 编辑 ==

对第一个答案的备注:好的,终于可以使用了。不得不下载 .Net Core 3.1.404 SDK 从这里: dotnet.microsoft.com/download/dotnet-core/thank-you/...。添加了路径 正如你所建议的那样,瞧,它开始工作了。

它在单元测试中可以正常工作,但在 T4 模板中却不行。当我尝试运行自定义工具时,我得到以下异常(启用绑定日志记录):

Severity    Code    Description Project File    Line    Suppression State
Error       Running transformation: System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
File name: 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
   at Microsoft.VisualStudio.TextTemplating9A1960153A0EC5389F1AC1A553BA062D21024CF3A0BEA5F9915226007DBBA0457E39D7A79FF10F4293C4331881904FF0454986C06541AC3156F88310BB537850.GeneratedTextTransformation.TransformText()
   at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
   at Microsoft.VisualStudio.TextTemplating.TransformationRunner.PerformTransformation()

=== Pre-bind state information ===
LOG: DisplayName = System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 (Fully-specified)
LOG: Appbase = file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/
LOG: Initial PrivatePath = NULL
Calling assembly : Wur.Roslyn.Metadata, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in LoadFrom load context.
WRN: Native image will not be probed in LoadFrom context. Native image will only be probed in default load context, like with Assembly.Load().
LOG: Using application configuration file: C:\Users\User\AppData\Local\Microsoft\VisualStudio\16.0_966a030a\devenv.exe.config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Post-policy reference: System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/System.Runtime.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/System.Runtime/System.Runtime.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/PublicAssemblies/System.Runtime.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/PublicAssemblies/System.Runtime/System.Runtime.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/PrivateAssemblies/System.Runtime.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/PrivateAssemblies/System.Runtime/System.Runtime.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/CommonExtensions/Microsoft/TestWindow/System.Runtime.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/CommonExtensions/Microsoft/TestWindow/System.Runtime/System.Runtime.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/CommonExtensions/Platform/Debugger/System.Runtime.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/CommonExtensions/Platform/Debugger/System.Runtime/System.Runtime.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/PrivateAssemblies/DataCollectors/System.Runtime.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/PrivateAssemblies/DataCollectors/System.Runtime/System.Runtime.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/PrivateAssemblies/DataCollectors/x86/System.Runtime.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/PrivateAssemblies/DataCollectors/x86/System.Runtime/System.Runtime.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/System.Runtime.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/System.Runtime/System.Runtime.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/PublicAssemblies/System.Runtime.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/PublicAssemblies/System.Runtime/System.Runtime.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/PrivateAssemblies/System.Runtime.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/PrivateAssemblies/System.Runtime/System.Runtime.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/CommonExtensions/Microsoft/TestWindow/System.Runtime.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/CommonExtensions/Microsoft/TestWindow/System.Runtime/System.Runtime.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/CommonExtensions/Platform/Debugger/System.Runtime.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/CommonExtensions/Platform/Debugger/System.Runtime/System.Runtime.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/PrivateAssemblies/DataCollectors/System.Runtime.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/PrivateAssemblies/DataCollectors/System.Runtime/System.Runtime.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/PrivateAssemblies/DataCollectors/x86/System.Runtime.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/PrivateAssemblies/DataCollectors/x86/System.Runtime/System.Runtime.EXE.
LOG: Attempting download of new URL file:///C:/Projects/FB-IT/grouptool/sources/Wur.GroupTool/Wur.Roslyn.Metadata/bin/Debug/netcoreapp3.1/System.Runtime.DLL.
LOG: Attempting download of new URL file:///C:/Projects/FB-IT/grouptool/sources/Wur.GroupTool/Wur.Roslyn.Metadata/bin/Debug/netcoreapp3.1/System.Runtime/System.Runtime.DLL.
LOG: Attempting download of new URL file:///C:/Projects/FB-IT/grouptool/sources/Wur.GroupTool/Wur.Roslyn.Metadata/bin/Debug/netcoreapp3.1/System.Runtime.EXE.
LOG: Attempting download of new URL file:///C:/Projects/FB-IT/grouptool/sources/Wur.GroupTool/Wur.Roslyn.Metadata/bin/Debug/netcoreapp3.1/System.Runtime/System.Runtime.EXE.    Wur.GroupTool.Core.ViewModels   C:\Projects\FB-IT\grouptool\sources\Wur.GroupTool\Wur.GroupTool.Core.ViewModels\ViewModels\Web\PlayGround.tt    1

是否有可能只是因为它不存在而找不到它。我的目录中没有 4.2.2.0 版本:

【问题讨论】:

    标签: c# .net roslyn .net-core-3.1


    【解决方案1】:

    SDK 版本不匹配

    看来,当您安装最新的 Visual Studio(我有 16.8.3)时 - MSBuildLocator 默认使用 .NET 5 MSBuild:

    JsonConvert.SerializeObject(MSBuildLocator.QueryVisualStudioInstances(VisualStudioInstanceQueryOptions.Default)); 
    // ouputs in VS 2019: 
    // [{"Version":"5.0.101","VisualStudioRootPath":"C:\\Program Files\\dotnet\\sdk\\5.0.101\\","Name":".NET Core SDK","MSBuildPath":"C:\\Program Files\\dotnet\\sdk\\5.0.101\\","DiscoveryType":4}]
    // just thought I'd try the same in LINQPad 5 and here's the output:
    // [{"Version":{"Major":16,"Minor":8,"Build":30804,"Revision":86,"MajorRevision":0,"MinorRevision":86},"VisualStudioRootPath":"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community","Name":"Visual Studio Community 2019","MSBuildPath":"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\MSBuild\\Current\\Bin","DiscoveryType":2}]
    

    当您执行 MSBuildLocator.RegisterDefaults() 时 - 它会从上面的列表中获取 第一个 实例。

    然后,使用 .NET 5 MSBuild 加载 .NET Core 3.1 项目似乎最终出现错误:

    Msbuild failed when processing the file '...' with message: The SDK resolver type "WorkloadSdkResolver" failed to load. Could not load file or assembly 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
    

    但是,您可以告诉 MSBuidLocator 从特定的 SDK 位置初始化环境:MSBuildLocator.RegisterMSBuildPath。所以我尝试像这样更新你的Workspace getter:

    public MSBuildWorkspace Workspace
    {
        get
        {
            if (_Workspace == null)
            {
                MSBuildLocator.RegisterMSBuildPath("C:\\Program Files\\dotnet\\sdk\\3.1.404");// your version might be different, check `dotnet --list-sdks`
                _Workspace = MSBuildWorkspace.Create();
            }
            return _Workspace;
        }
    }
    

    然后我必须按照诊断输出并安装以下软件包:

    <PackageReference Include="Microsoft.NET.HostModel" Version="3.1.6" />
    <PackageReference Include="NuGet.Packaging" Version="5.8.0" />
    <PackageReference Include="NuGet.ProjectModel" Version="5.8.0" />
    

    将包安装到我的项目后 - 我能够在我的测试解决方案中成功列出类。

    还有一件事

    您可能会因为缺少对Microsoft.CodeAnalysis.CSharp.Workspaces 的引用(更多背景信息请参阅this SO answer)。

    所以我最终像这样更改了您的构造函数:

    public RoslynProjectProvider(string pathToSolution, string projectName)
    {
        var _ = typeof(Microsoft.CodeAnalysis.CSharp.Formatting.CSharpFormattingOptions); // this line forces a reference so MSBuild loads the assembly in question.
        PathToSolution = pathToSolution;
        ProjectName = projectName;
    }
    

    如果您想查看它,我已将完整的工作示例发布到 GitHub,但它几乎是您打包后在 VS 中运行的所有代码。

    【讨论】:

    • 感谢您尝试 timur。该项目需要参考 .Net Core 3.1 而不是 .Net 5.0。 typeof() 也不能解决问题。
    • 你的项目都是.net core 3.1吗?
    • 是的,所有项目都是3.1
    • var vs = MSBuildLocator.QueryVisualStudioInstances().Aggregate(new StringBuilder(), (sb,s) =&gt; sb.AppendLine(s.MSBuildPath)).ToString();放在MSBuildLocator.RegisterDefaults();之前会输出什么?
    • C:\Program Files\dotnet\sdk\5.0.101\
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-03
    • 2011-04-11
    • 1970-01-01
    • 1970-01-01
    • 2011-03-14
    • 1970-01-01
    相关资源
    最近更新 更多