轉載至 .NET Framework 4.x 程序到底運行在哪一個 CLR 版本之上html
當咱們編譯程序目標框架選爲 .NET Framework 4.5/4.6/4.7/4.8 時,CLR 運行時是如何判斷咱們究竟應該用哪個 .NET Framework 呢?.NET Framework 的版本到底由哪些部分組成?咱們編譯 .NET Framework 時選擇的版本決定了什麼?web
讓我對這個問題產生興趣的緣由是:安全
app.config
文件後程序可以正常運行。這裏的疑點在於爲何以上兩種看似相似的狀況,提示的框架版本卻不一樣。其中的 app.config
文件成爲了調查此問題的突破口。app
觀察程序附帶的 app.config
文件,咱們發現支持的運行時版本是 v4.0,sku 版本是 4.8。框架
<configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" /> </startup> </configuration>
疑點:ide
微軟的官方文檔給了咱們解答:supportedRuntime Element。post
version
:用於指定此應用程序支持的公共語言運行時(CLR)的版本。sku
:stock-keeping unit(官方中文爲「庫存單位」,然而依然不懂這個詞的意思),用於指定此應用程序支持的 .NET Framework 發行版本。version
的值可取:ui
.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.8 | 「v4.0」 |
sku
的值可取:spa
.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」 |
4.7.1 | 「.NETFramework,Version=v4.7.1」 |
4.7.2 | 「.NETFramework,Version=v4.7.2」 |
4.8 | 「.NETFramework,Version=v4.8」 |
因而咱們發現,其實不管咱們將程序的目標框架選爲 .NET Framework 的哪個 4.x 版本,CLR 運行時都是用 v4.0 表示的。微軟的描述是:.net
對於支持 .NET Framework 4.0 或更高版本的應用程序,version 屬性指示 CLR 版本,這是 .NET Framework 4 及更高版本的通用版本,而 sku 屬性指示應用程序所針對的單個 .NET Framework 版本。
其實看到這裏咱們就能有一個看似不錯的解釋:
version
值都是 v4.0;sku
值決定應該採用那一組運行庫來爲程序運行提供支持。咱們須要尋找到 .NET Framework 的本質,否則如此錯綜複雜的版本號系統真把我搞懵了。
微軟在 .NET Framework Versions and Dependencies 中說到:
每一個版本的 .NET Framework 都包含公共語言運行時 (CLR)、基礎庫和其餘託管庫。
因而咱們談論 .NET Framework 的版本其實應該分三個不一樣的部分來談:
每一個新版本的 .NET Framework 都會保留早期版本中的功能並會添加新功能。 CLR 有其本身的版本號標識。 雖然 CLR 版本並不老是遞增的,但 .NET Framework 版本號在每次發佈時都會遞增。 例如,.NET Framework 四、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 能夠徹底沒有 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.二、4.六、4.6.一、4.6.二、4.七、4.7.一、4.7.二、4.8 是對 .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.一、4.5.二、4.6 這三個版本中的一個。
因而,本文一開始的疑問就所有明晰了:
supportedRuntime
中指定的 sku
值來決定的參考資料