所以原来的问题Microsoft.Build.Evaluation 的正确用法是什么?有以下可接受的答案:
project = new Project(projectPath, new Dictionary<string, string>(), "12.0", new ProjectCollection());
Run Code Online (Sandbox Code Playgroud)
这在 2021 年不适用于 NuGet 包 Microsoft.Build 16.8.0。
我想评估一个非 SDK 风格的项目,如下所示:
project = new Project(projectPath, new Dictionary<string, string>(), "12.0", new ProjectCollection());
Run Code Online (Sandbox Code Playgroud)
请注意:
尝试1
new Project(projectPath, new Dictionary<string, string>(), "16.0", new ProjectCollection());
Run Code Online (Sandbox Code Playgroud)
结果是:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
...
<Import Project="..\..\..\Tools\MSBuild\Dayforce.targets" />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
Run Code Online (Sandbox Code Playgroud)
尝试2
new Project(projectPath, new Dictionary<string, string>(), "Current", new ProjectCollection());
Run Code Online (Sandbox Code Playgroud)
结果是:
new Project(projectPath, new Dictionary<string, string>(), "16.0", new ProjectCollection());
Run Code Online (Sandbox Code Playgroud)
尝试3
new Project(projFilePath, new Dictionary<string, string>
{
["MSBuildExtensionsPath"] = @"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild",
}, "Current", new ProjectCollection());
Run Code Online (Sandbox Code Playgroud)
结果是:
Microsoft.Build.Exceptions.InvalidProjectFileException: The tools version "16.0" is unrecognized. Available tools versions are "Current".
Run Code Online (Sandbox Code Playgroud)
我们正在取得进展,Microsoft.Common.props 似乎已导入,现在我们在上次导入时失败 - Microsoft.CSharp.targets
尝试4
new Project(projFilePath, new Dictionary<string, string>
{
["MSBuildExtensionsPath"] = @"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild",
["MSBuildBinPath"] = @"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin",
}, "Current", new ProjectCollection());
Run Code Online (Sandbox Code Playgroud)
但结果是:
new Project(projectPath, new Dictionary<string, string>(), "Current", new ProjectCollection());
Run Code Online (Sandbox Code Playgroud)
那么,我错过了什么?
我设法做了我想做的事。但是,没有一个Microsoft.BuildNuGet 包能够按我的预期工作。我检查了所有已发布的版本。
对我有用的是引用 VS 2019 安装目录中找到的 Microsoft.Build Dlls。这是我的项目文件:
Microsoft.Build.Exceptions.InvalidProjectFileException: The imported project "C:\work\CSTool\CSTool\bin\Debug\netcoreapp3.1\Current\Microsoft.Common.props" was not found. Confirm that the expression in the Import declaration "C:\work\CSTool\CSTool\bin\Debug\netcoreapp3.1\Current\Microsoft.Common.props" is correct, and that the file exists on disk.
Run Code Online (Sandbox Code Playgroud)
这是有效的代码:
var project = new Project(projFilePath);
foreach (var compileItem in project.AllEvaluatedItems.Cast<ProjectItem>().Where(item => item.ItemType == "Compile"))
{
var filePath = compileItem.EvaluatedInclude;
...
}
Run Code Online (Sandbox Code Playgroud)
我检查了msbuild github 存储库- 它也不使用 NuGet 包。相反,它包含所有相关库的源代码并只是构建它们。这些 dll 的工作方式也与 VS dll 的工作方式相同。
那么,NuGet 包有什么用呢?我不明白这一点。打开https://github.com/dotnet/msbuild/issues/6147
小智 5
关于加载项目文件存在一个未解决的问题,该文件解释了 net5 和 net6 的当前 caviats。https://github.com/dotnet/msbuild/issues/3434#issuecomment-774280523
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="17.3.2" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Locator" Version="1.5.5" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.4.0" ExcludeAssets="runtime" />
</ItemGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)
using Microsoft.Build.Evaluation;
using Microsoft.Build.Locator;
class Program
{
const string ProjectPath = @"C:\tmp\project.csproj";
private static void Main(string[] args)
{
MSBuildLocator.RegisterDefaults();
LoadProject();
}
private static void LoadProject()
{
var buildEngine = new ProjectCollection();
var project = buildEngine.LoadProject(ProjectPath);
Console.WriteLine($"OutputType: {project.GetPropertyValue("OutputType")}");
Console.WriteLine($"TargetFramework: {project.GetPropertyValue("TargetFramework")}");
}
Run Code Online (Sandbox Code Playgroud)
请注意,MSBuild API 的首次使用必须在单独的方法中进行,否则 JIT 将在注册 MSBuildLocator 之前尝试解析 Microsoft.Build.dll。
在net6中似乎需要“MSBuildLocator.RegisterDefaults()”,但在net5中不需要。
我没有像其他人提到的那样设置MSBUILD_EXE_PATH。
| 归档时间: |
|
| 查看次数: |
2342 次 |
| 最近记录: |