如何在執行時檢測 .NET 4.5 版目前正在執行您的程式碼?
我從http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=27541安裝了 .NET 4.5 Developer preview ,它“替換”了 .NET 4.0 版本。
但是,檢測 .NET 框架版本的舊方法似乎返回 4.0(在我的 PC 上更準確地說是 4.0.30319.17020),而不是 4.5(肯定可能是為了向後兼容,或者?):
using System; namespace ConsoleApplication { class Program { static void Main(string[] args) { var version = Environment.Version; Console.WriteLine(version.ToString()); Console.ReadKey(); } } }如何檢測我的程式碼是否真正由 .NET 4.5 執行?
您需要明確區分 CLR(即“執行時”)和框架庫(即“框架”)。您在第一個或第一個上執行您的程式碼,您的程式碼被編譯並使用後者。不幸的是,當使用術語“.NET版本”時,通常指的是執行時和框架的整個包,而不管它們各自的版本如何——如前所述——可能不同。
您可以檢測已安裝的框架版本。但是,這並不能告訴您在執行時實際使用的是哪一個。
我不確定 4.5,但 2.0 與 3.0 或 3.5
Environment.Version沒有任何幫助,因為它總是返回 2.0,因為所有這些框架版本都使用 CLR 2.0。我假設框架4.5的CLR 版本仍然是 4.0,這可以解釋Environment.Version即使在這種情況下也會返回 4.0.x。一種可能對您有用的技術是檢查核心庫(mscorlib、System.Core 等)中的類型、方法或屬性,您知道這些庫僅從特定的 .NET 框架版本開始存在。
例如,ReflectionContext類在 .NET 框架 4.5 中似乎是全新的,並且可以方便地使用
mscorlib. 所以你可以做這樣的事情。public static bool IsNet45OrNewer() { // Class "ReflectionContext" exists from .NET 4.5 onwards. return Type.GetType("System.Reflection.ReflectionContext", false) != null; }說了這麼多,人們可能會質疑為什麼您需要知道您使用的是哪個 .NET 版本。只需嘗試訪問您需要的功能,如果它們不存在,可能會優雅地回退到其他東西(在舊版本中可用)。
更新:請注意,術語 .NET 4.5 是指組成基類庫 (BCL) 和更多(統稱為“框架”)的幾個程序集的整個包以及執行時本身,即 CLR——兩者都可以如前所述,不同的版本。
我不為 Microsoft 工作,並且不了解缺少(單個)函式或 API 來獲得“.NET 框架版本”的真正原因,但我可以做出有根據的猜測。
- **目前尚不清楚這樣的功能/API 應該提供哪些資訊。**甚至 BCL 的各個程序集也不共享一個公共(程序集/文件)版本。例如,對於 .NET 3.0 和 3.5,mscorlib.dll 的版本為 2.0.x,而只有 WCF 和 WF 的新程序集有 3.0 版本。我認為即使使用 .NET 3.5
System.ServiceModel.dll仍然有 3.0.x 版本。我想說的是,框架的所有程序集上都沒有統一的版本。那麼 API 呼叫應該System.Environment.FrameworkVersion返回什麼?該版本的價值是多少(即使它確實返回了像 4.5 這樣的“符號”版本,它也沒有什麼價值,不是嗎?)。- 過於具體某些新功能可能會出現在現有版本的 SP 中,並且是新版本的一部分。進行功能檢查時,您的應用程序可能在已更新的先前版本上執行良好,而通過顯式版本檢查,它可能會不必要地將自身限制為最新版本。我沒有來自 .NET 世界的範例,但總的來說(以及在 Windows 本身中,例如 WMI)它可以並且確實發生了。
- **不想要。我可以想像,他們甚至不希望提供一種確定應用程序目前正在使用的“框架版本”的方法。在本機/Win32 世界中,版本檢查謬誤有著悠久而邪惡的歷史(有關適用於 .NET 的概念,請參閱“不檢查版本”段落)。例如,人們錯誤地使用了API
GetVersion和GetVersionExAPI,只檢查他們執行的版本是否是他們在編寫應用程序時知道的最新版本。因此,當應用程序在較新版本的 Windows 上執行時,它不會執行,即使這些功能他們真正使用的仍然存在。微軟可能已經考慮過這樣的問題,因此甚至沒有在 .NET 中提供一些 API。順便說一句,這是 Microsoft在 GetVersion 函式的備註部分中推薦的內容:
辨識目前作業系統通常不是確定是否存在特定作業系統功能的最佳方式。這是因為作業系統可能在可再發行的 DLL 中添加了新功能。不要使用 GetVersionEx 來確定作業系統平台或版本號,而是測試功能本身是否存在。
Windows 團隊部落格對此也有話要說。
我知道這一切都是關於 Windows 和本機程式的,但是對於 .NET 應用程序、框架和 CLR 來說,概念和危險是相同的。
我會說使用(優雅的)回退進行功能檢查是一種更可靠和更強大的方式來確保您的應用程序向下兼容。如果您只希望您的應用程序與特定版本的 .NET 或更高版本一起工作,請不要做任何特別的事情,並依靠 .NET 本身的向後兼容性。