混合模式程序集是针对,版本之上

作者: 仪器仪表  发布:2019-10-07

本文转载   https://walterlv.github.io/dotnet/2017/09/22/dotnet-version.html ,感谢  吕毅 (包含链接: https://walterlv.github.io )

今天在把以前写的代码生成工具从原来的.NET3.5升级到.NET4.0,同时准备进一步完善,将程序集都更新后,一运行程序在一处方法调用时报出了一个异常:

每个版本的 .NET framework 都包含公共语言运行时 (CLR)、基类库和其他托管库。 本主题按版本介绍了 .NET Framework 的关键功能,提供了有关基础 CLR 版本和相关开发环境的信息,并标识了 Windows 操作系统所安装的版本。

当我们编译程序目标框架选为 .Net Framework 4.5/4.6/4.7 时,CLR 运行时是如何判断我们究竟应该用哪一个 .Net Framework 呢?.Net Framework 的版本到底由哪些部分组成?我们编译 .Net Framework 时选择的版本决定了什么?

 

每个新版本的 .NET Framework 都会保留早期版本中的功能并会添加新功能。 CLR 由其自己的版本号确定的。 虽然 CLR 版本不总是递增,但是 .NET Framework 版本号在每次释放时会递增。 例如,.NET Framework 4、4.5 和 4.5.1 包含 CLR 4,而 .NET Framework 2.0、3.0 和 3.5 包含 CLR 2.0。(没有版本 3 的 CLR。)


混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集

通常,你不应卸载计算机上安装 .NET Framework 的任何版本,因为你使用的应用程序可能取决于特定版本,并且可能中断,如果移除该版本。 你可以同时在一台计算机上加载 .NET Framework 的多个版本。 这意味着可以安装 .NET Framework,而无需卸载旧版本。 有关更多信息,请参见 .NET Framework 入门.aspx)。

让我对这个问题产生兴趣的原因是:

 

指定并运行 .NET Framework 4、4.5 和 4.5.1 应用程序

  • 我将程序编译的目标框架选为 .Net Framework 4.7;在一台安装了 .Net Framework 4.6 的电脑上提示缺少 .Net Framework 4.7;删除了随编译一起生成的 app.config 文件后程序能够正常运行。
  • 另一个程序,我明明将程序编译的目标框架选为 .Net Framework 4.5,但在一台没有安装任何额外 .Net Framework 的 Windows 7 的电脑上提示缺少的是 .Net Framework 4.0。

其调用的方法是从sqlite数据库中获取原来已经使用过的数据库连接,当时也没注意,就是准备设断点然后单步调试,结果竟然是断点无法进入方法体内,后来仔细看了一下方法体的时候发现了一个问题,就是现有的System.Data.Sqlite这个数据访问provider是针对.NET2.0环境开发(最新的版本是1.0.66.0,2010年4月18日发布的),而目前官方也没有给出最新的.NET4的数据访问支持。


这里的疑点在于为什么以上两种看似类似的情况,提示的框架版本却不同。其中的 app.config 文件成为了调查此问题的突破口。

既然出现这个问题,那肯定是上GOOGLE搜索解决方案,毕竟微软不可能因为升级到了.NET4.0的程序无法访问.NET2.0的程序集吧。后来在著名的stackoverflow.com上果然找到了解决方案,就是在app.config中添加一个配置节:startup

.NET Framework 4.5 是替代你计算机上的 .NET Framework 4 的一个就地更新,同样地,.NET Framework 4.5.1 是 .NET Framework 4.5 的一个就地更新。 在安装这些更新中的其中一个后,你的 .NET Framework 4 或 .NET Framework 4.5 应用程序在无需重新编译的情况下应继续运行。 但是,反之则不行。 我们不建议在 .NET Framework 4.5 上运行面向 .NET Framework 4.5.1 应用程序。 采用下面的规则:

配置支持的运行时

观察程序附带的 app.config 文件,我们发现支持的运行时版本是 v4.0,sku 版本是 4.7。

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

