未正确加载第三方解决方案的 Roslyn 工作区 API

Roslyn workspace API not loading properly for a third-party solution

提问人:user32882 提问时间:10/31/2023 最后编辑:user32882 更新时间:11/2/2023 访问量:54

问:

我正在尝试使用提供给我的第三方解决方案的 Roslyn Workspace API 枚举每个实例中的所有项目。我的代码如下所示:DocumentProject

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.MSBuild;


string slnPath = "ThirdPartySolution.sln";

MSBuildWorkspace workspace = MSBuildWorkspace.Create();
Solution s = await workspace.OpenSolutionAsync("ThirdPartySolution.sln")
);

foreach (Project p in s.Projects)
{
    Console.WriteLine(p.Name);
    Console.WriteLine(p.Documents.Count());
        
    foreach (Document d in p.Documents)
    {
        Console.WriteLine("\t" + d.Name);
    }
}

workspace.Dispose();

当我使用 .NET Core 生成和运行时,代码运行时没有错误。此外,此解决方案中的项目名称似乎都打印到终端。但是,每个对象中的实例计数始终为 0。我知道情况并非如此,因此我添加了以下代码来尝试诊断问题:DocumentProject

foreach (WorkspaceDiagnostic diagnostic in workspace.Diagnostics)
{
    Console.WriteLine(diagnostic.Message);
}

我收到的诊断消息之一如下:

未找到导入的项目“C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\amd64\Current\Microsoft.Common.props”。 确认导入声明中的表达式“C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\amd64\Current\Microsoft.Common.props”正确,并且该文件存在于磁盘上。
C:\Program Files\dotnet\sdk\6.0.408\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.props

我检查了上述路径是否存在,而确实存在。"C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\amd64\Current\Microsoft.Common.props"C:\Program Files\dotnet\sdk\6.0.408\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.props

我觉得这很奇怪,因为当我从 Visual Studio 2022 的主菜单中选择项目时,解决方案构建良好。它还可以使用 .Buid > Build Solutionmsbuild

这里可能出了什么问题?

编辑

工作方案:

// Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.MSBuild;
using Microsoft.Build.Locator;

string slnPath = "ThirdPartySolution.sln";

MSBuildLocator.RegisterDefaults();

MSBuildWorkspace workspace = MSBuildWorkspace.Create();
Solution s = await workspace.OpenSolutionAsync(slnPath
);

foreach (WorkspaceDiagnostic diagnostic in workspace.Diagnostics)
{
    Console.WriteLine(diagnostic.Message);
}

foreach (Project p in s.Projects)
{
    Console.WriteLine(p.Name);
    Console.WriteLine(p.Documents.Count());
        
    foreach (Document d in p.Documents)
    {
        Console.WriteLine("\t" + d.Name);
    }
}

workspace.Dispose();

除此之外,您必须确保在项目文件中为所有包引用设置了该引用,但以下引用除外:ExcludeAssets="runtime"Microsoft.Build.*Microsoft.Build.Locator

  <ItemGroup>
    <PackageReference Include="Microsoft.Build" Version="17.7.2"
        ExcludeAssets="runtime"/>
    <PackageReference Include="Microsoft.Build.Framework" Version="17.7.2"
        ExcludeAssets="runtime"/>
    <PackageReference Include="Microsoft.Build.Locator" Version="1.6.10" />
    <PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.7.2"
        ExcludeAssets="runtime"/>
    <PackageReference Include="Microsoft.CodeAnalysis" Version="4.7.0" />
    <PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="4.7.0" />
  </ItemGroup>

另请查看链接了解更多详情。

C# MSBuild Roslyn 代码分析

评论

0赞 Jonathan Dodds 10/31/2023
我不熟悉 Roslyn Workspace API,但我猜要在项目中查找文档,请使用 MSBuild(或等效的内部库)来加载项目并执行评估阶段。该项目是否是面向 .NET Framework 的 SDK 样式项目?
0赞 user32882 10/31/2023
该解决方案似乎包含面向 .NET Framework 或 .NET Standard 的 SDK 样式项目
0赞 Jonathan Dodds 10/31/2023
.NET Framework 是 VS 安装程序中“ASP.NET 和 Web 开发”和“.NET 桌面开发”工作负载的必需组件。是否为 Visual Studio 2022 安装了其中一个或两个工作负载? .NET Framework 仅限 Windows,在跨平台 .NET 安装中不可用(即C:\Program Files\dotnet\...)
0赞 user32882 10/31/2023
正如我在 OP 中提到的,我可以在 VS2022 中很好地构建解决方案。这就是你要问的吗?
0赞 Jonathan Dodds 10/31/2023
您尝试解析的项目构建良好,对吗?从 OP 中不清楚您指的是哪个项目。

答:

3赞 Jason Malinowski 11/1/2023 #1

目前(截至 2023 年 10 月撰写本文时),需要先使用 MSBuildLocator 注册 MSBuild 实例,然后才能使用 MSBuildWorkspace。如果尝试分析 SDK 样式项目,还应让应用面向 .NET Core,而不是 .NET Framework。

我强调此答案第一部分的“当前”,因为我实际上正在努力删除此拉取请求中的该要求,因此我希望在 4.9.0 NuGet 包发布时,这将不再是要求,用户的原始代码应该刚刚工作。因此,此问题的任何未来用户,请检查该支持是否已合并到您正在使用的 Roslyn 版本中。

评论

0赞 user32882 11/1/2023
谢谢。我将用我如何让事情工作的全部细节来编辑我的答案
1赞 Jason Malinowski 11/2/2023
@user32882 不错的文章!