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

问题描述 投票:11回答:2

在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中的文档。

.net .net-4.0 version clr
2个回答
0
投票

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

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


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 requiredRuntime语法中常用的语法。更常见的是,supportedRuntime不是运行应用程序所必需的,它只是为了美观。

应用程序运行时真正需要supportedRuntime的一个常见情况是,当我们有针对.NET 2.x-3.x的应用程序并尝试在只有4.x的机器上运行它时(例如,Windows 10有4.6+但是默认情况下没有安装.NET 2.x-3.x)。在这种情况下,如果没有app.config中的supportedRuntime,应用程序根本不会运行,即使4.x与以前的版本大多兼容。添加<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />将解决问题。


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

© www.soinside.com 2019 - 2024. All rights reserved.