疑点:

  1. 为什么我们基于 .Net Framework 4.7 开发的程序运行时版本是 4.0?
  2. sku 是什么?

微软的官方文档给了我们解答:supportedRuntime Element。

  • version:用于指定此应用程序支持的公共语言运行时(CLR)的版本。
  • sku:stock-keeping unit(官方中文为“库存单位”,然而依然不懂这个词的意思),用于指定此应用程序支持的 .Net Framework 发行版本。

version 的值可取:

.NET Framework 版本 version 值
忽略早期版本 忽略早期版本
2.0 “v2.0.50727”
3.0 “v2.0.50727”
3.5 “v2.0.50727”
3.5 “v2.0.50727”
4.0-4.7 “v4.0”

sku 的值可取:

.NET Framework version sku 值
4.0 “.NETFramework,Version=v4.0”
忽略中间版本 忽略中间版本
4.5 “.NETFramework,Version=v4.5”
4.5.1 “.NETFramework,Version=v4.5.1”
4.5.2 “.NETFramework,Version=v4.5.2”
4.6 “.NETFramework,Version=v4.6”
4.6.1 “.NETFramework,Version=v4.6.1”
4.6.2 “.NETFramework,Version=v4.6.2”
4.7 “.NETFramework,Version=v4.7”

于是我们发现,其实无论我们将程序的目标框架选为 .Net Framework 的哪一个 4.x 版本,CLR 运行时都是用 v4.0 表示的。微软的描述是:

对于支持 .NET Framework 4.0 或更高版本的应用程序,version 属性指示 CLR 版本,这是 .NET Framework 4 及更高版本的通用版本,而 sku 属性指示应用程序所针对的单个 .NET Framework 版本。

其实看到这里我们就能有一个看似不错的解释:

  1. 无论我们选择的目标框架是 .Net Framework 4.x 的哪一个版本,用于指定 CLR 运行时版本的 version 值都是 v4.0;
  2. CLR 运行时会根据配置文件的 sku 值决定应该采用那一组运行库来为程序运行提供支持。

<``startup useLegacyV2RuntimeActivationPolicy``=``"true"``>

  • 在 Visual Studio 2013,可以选择 .NET Framework 4.5 作为项目的目标框架(这组 GetReferenceAssemblyPaths.TargetFrameworkMoniker.aspx) 属性)可编译项目为 .NET Framework 4.5 程序集或可执行文件。 此程序集或可执行文件可随后用于任何安装有 .NET Framework 4.5 或 .NET Framework 4.5.1 的计算机。

  • 在 Visual Studio 2013,可以选择 .NET Framework 4.5.1 作为项目的目标框架(这组 GetReferenceAssemblyPaths.TargetFrameworkMoniker.aspx) 属性)可编译项目为 .NET Framework 4.5.1 程序集或可执行文件。 此程序集或可执行文件只能在安装有 .NET Framework 4.5.1 的计算机上运行。 面向 .NET Framework 4.5.1 的可执行文件会受到阻止,不能在只安装了 的计算机上运行,并且系统会提示用户安装 .NET Framework 4.5.1。 此外,不应从 .NET Framework 4.5 应用程序中调用 .NET Framework 4.5.1 程序集。

.Net Framework 的组成以及各部分的版本

我们需要寻找到 .Net Framework 的本质,不然如此错综复杂的版本号系统真把我搞懵了。

微软在 .NET Framework Versions and Dependencies 中说到:

每个版本的 .NET framework 都包含公共语言运行时 (CLR)、基础库和其他托管库。

于是我们谈论 .Net Framework 的版本其实应该分三个不同的部分来谈:

每个新版本的 .NET Framework 都会保留早期版本中的功能并会添加新功能。 CLR 有其自己的版本号标识。 虽然 CLR 版本并不总是递增的,但 .NET Framework 版本号在每次发布时都会递增。 例如,.NET Framework 4、4.5 和更高版本包含 CLR 4,而 .NET Framework 2.0、3.0 和 3.5 包含 CLR 2.0。 (没有版本 3 的 CLR。)

