1. 程式人生 > >.Net Framework 4.x 程序到底運行在哪個 CLR 版本之上

.Net Framework 4.x 程序到底運行在哪個 CLR 版本之上

mda ive 選擇 為什麽 rep target works 文檔 ocs

轉帖:https://blog.csdn.net/WPwalter/article/details/78067293

另參考:https://www.cnblogs.com/worksguo/archive/2010/02/10/1666939.html

當我們編譯程序目標框架選為 .Net Framework 4.5/4.6/4.7 時,CLR 運行時是如何判斷我們究竟應該用哪一個 .Net Framework 呢?.Net Framework 的版本到底由哪些部分組成?我們編譯 .Net Framework 時選擇的版本到底決定了什麽?

讓我對這個問題產生興趣的原因是:
- 我將程序編譯的目標框架選為 .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。

這裏的疑點在於為什麽以上兩種看似類似的情況,提示的框架版本卻不同。其中的 app.config 文件成為了調查此問題的突破口。
配置支持的運行時

觀察程序附帶的 app.config 文件,我們發現支持的運行時版本是 v4.0,sku 版本是 4.7。

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

1
2
3
4
5

疑點:
1. 為什麽我們基於 .Net Framework 4.7 開發的程序運行時版本是 4.0?
1. 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;
1. CLR 運行時會根據配置文件的 sku 值決定應該采用那一組運行庫來為程序運行提供支持。
.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。
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 這三個版本中的一個。

每一個不同的 .Net Framework 基礎庫有自己單獨的文件夾
解決一開始的疑問

於是,本文一開始的疑問就全部明晰了:
1. 不管是 .Net Framework 4.5 的還是 4.7 的那兩個程序,都是靠 4.0 版本的公共語言運行時(CLR)運行起來的;
1. 如果沒有安裝 4.0 版本的 CLR,則會彈出提示需要安裝 .Net Framework 4.0 版本才能運行,而不管我們的程序目標框架是 .Net Framework 4.x 的哪一個版本;
- 雖然說文案說的是 .Net Framework,但其實需要的是 CLR
1. 如果已經安裝有 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
---------------------
作者:walter lv
來源:CSDN
原文:https://blog.csdn.net/WPwalter/article/details/78067293
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

.Net Framework 4.x 程序到底運行在哪個 CLR 版本之上