遇见最美Windows 11之现代Windows桌面应用开发 - 探索.Net framework和CLR版本关系
背景
托管公共语言运行时(CLR)的所有应用程序都必须启动(或激活)CLR,才能运行托管代码。通常,.NET Framework应用在生成它的CLR版本上运行,但你可以使用应用程序配置文件(有时称为app.config文件)来更改桌面应用程序的此行为。
如果CLR激活系统无法加载应用程序所需运行时的正确版本,它将向用户显示一条错误消息,通知他们,他们的计算机未正确配置,无法运行该应用程序,并为他们提供机会来修复该问题。在此情况下通常会显示以下错误消息。用户可以选择“是”以转到Microsoft网站,从中为应用程序下载正确的.NETFramework版本。
若要解决根本问题并提供最佳用户体验(更少错误消息),建议执行以下操作:
- 对于.NET Framework 3.5(和更低版本)应用程序:将应用程序配置为支持.NET Framework 4或更高版本。
- 对于.NET Framework 4应用程序:安装.NET Framework 4可再发行组件包,作为应用程序安装的一部分。
Windows 8/10/11行为和UI
CLR激活系统在Windows 8/10/11上提供与在其他版本Windows操作系统上一样的行为和UI,除非加载CLR 2.0时遇到问题。Windows 8包括使用CLR 4.5的.NET Framework 4.5。但是,Windows 8不包括.NET Framework 2.0、3.0或3.5,它们都使用CLR 2.0。结果,依赖于CLR 2.0的应用程序默认情况下在Windows 8上不运行。相反,它们将显示下面的对话框,使用户能够安装.NET Framework 3.5。用户还可在“控制面板”中启用.NET Framework 3.5。
安装.NET Framework 3.5后,用户可以在其Windows8计算机上运行依赖于.NET Framework 2.0、3.0或3.5的应用程序。他们还可以运行.NET Framework 1.0和1.1应用程序,前提是这些应用程序未显式配置为仅在.NET Framework 1.0或1.1版上运行。
什么是通用语言运行库CLR
通用语言执行平台(Common Language Runtime
,简称CLR)是微软为.NET的虚拟机所选用的名称。它是微软对通用语言架构(CLI)的实现版本,它定义了一个代码执行的环境。CLR执行一种称为通用中间语言(Common Intermediate Language
,简称CIL)的字节码,这个是微软的通用中间语言实现版本。
CLR的主要功能如下
- 基类库支持(Base Class Library Support)
- 内存管理(Memory Management)
- 线程管理(Thread Management)
- 垃圾回收(Garbage Collection)
- 安全性(Security)
- 类型检查(Type Checker)
- 异常管理(Exception Manager)
- 调试管理(Debug Engine)
- 中间码(MSIL)到机器代码(Native)编译
- 类别装载(Class Loader)
开发人员使用高级编程语言撰写程序。接下来编译器将代码编译成微软的中继语言(MSIL)。执行的时候CLR会将MSIL码转换为操作系统的原生码(Native Code)。CLR内置有"即时编译(Just-in-time compilation)"编译器。
检测已安装.Net Framework版本
检测工具介绍
用户可在他们的计算机上安装和运行.NET Framework的多个版本。当你开发或部署应用时,你可能需要知道用户的计算机上安装了哪些.NET Framework版本。注册表包含计算机上安装的.NET Framework版本列表。
.NET Framework由两个采用不同版本的主要组件构成:
- 一组程序集,它们是为应用提供功能的类型与资源的集合。.NET Framework和程序集使用相同的版本号。例如,.NET Framework版本包括4.5、4.6.1和4.7.2。
- 公共语言运行时(CLR),可管理并执行应用代码。单个CLR版本通常可支持多个.NET Framework版本。例如,CLR版本4.0.30319.xxxxx(其中xxxxx小于42000)支持.NET Framework版本4到4.5.2。大于或等于4.0.30319.42000的CLR版本支持从.NET Framework 4.6开始的.NET Framework版本。
可使用社区维护的工具帮助检测安装了哪些.NET Framework版本:
- .NET Framework 2.0命令行工具 https://github.com/jmalarcon/DotNetVersions
- PowerShell 2.0模块 https://github.com/EliteLoser/DotNetVersionLister
使用DotNetVersions检测
解压后,直接运行DotNetVersions.exe
程序即可。
它会通过终端命令行弹出界面来显示出打印结果,我们便可知道当前系统中已经安装哪些版本了。
使用DotNetVersionLister检测
通过命令行可以直接安装它。
Install-Module -Name DotNetVersionLister -Scope CurrentUser #-Force
安装后,调用命令行来使用它。
Get-STDotNetVersion
或者检测远程计算机的版本
Get-STDotNetVersion -ComputerName $RemoteServerName
通过注册表位置来确认已安装版本
通过Win
+ R
组合来运行regedit
,可进入注册表编辑器,输入如下路径,可以查看到所有.Net framework版本的注册表信息。
计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP
通过v4\Full
路径下子项中Release
的值确定已安装的版本,注册表值和.Net framework版本对应关系如下:
.Net Framework版本 | Release值 |
---|---|
.NET Framework 4.5 | 所有Windows 8 操作系统: 378389 |
.NET Framework 4.5.1 | 在Windows 8.1 和Windows Server 2012 R2 上:378675 在所有其他Windows 操作系统上: 378758 |
.NET Framework 4.5.2 | 所有Windows 操作系统:379893 |
.NET Framework 4.6 | 在Windows 10 1507 上:393295 在所有其他Windows 操作系统上: 393297 |
.NET Framework 4.6.1 | 在Windows 10 11月更新(Windows 10 1511) 系统上:394254 在所有其他Windows 操作系统(包括Windows 10)上: 394271 |
.NET Framework 4.6.2 | 在Windows 10 周年更新(Windows 10 1607) 和Windows Server 2016 上:394802 在所有其他Windows 操作系统(包括其他Windows 10操作系统)上: 394806 |
.NET Framework 4.7 | 在Windows 10 创意者更新(Windows 10 1703) 上:460798 在所有其他Windows 操作系统(包括其他Windows 10操作系统)上: 460805 |
.NET Framework 4.7.1 | 在Windows 10 秋季创意者更新(Windows 10 1709) 和Windows Server版本1709 上:461308 在所有其他Windows 操作系统(包括其他Windows 10操作系统)上: 461310 |
.NET Framework 4.7.2 | 在Windows 10 2018年4月更新(Windows 10 1803) 和Windows Server版本1803 上:461808 在除Windows 10 2018年4月更新和Windows Server版本1803之外的所有Windows 操作系统上: 461814 |
.NET Framework 4.8 | 在Windows 10 2019年5月更新(Windows 10 1903) 和Windows 10 2019年11月更新 上:528040 在 Windows 10 2020年5月更新 、Windows 10 2020年10月更新 和Windows 10 2021年5月更新 上:528372 在 Windows 11 和Windows Server 2022 上:528449 在所有其他Windows 操作系统(包括其他Windows 10操作系统)上: 528049 |
检测已安装CLR版本
可以通过clrver
这个工具检测本机已安装的CLR版本,这个工具不需要单独安装,一般是随Visual Studio安装附带了。
从开始菜单找到Developer Command Prompt for VS 2022
入口,打开它,输入如下命令即可:
clrver
如果要显示当前计算机上的所有使用CLR的进程:
clrver -all
.Net Framework版本与CLR的关系
.NET框架是微软公司继Windows DNA之后的新开发平台。.NET框架是以一种采用系统虚拟机运行的编程平台,以通用语言运行库(Common Language Runtime)为基础,支持多种语言(C#、F#、VB.NET、C++、Python等)的开发。
2014年11月12日,微软宣布将完全开放.NET框架的源代码,并提供给Linux和macOS使用。
.Net Framework版本历史
版本 | 公共语言执行时 | 发布时间 | 随同分发于Visual Studio | 预安装于Windows | 包含之前版本 | ||
---|---|---|---|---|---|---|---|
客户端版 | 服务器版 | ||||||
1.0 | 1.0 | 2002年2月13日 | .NET | 不适用 | 不适用 | 不适用 | |
1.1 | 1.1 | 2003年4月24日 | .NET 2003 | 不适用 | 2003 | ||
2.0 | 2.0 | 2005年11月7日 | 2005 | 不适用 | 2003 R2 | ||
3.0 | 2006年11月6日 | 不适用 | Vista | 不适用 | 2.0 | ||
3.5 | 3.5 | 2007年11月19日 | 2008 | 不适用 | 不适用 | 3.0 SP1 (2.0 SP1) | |
3.5.1 | 2008年2月4日 | 不适用 | 不适用 | 2008 | |||
3.5 SP1 | 2008年8月11日 | 2008 SP1 | 不适用 | 不适用 | 3.0 SP2 (2.0 SP2) | ||
3.5.1 SP1 | 2009年7月22日 | 不适用 | 7 | 2008 R2 | |||
4 | 4.0 | 4.0 | 2010年4月12日 | 2010 | 不适用 | 不适用 | 不适用(置位更新) |
4.5 | 2012年8月15日 | 2012 | 8 | 2012 | |||
4.5.1 | 2013年10月17日 | 2013 | 8.1 | 2012 R2 | |||
4.5.2 | 2014年5月5日 | 不适用 | 不适用 | 不适用 | |||
4.6 | 2015年7月20日 | 2015 | 10 | 不适用 | |||
4.6.1 | 2015年11月30日 | 2015 Update 1 | 10 v1511 | 不适用 | |||
4.6.2 | 2016年8月2日 | 不适用 | 10 v1607 | 2016 | |||
4.7 | 2017年4月5日 | 2017 v15.3 | 10 v1703 | 不适用 | |||
4.7.1 | 2017年10月17日 | 2017 v15.5 | 10 v1709 | v1709 | |||
4.7.2 | 2018年4月30日 | 2019 | 10 v1803 | v1803 | |||
4.8 | 2019年4月18日 | 不适用 | 10 v1909 | v1909 |
针对.NET Framework的可再发行组件包和语言包
- .NET Framework 4.8
- .NET Framework 4.7.2
- .NET Framework 4.7.1
- .NET Framework 4.7
- .NET Framework 4.6.2
- .NET Framework 4.6.1
- .NET Framework 4.6
- .NET Framework 4.5.2
- .NET Framework 4.5.1
- .NET Framework 4.5
- .NET Framework 4.0
- .NET Framework 3.5 SP1
勤学实践
创建解决方案HelloDesktopAppConfig
dotnet new sln -o HelloDesktopAppConfig
cd .\HelloDesktopAppConfig\
explorer.exe .
创建.Net framework项目demoForNetFramework2
选择C#语言
-Windows
平台-桌面
类型,选中Windows窗体应用
模板,创建名为demoForNetFramework2
的项目。
这里框架选定:.Net framework 2.0
创建.Net framework项目demoForNetFramework3
选择C#语言
-Windows
平台-桌面
类型,选中Windows窗体应用
模板,创建名为demoForNetFramework3
的项目。
这里框架选定:.Net framework 3.5
创建.Net framework项目demoForNetFramework4
选择C#语言
-Windows
平台-桌面
类型,选中Windows窗体应用
模板,创建名为demoForNetFramework4
的项目。
这里框架选定:.Net framework 4
创建.Net framework项目demoForNetFramework4.5
选择C#语言
-Windows
平台-桌面
类型,选中Windows窗体应用
模板,创建名为demoForNetFramework45
的项目。
这里框架选定:.Net framework 4.5
我们发现,在demoForNetFramework45
项目中会比之前多出来一个App.config
配置文件。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
创建.Net framework项目demoForNetFramework4.8
选择C#语言
-Windows
平台-桌面
类型,选中Windows窗体应用
模板,创建名为demoForNetFramework48
的项目。
这里框架选定:.Net framework 4.8
我们发现,在demoForNetFramework48
项目中会比之前多出来一个App.config
配置文件。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
</configuration>
查看已有的应用配置文件
从上诉创建结果来看,从.Net framework 4.5
的项目模板开始,Visual Studio就已经内置并在创建项目的时候,添加了应用配置文件App.config
,虽然这里它叫App.config
,但是你会发现编译生成后的对应的文件不叫这个,而是和exe同名的一个config文件,比如编译后得到的程序是demoForNetFramework48.exe
,那么得到的配置文件实际上最终名称和它一一对应,叫做demoForNetFramework48.exe.config
,我们查看Bin下面的文件,这印证了这个说法。
补充新建应用配置文件
对于较老版本的.Net framework
项目而言,创建之后并没有携带应用配置文件,那么我们可以自己来创建一个,在项目上右键-添加-新建项。
在左侧切换到常规-应用程序配置文件,点击添加即可。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
</configuration>
默认得到的是个几乎空白没有意义的XML文件,这时候需要我们自己根据需要填充。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="version"/>
</startup>
</configuration>
其中Version
版本字段,指定与你的应用程序支持的.NET Framework版本匹配的CLR版本。使用以下字符串:
- .NET Framework 1.0:
v1.0.3705
- .NET Framework 1.1:
v1.1.4322
- .NET Framework 2.0、3.0和3.5:
v2.0.50727
- .NET Framework 4及更高版本:
v4.0
并且我们可以通过多组SupportedRuntime
节点来指定对多个.NET Framework版本的支持。
注意书写时需要按优先级顺序写出,优先级高的放置在前面。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
</configuration>
关于
SupportedRuntime
的组合与安装了不同版本.Net framework运行时计算机的对应情况
App.config文件设置 | 在安装了3.5版的计算机上 | 在安装了版本3.5和4或更高版本的计算机上 | 在安装了版本4或更高版本的计算机上 |
---|---|---|---|
None |
在3.5上运行 | 在3.5上运行 | 显示提示用户安装正确版本的错误消息 |
<supportedRuntimeversion="v2.0.50727"/> |
在3.5上运行 | 在3.5上运行 | 显示提示用户安装正确版本的错误消息 |
<supportedRuntimeversion="v2.0.50727"/><supportedRuntimeversion="v4.0"/> |
在3.5上运行 | 在3.5上运行 | 在4或更高版本上运行 |
<supportedRuntimeversion="v4.0"/><supportedRuntimeversion="v2.0.50727"/> |
在3.5上运行 | 在4或更高版本上运行 | 在4或更高版本上运行 |
<supportedRuntimeversion="v4.0"/> |
显示提示用户安装正确版本的错误消息 | 在4或更高版本上运行 | 在4或更高版本上运行 |
允许混合模式程序集加载到更高版本.Net framework
虽然我们可以通过SupportedRuntime
的组合来实现程序对已安装.Net framework版本的灵活选择,但是默认情况下,想要在仅安装.Net framework v4.0及其以上版本环境中继续使用.Net 3.5或者.Net 2.0的程序集是不被允许的。
如需允许.Net framework v4.0及其以上版本运行较低.Net framework版本(如v2.0、v3.5)的程序集,那么可以通过设置Startup
节点的useLegacyV2RuntimeActivationPolicy
属性值为true
,来实现运行的兼容,这意味着在仅有v4.0+的计算机上仍然可以支持较低版本应用程序的运行。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
</configuration>
这对由较低.Net framework版本构建的.Net桌面应用程序实现向前兼容运行非常有用。
总结来说:SupportedRuntime
节点组,主要是帮助程序在同时安装了多个.Net framework(比如3.5&4.0)的版本的计算机环境中去择选更优的运行时版本,而UseLegacyV2RuntimeActivationPolicy
设置成true
,可以让较低.Net framework(比如2.0/3.5)版本构建的桌面程序在仅安装了较高.Net framework(比如4.0/4.5/4.8)版本的计算机环境中兼容运行。
参考
- 公共语言运行时 (CLR) 概述
- .NET Framework 版本和依赖关系
- .NET Framework 概述
- .NET Framework应用的版本兼容性
- 如何:将应用配置为支持 .NET Framework 4 或更高版本
- .NET Framework 初始化错误:管理用户体验
- .NET Framework 部署指南(针对开发人员)
- 启动设置架构
- 启用useLegacyV2RuntimeActivationPolicy的影响?
- .net 4.5兼容4.0?
- 【回答】:Microsoft .NET Framework 各个版本之间的关系?如何安装2.0,3.0,4.0?向下兼容?
- [VS2010].NET4.0环境下使用.NET2.0程序集,出现“混合模式程序集异常”
- 为什么使用useLegacyV2RuntimeActivationPolicy?
- 釐清 CLR、.NET、C#、Visual Studio、ASP.NET 各版本之間的關係
- Microsoft Developer Blogs
- What is the difference between .NET Framework and CLR Version
- .NET Framework version history
- .NET Framework For Version
- Microsoft .NET Framework 以及 CLR 的版本
- Installation C# application without dot net framework
- .NET Versioning and Multi-Targeting - .NET 4.5 is an in-place upgrade to .NET 4.0
- .NET Framework版本与CLR版本之间的关系
- Does the .Net Framework 4.0 Installer include the .Net Framework 3.5?
- Running .NET 3.5 apps on .NET 4 only systems
- 即时编译
- DotNetVersionLister
- DotNetVersions
- HTML cleanup tool
- .NET框架
- 适用于程序集加载的最佳做法
- 各个版本Windows系统中自带的.NET Framework版本
- Clrver.exe(CLR 版本工具)