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

标签 .net clr version .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 版本”时,通常指的是运行时和框架的整个包,而不管它们各自的版本 - 正如所说 - 可以不同。

您可以检测到 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 框架 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返回?该版本有什么值(value)(即使它确实返回了像 4.5 这样的“符号”版本,它也没有什么值(value),不是吗?)。
  • 太具体一些新功能可能会出现在 SP 的现有版本中,并且成为新版本的一部分。进行功能检查时,您的应用程序可能会在已更新的先前版本上运行良好,而进行显式版本检查时,它可能会不必要地将自身限制为最新版本。我没有来自 .NET 世界的例子,但总的来说(以及在 Windows 本身,例如 WMI)它可以并且确实发生了。
  • 不想要。 我可以想象,他们甚至不希望提供一种计算应用程序当前正在使用的“框架版本”的方法。 version checking fallacies有着悠久而邪恶的历史(有关适用于 .NET 的概念,请参阅“不要检查版本”段落),在 native /Win32 世界中。例如,人们使用 GetVersionGetVersionEx API 是错误的,只检查他们运行的版本是否是他们在编写应用程序时知道的最新版本。因此,当应用程序在较新版本的 Windows 上运行时,它不会运行,即使他们真正使用的功能仍然存在。 Microsoft 可能已经考虑过类似的问题,因此甚至没有在 .NET 中提供一些 API。

  • 顺便说一句这是微软recommends在 GetVersion 函数的备注部分:

    Identifying the current operating system is usually not the best way to determine whether a particular operating system feature is present. This is because the operating system may have had new features added in a redistributable DLL. Rather than using GetVersionEx to determine the operating system platform or version number, test for the presence of the feature itself.



    Windows 团队博客也有一些东西 to say对这个。

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

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

    关于.net - 如何在运行时检测 .NET 4.5 版当前正在运行您的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8517159/

    相关文章:

    iphone - 我的应用程序的 1.1 版本需要哪些新的(如果有)分发/配置?

    python - 以编程方式找到pywin32的安装版本

    jquery - 如何在 MVC5 中使用 Jquery 屏蔽输入?

    .net - NLog 控制台单行日志记录

    c# - C#/CLI 标识符的最大长度是多少?

    c# - 在哪里可以找到 RemotingServices.CreateTransparentProxy 实现?

    .net - 在哪里存储加密 key

    c# - 64 位 .NET 应用程序中是否忽略了 CallingConvention?

    sql - 如何在不使用 Visual Studio 的情况下部署托管存储过程?

    android - 除Oreo外,应用程序无法正常运行