若要确保应用程序的编程生成与在 Visual Studio 或 MSBuild.exe中完成的生成匹配,可能需要加载与特定版本的 Visual Studio 一起安装的相同版本的 MSBuild 程序集,并使用该版本的 Visual Studio 中可用的相同 SDK。 或者,在创建将在可能安装了各种版本的 MSBuild、.NET 和 Visual Studio 的计算机上运行的生成应用程序时,可能还需要查找和使用 MSBuild 的一致版本。 Microsoft.Build.Locator API 简化了此过程。
使用 Microsoft.Build.Locator
Microsoft.Build.Locator 包与以下情况相关:应用程序在客户端计算机、虚拟机或容器上运行,其中安装了 Visual Studio,或所处环境下仅安装了 Visual Studio 生成工具,或者仅安装了 .NET SDK,例如使用 dotnet build
命令行请求生成时。 在任何情况下,应用程序都需要找到所需的 MSBuild 版本。 该版本的 MSBuild 可以是与 Visual Studio、MSBuild.exe或 dotnet build
匹配的版本,也可以是特定的一致版本,无论使用应用程序的环境中的不同计算机配置如何。
警告
Microsoft.Build.Locator 包包含适用于 .NET Framework 和 .NET Core 的程序集(也适用于 .NET 5 及更高版本)。 在 .NET Framework 应用程序中,使用 Microsoft.Build.Locator 的 .NET Framework 版本,并在 .NET Core 应用程序中使用 .NET Core 版本。 但是,.NET Core 版本只能查找使用 .NET Core 生成的 MSBuild 实例,即 .NET SDK 安装中 dotnet.exe
使用的 MSBuild 实例,而不是 Visual Studio 安装或 Visual Studio 生成工具安装。 Microsoft.Build.Locator 的 .NET Framework 版本只能看到 Visual Studio 安装、Visual Studio 生成工具安装,而不是 .NET SDK 安装。 因此,可能需要在两个不同的目标框架配置中生成一个工具来针对两者。
如果使用应用程序重新分发 Microsoft.Build.Locator.dll,则无需分发其他 MSBuild 程序集。
使用定位符 API 需要在项目中进行一些更改,如下所述。 若要查看更新项目所需更改的示例,请参阅在 MSBuildLocator 存储库中对示例项目进行的提交。
更改 MSBuild 引用
若要确保 MSBuild 从中心位置加载,您不得随您的应用程序一起分发其程序集。
更改项目以避免从中心位置加载 MSBuild 的机制取决于引用 MSBuild 的方式。
使用 NuGet 包(首选)
这些说明假定用户使用 PackageReference 样式 NuGet 引用。
将项目文件更改为从 NuGet 包中引用 MSBuild 程序集。 指定 ExcludeAssets=runtime
以告知 NuGet 程序集仅在构建时需要,不应将它们复制到输出目录。
MSBuild 包的主版本和次要版本必须小于或等于你希望支持的 Visual Studio 的最低版本。 例如,如果要支持 Visual Studio 2017 及更高版本,请引用包版本 15.1.548
。
例如,可以使用以下 XML:
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="15.1.548" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.1.548" ExcludeAssets="runtime" />
</ItemGroup>
使用扩展程序集
如果无法使用 NuGet 包,则可以引用随 Visual Studio 一起分发的 MSBuild 程序集。 如果直接引用 MSBuild,请确保它不会复制到输出目录,方法是将 Copy Local
设置为 False
。 在项目文件中,此设置类似于以下代码:
<Reference Include="Microsoft.Build, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
备注
如果要从 15 之前的 MSBuild 版本更新,MSBuild 需要某些程序集(Microsoft.Build
程序集)的绑定重定向,但如果引用 Microsoft.Build.Locator
包,请确保应用程序自动使用所需的绑定重定向到版本 15.1.0.0。 此版本的绑定重定向支持 MSBuild 15.x、16.x 和 17.x。
确保输出干净
生成项目并检查输出目录,以确保它不包含除将在下一步添加的 Microsoft.Build.Locator.dll
以外的任何 Microsoft.Build.*.dll
程序集。
为 Microsoft.Build.Locator 添加包引用
为 Microsoft.Build.Locator添加 NuGet 包引用。
<PackageReference Include="Microsoft.Build.Locator">
<Version>1.1.2</Version>
</PackageReference>
不要为 Microsoft.Build.Locator 包指定 ExcludeAssets=runtime
。
在调用 MSBuild 之前注册实例
在为一般用途创建构建应用程序时,您无法确定您的应用程序所在的计算机上安装了哪些版本的 Visual Studio、.NET 和 MSBuild。 MSBuildLocator 的目的是查找在具有不同安装环境的计算机上使用的 MSBuild 的适当安装。 MSBuildLocator 允许你指定一些逻辑来确定要使用的 MSBuild,但作为应用程序的开发人员需要确定它需要或可以接受哪些 MSBuild 版本,或者为用户指定版本提供一种方法,并包括逻辑,将该选择转换为对 MSBuildLocator API 的相应调用。
向定位符 API 添加调用的最简单方法是在应用程序启动代码中添加对 MSBuildLocator.RegisterInstance
的调用。 一个示例是选取最新版本,如下所示,但应用程序可能具有自己的要求。
不能在调用 MSBuildLocator 的方法中引用任何 MSBuild 类型(从 Microsoft.Build
命名空间)。 例如,不能使用如下所示的代码:
void ThisWillFail()
{
// Register the most recent version of MSBuild
RegisterInstance(MSBuildLocator.QueryVisualStudioInstances().OrderByDescending(
instance => instance.Version).First());
Project p = new Project(SomePath); // Could be any MSBuild type
// Code that uses the MSBuild type
}
而是编写如下所示的代码:
void MethodThatDoesNotDirectlyCallMSBuild()
{
var instance = ... // select which of the installed instances to use
// Register a specific instance of MSBuild
MSBuildLocator.RegisterInstance(instance);
MethodThatCallsMSBuild();
}
void MethodThatCallsMSBuild()
{
Project p = new Project(SomePath);
// Code that uses the MSBuild type
}
若要指定 MSBuild 实例,可以选择使用所需的自定义逻辑将 MSBuildLocator.QueryVisualStudioInstances
传递给 MSBuildLocator.RegisterInstance
的结果。
相关内容
通过查阅 MSBuild API 参考资料,以便更好地了解 MSBuild API。