提问人:user32882 提问时间:10/31/2023 最后编辑:user32882 更新时间:11/2/2023 访问量:54
未正确加载第三方解决方案的 Roslyn 工作区 API
Roslyn workspace API not loading properly for a third-party solution
问:
我正在尝试使用提供给我的第三方解决方案的 Roslyn Workspace API 枚举每个实例中的所有项目。我的代码如下所示:Document
Project
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。我知道情况并非如此,因此我添加了以下代码来尝试诊断问题:Document
Project
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 Solution
msbuild
这里可能出了什么问题?
编辑
工作方案:
// 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>
另请查看此链接了解更多详情。
答:
目前(截至 2023 年 10 月撰写本文时),需要先使用 MSBuildLocator 注册 MSBuild 实例,然后才能使用 MSBuildWorkspace。如果尝试分析 SDK 样式项目,还应让应用面向 .NET Core,而不是 .NET Framework。
我强调此答案第一部分的“当前”,因为我实际上正在努力删除此拉取请求中的该要求,因此我希望在 4.9.0 NuGet 包发布时,这将不再是要求,用户的原始代码应该刚刚工作。因此,此问题的任何未来用户,请检查该支持是否已合并到您正在使用的 Roslyn 版本中。
评论
C:\Program Files\dotnet\...
)