如何在运行时检测到.NET 4.5版本正在运行您的代码?

我从http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=27541安装了.NET 4.5 Developer预览版,它将“replace”.NET 4.0版本。

然而,旧的方式来检测.NET框架版本似乎返回4.0(更确切地说,我的电脑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 版本 ”时,通常指的是运行时和框架的整个包,而不pipe它们各自的版本如上所述可以不同。

您可以检测已安装的框架版本 。 但是,这并不能告诉你在运行时实际使用哪一个。

我不确定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等)中的types,方法或属性,你只知道它是从一个特定的.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版本。 只需尝试访问所需的function,并可能优雅地回退到其他(旧版本中可用的)function,如果它们不存在的话。

更新 :请注意,术语.NET 4.5是指构成基本类库(BCL)和更多(统称为“框架”)的几个程序集的整个包,以及运行时本身(即CLR) – 它们都可以不同的版本,如前所述。

我不为微软工作,也没有深入了解缺乏(单一)函数或API来获取“.NET框架版本”背后的真正原因,但我可以做一个有根据的猜测。

  1. 目前还不清楚这些function/ 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版本。 我想说的是,框架的所有程序集都没有统一的版本。 那么,像System.Environment.FrameworkVersion这样的API调用应该返回什么呢? 这个版本会有什么价值(即使它返回像4.5这样的“符号”版本,价值不大,不是吗?)。

  2. 太具体了一些新的function可能会到达现有版本的SP,再加上是新版本的一部分。 在进行function检查时,应用程序可能在以前的版本上运行得非常好,并且已经更新,而在进行明确的版本检查时,它可能会不必要地限制到最新版本。 我没有一个来自.NET世界的例子,但总的来说(在Windows本身,例如WMI),它可以并确实发生。

  3. 不想要。 我可以想象一下,一个应用程序当前正在使用的“框架版本”的方法对于他们来说是不可取的。 在本地/ Win32的世界里,有一个长期而邪恶的版本检查谬误的历史(请参阅“不要检查版本”的段落适用于.NET的概念)。 例如,人们使用GetVersionGetVersionEx API是错误的,只检查他们在编写应用程序时运行他们知道的最新版本。 所以,当应用程序在较新版本的Windows上运行时,即使它们真正使用的function仍然存在,它也不会运行。 微软可能已经考虑过这样的问题,因此甚至没有在.NET中提供一些API。

顺便说一句,这是Microsoft build议在GetVersion函数的注释部分:

识别当前的操作系统通常不是确定是否存在特定操作系统function的最佳方法。 这是因为操作系统可能在可重新分发的DLL中添加了新function。 testing是否存在特征本身,而不是使用GetVersionEx来确定操作系统平台或版本号。

Windows团队博客也有这方面的说法 。

我知道所有这些都是关于Windows和本地编程的,但是.NET应用程序框架和CLR的概念和危险是一样的。

我会说function检查与(优雅)回退因此是一个更可靠和可靠的方式来确保您的应用程序向下兼容。 如果您只希望您的应用程序使用特定版本的.NET或更新版本,请不要做任何特别的事情,并指望.NET本身的向后兼容性。

.NET Framework 4.5是就地升级到4.0的。 这松散地意味着,如果您运行的是版本4.0或4.5运行时,并且安装了4.5,那么您肯定在4.5上运行。 您的支票可能如下。

我们来调用4.0和4.5运行时4.0版本的运行时

  1. 检查您是否正在运行4.0版本的运行时:

    • 如果您的程序集编译为目标.NET 4.0或
    • Environment.Version.Major == 4 && Environment.Version.Minor == 0

    那么你正在运行一个4.0版本的运行时。

  2. 通过检查安装的版本来检查4.0版本的运行时是否实际上是版本4.0或4.5。

    • 在关键HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client ,检查_Version_值。 如果以"4.0"开头,则运行在4.0运行时,如果以"4.5"开头,则运行在4.5运行时。

要确定您的应用程序正在运行的.NET的哪个修补程序,可以通过此调用来查找mscorlib的构build版本:

 System.Diagnostics.FileVersionInfo.GetVersionInfo(typeof(int).Assembly.Location).ProductVersion 

它目前为我返回4.6.1055.0,这对应于.NET 4.6.1。

您可以通过在registry中检查名为ReleaseDWORDHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full子项来testing是否安装了.NET Framework 4.5.NET Framework 4 。 该DWORD的存在表示该计算机上已经安装了.NET Framework 4.5Release的值是一个版本号。 要确定是否安装了最终版本的.NET Framework 4.5 ,请检查一个等于或大于378389

从我从在线资源中了解到的情况来看,.NET 4.5将以类似的方式(尽pipe不完全相同)与2.0的版本相同:版本号保持不变(如果运行3.5代码,CLR版本将为2.0)它将作为现有CLR 4.0的更新。

所以你可以将共存2.0升级到3.5和4.0升级到4.5。

目前还不清楚的是,如果可以在4.0中制作(或在现有的)现有项目而无需将其升级到4.5:目前,您可以在Visual Studio 2010中制作2.0或3.5项目,但可能不会相同为4.0和4.5。