从官方文档给出的表格当中我们可以确信:.Net Framework 4.0/4.5/4.6/4.7 包含的 CLR 版本都是 4.0。

<``supportedRuntime version``=``"v4.0"``/>

.NET Framework 中的某些更改可能需要更改你的应用程序代码;请先参见 .NET Framework 4.5 中的应用程序兼容性.aspx),然后再使用 .NET Framework 4.5 或 .NET Framework 4.5.1 运行现有应用程序。 有关安装当前版本的更多信息,请参见安装 .NET Framework 4.5、4.5.1.aspx)。 有关对 .NET Framework 的支持的信息,请参见 Microsoft 支持网站上的 Microsoft .NET Framework 支持生命周期策略。

CLR 的更新

然而,不相信微软的 CLR 可以完全没有 BUG,既然 CLR 版本都是 4.0,那么微软对 CLR 运行时的更新怎么处理?安装了 .Net Framework 4.5/4.6/4.7 会如何提升 CLR 的稳定性和安全性?

在 Targeting and Running .NET Framework apps for version 4.5 and later 中,解释了 CLR 的更新机制——就地更新(in-place update)。这篇文章 .NET 4.5 is an in-place replacement for .NET 4.0 对这种就地更新方式有比官方文档更详细的解释,并且还附带自己的一些试验(含代码)。不过文章是 2012 年写的,部分结论现在看来已经过时(因为在我的 Windows 10 配 .Net Framework 4.7 上结论已经不一样),不过对我理解就地更新本身非常有帮助,也为后续调查提供了更清晰的思路。

微软对 .Net Framework 4.x 框架就地更新的说明是:

.NET Framework 4.5 是替代计算机上的 .NET Framework 4 的就地更新,同样,.NET Framework 4.5.1 4.5.2、4.6、4.6.1、4.6.2 和 4.7 是对 .NET Framework 4.5 的就地更新,这意味着它们将使用相同的运行时版本,但是程序集版本会更新并包括新类型和成员。 在安装其中某个更新后,你的 .NET Framework 4.NET Framework 4.5 或 .NET Framework 4.6 应用应继续运行,而无需重新编译。 但是,反过来则不行。

也就是说,无论我们在开发时指定目标框架的版本是 4.x 的哪一个,在运行时,CLR 环境都是 4.0。但是新的 .Net Framework 会带来更新版本的 CLR,这个 CLR 会直接替换掉旧的 CLR。.NET 4.5 is an in-place replacement for .NET 4.0 文章中 .Net Framework 基础库也是就地更新的;但我实际实验的情况是每一个不同的 .Net Framework 基础库有自己单独的文件夹,目前尚不清楚这个改变是从 .Net Framework 的哪一个版本开始的,但一定是 4.5.1、4.5.2、4.6 这三个版本中的一个。

图片 1

</``startup``>

指定并运行早期版本的应用程序

解决一开始的疑问

于是,本文一开始的疑问就全部明晰了:

  1. 不管是 .Net Framework 4.5 的还是 4.7 的那两个程序,都是靠 4.0 版本的公共语言运行时(CLR)运行起来的;
  2. 如果没有安装 4.0 版本的 CLR,则会弹出提示需要安装 .Net Framework 4.0 版本才能运行,而不管我们的程序目标框架是 .Net Framework 4.x 的哪一个版本;
    • 虽然说文案说的是 .Net Framework,但其实需要的是 CLR
  3. 如果已经安装有 4.0 版本的 CLR(可能随 .Net Framework 4.5/4.6 安装),我们程序的目标框架是 .Net Framework 4.7,但 .Net Framework 基础库并没有安装 4.7 版本,则运行时会提示需要安装 .Net Framework 4.7;
    • 这个提示是 4.0 版的 CLR 弹出的,是根据 supportedRuntime 中指定的 sku 值来决定的

 


