System.Environment.Version提供不准确的值

本文关键字:不准确 Environment Version System | 更新日期: 2023-09-27 18:10:25

我有一个快速的问题:当我在Visual Studio 2012中去HELP->About时,窗口表明我使用的。net版本是4.5.50709。但是,当我执行以下代码时:

Console.WriteLine(Environment.Version);

我得到版本4.0.30319.18034。到底发生了什么事?在Troelsen的Pro c# 5 &. net 4.5 Framework,在第81页中指出,Version属性返回一个表示。net平台版本的对象。这是不对的吗?上一个问题的线程表明此属性返回CLR版本。如果是这种情况,Version对象的目的是什么(也就是说,知道CLR版本与框架版本有什么不同),以及如何实际获得框架版本本身?

System.Environment.Version提供不准确的值

CLR (Common Language Runtime)版本为4.0.30319.18034。它从4.0.30319开始,因为。net 4.5是。net 4.0程序集的就地升级。

4.5更新完全取代了。net 4.0运行时,并保留了v4.0.30319的实际版本号。

(来源1,来源2)

但是你的版本号可能代表。net 4.5和一些更新,正如用户Daniel从这个列表中推断出来的:

下面是我看到的一些运行时版本的例子:

  • 4.0.30319.1 = .net 4.0 rtm
  • 4.0.30319.269 =我们从用户收集的数据中看到的最常见的。net 4.0版本
  • 4.0.30319.544 =另一个。net 4.0版本,我们的一小部分用户已经安装了
  • 4.0.30319.17626 = .net 4.5 rc4.0.30319.17929 = .net 4.5 rtm
  • 4.0.30319.18010 =我的Windows 8机器当前版本

主版本号、次版本号和构建版本号都没有改变,所以我估计他们认为。net 4.0和。net 4.5之间的差异不会大到对大多数人来说有什么影响。. net 4.0的应用程序在。net 4.5下仍然可以像预期的那样工作。


无论您是为。net 4.0还是4.5编写代码,您都是针对完全相同的。net程序集进行编译的。唯一的区别是。net 4.5中的一些新类在针对。net 4.0编译时是隐藏的(就好像它们从未存在过一样)。因此,区分。net 4.0和。net 4.5的唯一可靠的方法似乎是Christian提出的相当粗糙的方法。K在他的帖子中,不涉及版本号:

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;
}

作为练习,我想知道Visual Studio是如何检索。net版本的。您可以查询注册表以查看安装了哪些版本,我提出了以下代码:

static void Main(string[] args)
{
    Console.WriteLine("The following .NET versions are installed:");
    var vers = SearchRegistry(Registry.LocalMachine, "Software''Microsoft''NET Framework Setup''NDP", "Version")
        .GroupBy(v => v)
        .Select(v => (string)v.Key)
        .OrderBy(s => s);
    foreach (string s in vers)
        Console.WriteLine(s);
    Console.WriteLine(string.Format("Newest Installed .NET version: {0}", vers.Last()));
}
private static IEnumerable<object> SearchRegistry(RegistryKey root, string subkey, string search)
{
    foreach (string sub in root.OpenSubKey(subkey).GetSubKeyNames())
    {
        foreach (string val in root.OpenSubKey(subkey).OpenSubKey(sub).GetValueNames())
            if (val == search)
                yield return root.OpenSubKey(subkey).OpenSubKey(sub).GetValue(val);
        foreach (var o in SearchRegistry(root.OpenSubKey(subkey), sub, search))
            yield return o;
    }
}