.NET 4.5.2 应用程序如何在仅安装 4.5.1 的构建服务器上编译?

How can a .NET 4.5.2 app still compile on a build server with only 4.5.1 installed?

这让我完全莫名其妙。我正在测试将我们的构建基础设施升级到 .NET 4.5.2,目前在 .NET 4.5.1 上。

我的第一步是在我的面向 .NET 4.5.2 的开发机器上创建一个 ASP.NET MVC 项目。我正在使用 VS 2013 并安装了 4.5.2 Developer Pack。我使用仅在 .NET 4.5.2 中支持的方法编写了一些多余的代码:

public ActionResult Index()
{
    if (!Response.HeadersWritten)
        Response.AddOnSendingHeaders((c) => { c.Response.AddHeader("Foo", "Bar"); });

    return View();
}

Response.HeadersWritten and Response.AddOnSendingHeaders仅在System.Web.dll的.NET 4.5.2版本中引入。正如预期的那样,这在本地编译得很好。

在将构建服务器升级到 4.5.2 之前,我想我只是 运行 从源代码管理在构建服务器上构建上述项目,然后看到它失败了。但是构建成功完成,仅报告以下警告:

The reference assemblies for framework ".NETFramework,Version=v4.5.2" were not found. To resolve this, install the SDK or Targeting Pack for this framework version or retarget your application to a version of the framework for which you have the SDK or Targeting Pack installed. Note that assemblies will be resolved from the Global Assembly Cache (GAC) and will be used in place of reference assemblies. Therefore your assembly may not be correctly targeted for the framework you intend.

我将已编译的二进制文件从 drop 下载到我的本地机器,应用 运行 没问题,并添加了 foo header.

这个4.5.2代码是如何编译的!没有本地引用 System.Web 检查到正在构建的源代码中,也没有通过 nuget 包等引入任何内容。

如果您的应用没有使用 v4.5.2 特有的任何内容(或者被淘汰或以破坏性方式更改),您应该是好的。

当然,也可能是 B^) 您只是没有遇到事情向南发展的特定执行路径。

此外,人们可能会注意到 4.5.2 was an in-place update to 4.x family,因此无论您 运行 是什么 4.x 版本,您都会获得相同的 DLL。运行。

我已将其追踪到构建期间引用的 GAC 中的 System.Web.dll 版本。尽管所有文档都指出 Response.HeadersWrittenResponse.AddOnSendingHeaders 仅在 .NET 4.5.2 中引入,但 .NET 4.5/4.5.1 的以下安全更新安装了 System.Web.dll 版本到包含这些方法的 GAC:

https://support.microsoft.com/en-us/kb/2894854

这就解释了编译仍然成功的原因。当强制编译目标 4.5.1 时,使用 /p:TargetFrameworkVersion=v4.5.1 msbuild 开关,System.Web.dll 引用是从以下位置提取的旧版本,它不包含这些方法,因此无法编译为预期:

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Web.dll