参考资料

  • supportedRuntime Element - Microsoft Docs
  • .NET Framework Versions and Dependencies - Microsoft Docs
  • .NET 4.5 is an in-place replacement for .NET 4.0 - Rick Strahl’s Web Log
  • app config - What does “SKU” (attribute) mean in C#? - Stack Overflow
  • .net - What happens if I remove the auto added supportedRuntime element? - Stack Overflow

本文会经常更新,请阅读原文: https://walterlv.github.io/dotnet/2017/09/22/dotnet-version.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

 

.NET Framework 版本 2.0、3.0 和 3.5 是使用 CLR (CLR 2.0) 的相同版本生成的。 这些版本表示单个安装的连续层。 每个版本增量地生成在早期版本的顶部。 在计算机上不可能并排运行版本 2.0、3.0 和 3.5。 当安装 3.5 版时,自动获得 2.0 和 3.0 层,为 2.0、3.0 和 3.5 版创建的应用程序均可在 3.5 版上运行。 但是,NET Framework 4 关闭此分层方法,2.0 生成的应用程序同样如此。3.0 或 3.5 在 4 版或更高版本上不起作用。 以 .NET Framework 4 开始,可使用进程内并行承载来在单独的进程中运行多个公共语言运行时 (CLR) 版本。 有关更多信息,请参见程序集和并行执行.aspx)。

这段配置节的意思是(参考自MSDN,具体地址:

此外,如果你的应用程序面向 2.0、3.0 或 3.5 版,你的用户可能需要在运行应用程序前在 Windows 8 或 Windows 8.1 预览版 计算机上启用 .NET Framework 3.5。 有关更多信息,请参见在 Windows 8 或 8.1 上安装 .NET Framework 3.5.aspx)。

 

功能及 IDE

启用 .NET Framework 2.0 版 运行时激活策略,这是通过使用最新支持的运行时加载所有程序集。


 

在安装最新版本的 .NET Framework 或 CLR 之前不必安装它们的早期版本。

注意:由于config配置文件的特性,如果在config配置文件中存在configSections节点,则必须将configSections放在一个,否则会引发异常:配置系统未能初始化

下表对应 .NET Framework、CLR 和版本和 Visual Studio 版本,并提供每个版本的简要评审。 注意 Visual Studio 提供多目标锁定功能,你将不再只能使用所列版本的 .NET Framework。

 

 

 

.NET Framework 版本

引入 IDE

说明

4.5.1

Visual Studio 2013

包括性能和调试改进、支持自动绑定重定向以及 Windows 应用商店应用的扩展支持。

4.5

Visual Studio 2012

包括 CLR 4 的更新版本,支持生成 Windows 应用商店应用并更新至 WPF、WCF、WF 和 ASP.NET。

4

Visual Studio 2010

包含新版本的 CLR、扩展的基类库和新功能(如 Managed Extensibility Framework (MEF)、动态语言运行时 (DLR) 和代码协定)。

3.5

Visual Studio 2008

添加了新功能,如支持 AJAX 的网站和 LINQ。 SP1 更新添加了动态数据和少量附加增强功能。

3.0

Visual Studio 2005

此版本实质上是添加了 Windows Presentation Foundation (WPF)、Windows Communications Foundation (WCF)、Windows Workflow Foundation (WF) 和 CardSpace 的 .NET Framework 2.0。 使用 SP1 和 SP2 进行了更新。

2.0

Visual Studio 2005

引入了新版本的 CLR,并为基类库增添了内容,包括泛型、泛型集合以及为 ASP.NET 增添的重要内容。使用 SP1 和 SP2 更新了此版本。

1.1

Visual Studio .NET 2003

包含对 ASP.NET 和 ADO.NET 的更新。 随后使用 Service Pack 1 (SP1) 和 SP2 将此版本更新了 2 次。 此版本还引入了并行执行,这将使单台计算机上的应用程序可对多个版本的 CLR 运行。

1.0

Visual Studio .NET

包含第一个版本的 CLR 和第一个版本的基类库。

 

操作系统支持

本文由88必发手机版发布于仪器仪表,转载请注明出处:混合模式程序集是针对,版本之上

关键词:

上一篇:没有了
下一篇:没有了