我目前正在尝试在我自己的程序的运行时执行期间编译解决方案。这个解决方案是用户定义的,必须支持任意数量的项目,并且在这些项目中用户想要添加的任何 nuget 依赖项。例如,具有如下定义的单个 C# 项目的解决方案:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="xunit" Version="2.4.1" />
</ItemGroup>
</Project>
如果用户决定在他们的代码中使用 xunit 或 Newtonsoft.Json 类,则应该编译。
我目前正在按照以下步骤编译项目:
using var workspace = MSBuildWorkspace.Create();
var solution = await workspace.OpenSolutionAsync(solutionPath, cancellationToken: token);
foreach (var project in solution.Projects)
{
var compilation = await project.GetCompilationAsync(token);
// handle compilation
}
我面临的问题是 MSBuild 似乎没有解析所有 nuget 引用。这很奇怪,因为可以使用
Newtonsoft.Json
,并且使用提示路径添加对 dll 的引用也可以。但是,xunit
永远不会被解析,编译失败并显示找不到命名空间Xunit
的消息。 compilation.References
只显示系统引用以及出于某种原因总是 Newtonsoft.Json,即使它没有被引用。 workspace.Diagnostics
是空的,我很茫然
如何让 MSBuild 包含我的用户将引用的 nuget 包?
问题是当您调用
GetCompilationAsync
时,Roslyn 不会恢复您的项目。不幸的是,没有简单的方法可以使用 MSBuildWorkspace API 恢复您的项目。幸运的是,Microsoft.Build
NuGet 包就是答案。
确保从您首先使用
Microsoft.Build.*
dll 中定义的类的不同函数调用 MSBuildLocator,否则您将获得 FileNotFoundException,因为尚无法为您的程序找到 DLL。之后,我使用了SolutionFile.Parse
,遍历了那里的每个项目,并使用了来自 Roslyn this 类的“深受启发”的代码,以便以 Restore
的目标步骤调用 MSBuild。这样做之后,我创建了我的 MSBuildWorkspace,打开了解决方案,现在每次更新项目的依赖项时编译都会成功。
如果有人知道更简单的方法,请告诉我