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

.net 何时以及为什么需要supportedRuntime元素和sku属性?,.net,.net-4.0,version,clr,.net,.net 4.0,Version,Clr,在Visual Studio中创建的大多数(如果不是全部的话)C#(以及F#和VB)库和可执行项目中,有一个自动添加的app.config文件指定运行时版本和目标框架名字对象(TFM): .csproj文件确实指定了目标框架,我猜这就是目标在构建期间从on传递到编译器的地方 如果配置文件中没有部分,可执行文件似乎运行正常。解释了属性的含义,但是,多年来我一直无法理解为什么配置文件中需要这些属性。不过,我主要处理的是Windows桌面应用程序 明确声明“不可能让编译为目标.NET 4.0的程序像在

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

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

如果配置文件中没有
部分,可执行文件似乎运行正常。解释了属性的含义,但是,多年来我一直无法理解为什么配置文件中需要这些属性。不过,我主要处理的是Windows桌面应用程序

明确声明“不可能让编译为目标.NET 4.0的程序像在更高版本上运行一样运行”,如果相反,在更低版本的框架上运行程序也是可能的,我会非常惊讶

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



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

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


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

需要声明您的应用程序实际上与哪些框架版本兼容。假设我们有一个以.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将显示一条漂亮的错误消息,要求安装所需的框架版本:

如果我们省略app.config,Windows将尝试运行它,然后应用程序将在第一次遇到特定于.NET Framework 4.7.2的功能时崩溃,而该功能在已安装的Framework版本中不存在

请注意,文档中说“所有使用.NET Framework 1.1版或更高版本构建的应用程序都应使用此元素”是误导性的。它可能被解释为“此元素是应用程序在.NET 1.1+上运行所必需的”,而实际上它只意味着.NET 1.1更改了以前在.NET 1.0
requiredRuntime
语法中使用的语法。通常情况下,应用程序不需要运行not
supportedRuntime
,这只是为了美观

当应用程序运行所需的
supportedRuntime
时,一种常见的情况是,我们将应用程序定位为.NET 2.x-3.x,并尝试在只有4.x的计算机上运行它(例如,Windows 10有4.6+,但默认情况下没有安装.NET 2.x-3.x)。在这种情况下,如果app.config中没有
supportedRuntime
,应用程序将无法运行,即使4.x与以前的版本基本兼容。添加
将解决此问题



因此,总而言之,它并没有复制程序集元数据中的信息,而是为Windows提供了有关如何将应用程序与它兼容的框架版本连接的其他信息,以及如果目标计算机上没有该应用程序,则要求用户安装哪个版本的信息。

在我看来,该设计似乎是“为未来保留某些东西”. 硬编码到二进制文件中的信息是不可能更改的,但有时Microsoft可能需要向开发人员提供一种方法来更改运行时行为(我无法说出具体的情况,但运行时版本相关的行为在.NET Framework中很常见),他们可以在
app.config
(在这种情况下,两者不再重复)。“supportedRuntime是[…]应用程序运行所需的时间,是当我们将应用程序定位为.NET 2.x-3.x并尝试在只有4.x的计算机上运行它时”——这很了不起。看起来app.config中的属性覆盖了程序集级属性(假设旧工具还嵌入了TargetFrameworkAttribute)。下载提示的行为令人费解;看起来初始的exe加载过程(对我来说真的很神秘)从app.config中选择目标版本,但忽略了同一程序集中的TargetFrameworkAttribute。有趣的设计决策…
.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
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/></startup></configuration>