强制 Microsoft Build Tools 2015 为框架的目标版本而不是 4.6 包含 mscorlib

Phi*_*Atz 5 c# msbuild mscorlib c#-6.0 .net-4.5.2

我在 Visual Studio 2015 中编写了一个应用程序,它使用 C# 6.0 功能并针对 .NET 4.5.2。当我使用 Microsoft Build Tools 2015 构建它时,这是由我们的 TeamCity 服务器完成的,生成的 bin 文件夹还包含mscorlib.dll. 这里的问题是 mscorlib.dll被复制的是 .NET 4.6 DLL,这会导致运行时出现问题。

我已经用string.Format()新的字符串插值语法替换了我的调用来解决这个问题。然而,这将根本问题推到了地毯下,而不是解决它:为什么 .NET 4.6 DLL 包含在我的构建中,我如何强制将 4.5.2 DLL 包含在它的位置?

如果您对这给我造成的运行时问题感兴趣,它会导致我的:

string.Format(CultureInfo.InvariantCulture, "{0}='{1}'", "key", "value")
Run Code Online (Sandbox Code Playgroud)

被解释为(链接——仅存在于 .NET 4.6 中):

System.String System.String.Format(System.IFormatProvider, System.String, System.Object, System.Object)
Run Code Online (Sandbox Code Playgroud)

而不是(链接):

System.String System.String.Format(System.IFormatProvider, System.String, params System.Object[])
Run Code Online (Sandbox Code Playgroud)

Phi*_*Atz 1

当您在 TeamCity 生成代理上生成解决方案时,TeamCity 使用您在代理上安装的 MSBuild 版本。每个版本的 MSBuild 都是为了构建针对特定版本的 .NET 的 DLL 而创建的。例如,我认为 MSBuild 2015 的目标是 .NET 4.6。

为了使用 MSBuild 2015 构建面向 .NET 4.5.2 的 DLL,您还需要安装所谓的 .NET 4.5.2 目标包(在某些地方也称为开发包):

如果您不安装目标包并尝试使用错误的构建工具针对旧版本的 .NET 进行构建(就像我的情况一样),那么 MSBuild 2015 会尝试通过构建它知道的唯一方式来进行补偿:通过遵循.NET 4.6(无论如何应该向后兼容 4.5.2)并在构建文件夹中放入 .NET DLL ( mscorlib.dll )。

在大多数情况下,这仍然可以正常工作,除了我的代码使用的String.Format()它在 4.5.2 和 4.6 之间发生了非常微妙的重大变化。