kkm*_*kkm 11 .net clr version .net-4.0
在Visual Studio中创建的大多数(如果不是全部)C#(和F#和VB)库和可执行项目中,都有一个自动添加的app.config
文件,它指定运行时版本和目标框架名字对象(TFM):
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
. . .
Run Code Online (Sandbox Code Playgroud)
即使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
Run Code Online (Sandbox Code Playgroud)
该.csproj
文件确实指定了目标框架,我猜这是目标在构建期间从编译器传递到编译器的位置.
如果没有<startup>
配置文件中的部分,可执行文件似乎运行得很好.文档解释了什么做的属性意味着,但是,看到他们很多年了,我永远无法理解为什么他们需要在配置文件中 不过,我主要处理Windows的桌面应用程序.
这个答案明确指出"使编译为目标.NET 4.0的程序行为就像它在更高版本上运行一样是不可能的",如果反过来说,在框架的较低版本上运行程序也会让我感到非常惊讶可能.
那么,在什么情况下,应用程序开发人员需要在应用程序的.config
文件中指定运行时的版本和TFM ,并且是否必须始终复制编译器硬编码到二进制文件中的信息?这项要求乍一看似乎违反直觉.
更新2018-06-29:X-ref:我要求澄清GitHub问题dotnet/docs#6234中的文档.
需要声明您的应用程序实际上与哪些框架版本兼容。假设我们有一个面向 .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>
Run Code Online (Sandbox Code Playgroud)
Windows 将显示一条不错的错误消息,要求安装所需的框架版本:
如果我们省略 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,应用程序将根本无法运行,即使 4.x 基本上与以前的版本兼容。添加将解决该问题。supportedRuntime
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
因此,总而言之,它不会复制程序集元数据中的信息,而是为 Windows 提供有关如何将应用程序与其兼容的框架版本连接的附加信息,以及如果目标计算机上不存在则要求用户安装哪个版本。