msbuild - MSBuildWorkspace 无法编译项目到另一个项目
问题描述
注意我也在Roslyn 的 GitHub 上问过这个问题(带有复制代码)
- 使用 2 个项目(CoreLibrary 和 DownstreamLibrary)创建一个新的解决方案。
- 将 DownstreamLibrary 中的项目引用添加到 CoreLibrary。
- 运行以下代码并注意 DownstreamLibrary 不再编译。
请注意,我已经尝试将 net461、netcoreapp2.1 和 netstandard2.0 作为项目的目标框架——每次都出现同样的问题。
static async Task Main(string[] args)
{
MSBuildLocator.RegisterDefaults();
using (var workspace = MSBuildWorkspace.Create())
{
workspace.WorkspaceFailed += (sender, workspaceFailedArgs) => WriteLine(workspaceFailedArgs.Diagnostic.Message);
var solution = await workspace.OpenSolutionAsync(@"c:\source\ForRoslynTest\ForRoslynTest.sln");
WriteLine($"Loaded solution {solution.FilePath}");
var projectTree = workspace.CurrentSolution.GetProjectDependencyGraph();
foreach (var projectId in projectTree.GetTopologicallySortedProjects())
{
await CompileProject(workspace.CurrentSolution.GetProject(projectId));
}
}
}
private static async Task CompileProject(Project project)
{
WriteLine($"Compiling {project.Name}. It has {project.MetadataReferences.Count} metadata references.");
var compilation = await project.GetCompilationAsync();
var errors = compilation.GetDiagnostics().Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error);
if (errors.Any())
{
WriteLine($"COMPILATION ERROR: {compilation.AssemblyName}: {errors.Count()} compilation errors: \n\t{string.Join("\n\t", errors.Where(e => false).Select(e => e.ToString()))}");
}
else
{
WriteLine($"Project {project.Name} compiled with no errors");
}
}
您将收到以下输出:
Msbuild failed when processing the file 'c:\source\ForRoslynTest\DownstreamLibrary\DownstreamLibrary.csproj' with message: C:\Program Files\dotnet\sdk\2.1.602\Microsoft.Common.CurrentVersion.targets: (1548, 5): The "Microsoft.Build.Tasks.ResolveNonMSBuildProjectOutput" task could not be loaded from the assembly Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a. Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.
Found project reference without a matching metadata reference: c:\source\ForRoslynTest\CoreLibrary\CoreLibrary.csproj
Loaded solution c:\source\ForRoslynTest\ForRoslynTest.sln
Compiling CoreLibrary. It has 113 metadata references.
Project CoreLibrary compiled with no errors
Compiling DownstreamLibrary. It has 0 metadata references.
COMPILATION ERROR: DownstreamLibrary: 3 compilation errors:
c:\source\ForRoslynTest\DownstreamLibrary\Class1.cs(1,7): error CS0246: The type or namespace name 'System' could not be found (are you missing a using directive or an assembly reference?)
c:\source\ForRoslynTest\DownstreamLibrary\Class1.cs(5,18): error CS0518: Predefined type 'System.Object' is not defined or imported
c:\source\ForRoslynTest\DownstreamLibrary\Class1.cs(5,18): error CS1729: 'object' does not contain a constructor that takes 0 arguments
所以我的问题是如何修复上述错误并让 DownstreamLibrary 进行编译?
编辑 我 99% 确定根本原因是这个错误
无法从程序集 Microsoft.Build.Tasks.Core 加载“Microsoft.Build.Tasks.ResolveNonMSBuildProjectOutput”任务,版本 = 15.1.0.0
我已经用 procmon 确认它正在加载以下 DLL (C:\Program Files\dotnet\sdk\2.1.602\Microsoft.Build.Tasks.Core.dll),我用 ILSpy 确认了它没有ResolveNonMSBuildProjectOutput里面的任务。此 DLL 的旧版本确实有此任务。
解决方案
我找到了此 WorkspaceFailed 错误的手动解决方法:
[失败] 处理 with 消息时 Msbuild 失败:无法从程序集 Microsoft.Build.Tasks.Core 加载“Microsoft.Build.Tasks.ResolveNonMSBuildProjectOutput”任务,版本=15.1.0.0,文化=中性,PublicKeyToken=b03f5f7f11d50a3a . 确认声明正确,程序集及其所有依赖项都可用,并且任务包含实现 Microsoft.Build.Framework.ITask 的公共类。
有几个解决步骤:
- 在https://github.com/microsoft/msbuild/issues/4770之后,我将 VS 2019 从 16.2 更新到 16.5.3 ...这并没有解决我的错误,但值得记录我这样做。
- 我将我的 Microsoft.Build.* 和 Microsoft.CodeAnalysis 依赖项升级到最新版本,这还没有解决问题,同样的错误。
- 我导航到以前有几个目录的 C:\Program Files\dotnet\sdk:
1.0.0/ 1.0.0-rc4-004771/ 2.0.3/ 2.1.505/
1.0.0-preview1-002702/ 1.0.3/ 2.1.202/ 3.1.100/
1.0.0-preview2-003121/ 1.0.4/ 2.1.4/ 3.1.201/
1.0.0-preview4-004233/ 1.1.0/ 2.1.502/ NuGetFallbackFolder/
- 我将其重命名为 sdk_o 并创建了一个新文件夹 C:\Program Files\dotnet\sdk,仅复制到 3.1.201/
成功!这个错误消失了,但是运行我的 roslyn 应用程序然后导致一些错误,比如(路径被剥离)
[失败] 处理文件时 Msbuild 失败,消息“ProcessFrameworkReferences”任务意外失败。System.IO.FileNotFoundException:无法加载文件或程序集“NuGet.Frameworks,版本=5.5.0.4,文化=中性,PublicKeyToken=31bf3856ad364e35”。该系统找不到指定的文件。文件名:'NuGet.Frameworks,版本=5.5.0.4,文化=中性,PublicKeyToken=31bf3856ad364e35'
通过将 NuGet.ProjectModel 5.5.1 添加到我的项目中解决了这个问题,csproj 现在具有以下包引用:
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="16.5.0" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Framework" Version="16.5.0" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Locator" Version="1.2.6" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="16.5.0" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.CodeAnalysis" Version="3.5.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.5.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="3.5.0" />
<PackageReference Include="NuGet.ProjectModel" Version="5.5.1" />
</ItemGroup>
此代码不再有 WorkspaceFailed 事件:
Microsoft.Build.Locator.MSBuildLocator.RegisterDefaults();
var workspace = MSBuildWorkspace.Create();
workspace.WorkspaceFailed += (s, e) => { Console.WriteLine(e.Diagnostic); };
var project = await workspace.OpenProjectAsync(@"C:/path/to.csproj");
我使用 Roslyn 加载的 csproj 如下所示:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<OutputType>Library</OutputType>
<ApplicationIcon />
<StartupObject />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\dependencies\some.csproj" />
</ItemGroup>
</Project>
推荐阅读
- hibernate - 使用 Hibernate 将实体映射到表时出现 BeanCreationException
- javascript - 移除显示:在@media 大小之间更改时无
- openscenegraph - 多渲染目标 (MRT) 和 OSG
- javascript - Ajax 调用 - 数据未加载到我的数据库中
- html - 使用 HTML5 Canvas 裁剪图像位置
- c++ - Qt Creator 无法在 Ubuntu 上解析 gvContext
- rest - 非奇异资源下的资源是否仍然是 RESTful?
- git - Gradle 更新 git 子模块
- python - 如何创建时间属性?
- typescript - 泛型函数的Typescript ReturnType