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

时间:2011-12-15 08:31:44

标签: .net clr version .net-4.5

我从http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=27541安装了.NET 4.5 Developer预览版,它取代了'.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执行?

7 个答案:

答案 0 :(得分:106)

您需要明确区分CLR(即"运行时")和框架库(即"框架")。您在第一个或第一个上执行代码,您的代码将被编译并使用后者。不幸的是,当使用术语" .NET 版本"一个通常是指运行时和框架的整个包,无论它们各自的版本如何 - 如前所述 - 可以有所不同。

您可以检测到installed framework versions。但是,这并不能告诉您在运行时实际使用的是哪一个。

我不确定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 framework 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)和更多内容的几个程序集的整个包(统称为#34;框架" )加上运行时本身,即CLR - 两者都可以有不同的版本,如前所述。

我不为微软工作,也没有深入了解缺少(单一)功能或API以获得.NET框架版本的真正原因"但是我可以制作一个有根据的猜测。

  1. 目前尚不清楚特定功能/ 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;符号的版本,如4.5版本,它没什么价值,不会吗?)。

  2. 太具体某些新功能可能会在SP中到达现有版本,并且是新版本的一部分。进行功能检查时,您的应用程序可能会在已更新的之前的版本上运行良好,而在显式版本检查时,它可能会不必要地将自己限制为最新版本。我没有从.NET世界中得到一个例子,但总的来说(在Windows本身,例如WMI)它可以而且确实发生过。

  3. 不想要。我可以想象一种方法来计算框架的版本"目前正由应用程序使用的内容甚至不是理想的供他们提供。在本机/ Win32世界中,有version checking fallacies(参见"不要检查版本"适用于.NET的概念的段落)的历史悠久而不圣洁。例如,人们使用GetVersionGetVersionEx API是错误的,只是检查他们在编写应用程序时运行他们知道的最新版本。因此,当应用程序在较新版本的Windows上运行时,它将无法运行,即使它们真正使用的功能仍然存在。微软可能已经考虑过这样的问题,因此甚至没有在.NET中提供一些API。

  4. 顺便说一句,这就是GetVersion函数备注部分中的Microsoft recommends

      

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

    Windows团队博客也有to say的内容。

    我知道这一切都与Windows和本机编程有关,但.NET应用程序框架和CLR的概念和危险是相同的。

    我认为使用(优雅)回退进行功能检查是一种更可靠,更健壮的方法,可确保您的应用程序向下兼容。如果您只希望您的应用程序使用特定版本的.NET或更新版本,请不要做任何特别的事情,并依靠.NET本身的向后兼容性。

答案 1 :(得分:28)

要准确确定您的应用程序正在运行哪个.NET补丁,请进行此调用以查找mscorlib的内部版本号:

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

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

答案 2 :(得分:25)

.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运行时。

答案 3 :(得分:7)

James提供great answer在运行时获取 mscorlib.dll 的“产品版本”:

using System.Diagnostics;

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

这很有效,但您可以通过检查 System.dll 来获得更细粒度的结果:

FileVersionInfo.GetVersionInfo(typeof(Uri).Assembly.Location).ProductVersion

请注意,稍微不同的是使用typeof(Uri)而不是typeof(int)的程序集,因为前者在System.dll中定义,而后者在mscorlib.dll中定义。对于针对 .NET 4.7.1 的简单C#控制台程序,目前在我的系统上报告的差异如下

  

... \ Microsoft.NET \ Framework \ v4.0.30319 \ mscorlib.dll 4.7。 2600 .0   ... \ Microsoft.NET \ Framework \ v4.0.30319 \ System.dll 4.7。 2556 .0

至于区分是否有用或如何使用更详细的信息,这取决于具体情况。

答案 4 :(得分:5)

您可以通过检查注册表中的HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full子项{{{}来测试是否安装了 .NET Framework 4.5 .NET Framework 4 。 1}}名为DWORD的值。此Release的存在表示该计算机上已安装 .NET Framework 4.5 DWORD的值是版本号。要确定是否安装了 .NET Framework 4.5 的最终发行版,请检查是否等于或大于Release

答案 5 :(得分:2)

从我对在线资源的理解,.NET 4.5将以类似的方式(虽然不完全相同)与3.5对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都是一样的。

答案 6 :(得分:0)

从.NET Core 3.0(和.NET Standard 2.1)开始,情况已更改,现在Environment.Version可以正常工作。因此,您可以使用此属性来检测所使用的点网版本。

System.Console.WriteLine($"Environment.Version: {System.Environment.Version}");

// Old result
//   Environment.Version: 4.0.30319.42000
//
// New result
//   Environment.Version: 3.0.0

有关更多信息,请参见documentation