我何时以及为什么需要supportedRuntime元素和sku属性?

时间:2017-11-15 03:35:32

标签: .net .net-4.0 version clr

在Visual Studio中创建的大多数(如果不是全部)C#(和F#和VB)库和可执行项目中,有一个自动添加的app.config文件,它指定运行时版本和目标框架名字对象(TFM):

<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
. . .

即使完全没有app.config文件,编译器似乎总是生成一个程序集级属性,正如ILDASM所示:

.custom instance void [mscorlib]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) = ( 01    // ....NETFramework
                                                                                                      ..    // ,Version=v4.6.1.
                                                                                      bytes snipped-> ..    // .T..FrameworkDis
                                                                                                      ..    // playName..NET Fr
                                                                                                      61  ) // amework 4.6.1

.csproj文件确实指定了目标框架,我猜这是目标在构建期间从编译器传递到编译器的地方。

如果没有配置文件中的<startup>部分,可执行文件似乎运行正常。 The documentation解释属性意味着什么,但是,多年来看到它们,我从未理解配置文件中需要为什么。不过,我主要处理Windows的桌面应用程序。

This answer明确指出“将程序编译为目标.NET 4.0的行为就像在较高版本上运行一样是不可能的”,如果反过来在较低版本上运行程序,我会感到非常惊讶该框架的版本也是可能的。

因此,在什么情况下,应用程序开发人员需要在应用程序的.config文件中指定运行时的版本和TFM,并且它必须始终复制由硬编码到二进制文件中的信息。编译器?这个要求一见钟情似乎违反直觉。

更新2018-06-29:X-ref:我要求澄清GitHub问题dotnet/docs#6234中的文档。

2 个答案:

答案 0 :(得分:0)

targetFramework 属性主要确定用于编译目的的.NET Framework。它还用于确定引用.NET库(DLL)的兼容性。但是,当您将.NET项目作为应用程序分发并将其部署到其他计算机上时,会出现一个问题。问题是“如果目标计算机未安装在编译过程中使用的.NET Framework版本,会发生什么情况?”。这就是 supportedRuntime 元素的重要意义。 supportedRuntime 元素列表中匹配的第一个版本将用于运行该应用程序。如果 supportedRuntime 元素中的所有版本均与目标计算机上已安装的版本都不匹配,则将使用该框架的最新版本来运行该应用程序。

我希望这个解释能回答您的问题。

答案 1 :(得分:0)

需要声明您的应用程序实际上与哪些框架版本兼容。假设我们有一个针对.NET Framework 4.7.2的应用程序,并尝试在仅安装.NET Framework 4.5的计算机上运行它。如果我们添加此app.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/></startup></configuration>

Windows将显示一个不错的错误消息,要求安装所需的框架版本:

error message

如果我们省略了app.config,Windows将尝试运行该应用程序,然后应用程序在其首次遇到.NET Framework 4.7.2的特定功能且已安装的框架版本中缺少该功能时,它将崩溃。

请注意,文档的误导性在于:“ 此元素应由使用.NET Framework 1.1版或更高版本构建的所有应用程序使用”。它可能被解释为“ 该元素是应用程序在.NET 1.1+上运行所必需的”,而实际上,这仅意味着.NET 1.1更改了以前在.NET 1.0中使用的语法。{{ 1}}语法。这样一来,运行应用程序就不需要requiredRuntime了,只是为了美观。

运行应用程序需要确实的一种常见情况是:我们具有面向.NET 2.x-3.x的应用程序并尝试在具有.NET 2.x-3.x的计算机上运行仅4.x(例如,Windows 10具有4.6+,但默认情况下未安装.NET 2.x-3.x)。在这种情况下,即使app.config中没有supportedRuntime,该应用程序也将无法运行,即使4.x与以前的版本基本兼容。添加supportedRuntime将解决此问题。


因此,总而言之,它不会在程序集元数据中复制信息,而是为Windows提供有关如何将应用程序与兼容版本的框架版本连接以及要求用户安装哪个版本(如果不存在)的附加信息。在目标计算机上。