.NET Framework CLR 版本检测

来源:互联网 发布:淘宝日本直邮是真的吗 编辑:程序博客网 时间:2024/05/18 17:28

我写了一个 C# 程序来检测 .NET Framework CLR 版本。

在 Ubuntu 操作系统中的运行结果:

ben@ben-m4000t:~/work$ ./ClrInfo.exe      OS Version: Unix 2.6.31.16     CLR Version: 2.0.50727.1433  ( Mono 2.4.2.3 )Default Encoding: System.Text.UTF8EncodingAvailable Frameworks:  Mono 1.0 Profile  Mono 2.0 Profile

在 Windows Vista 操作系统中的运行结果:

E:\CS\ClrInfo> ClrInfo.exe      OS Version: Microsoft Windows NT 6.0.6002 Service Pack 2     CLR Version: 2.0.50727.4200  ( Net 2.0.50727.4200 )Default Encoding: System.Text.DBCSCodePageEncodingAvailable Frameworks:  Net 2.0.50727

注意,这个程序检测的是 .NET Framework CLR 版本,而不是 .NET Framework 版本。实际上这个 Windows Vista 操作系统中安装了 .NET Framework 的以下版本:

  • 2.0.50727.4016
  • 3.0.30729.4037
  • 3.5.30729.01

而三个版本的 .NET Framework 的 CLR 版本都是 2.0.50727。

在 Windows Server 2003 操作系统中的运行结果:

E:\CS\ClrInfo> ClrInfo.exe      OS Version: Microsoft Windows NT 5.2.3790 Service Pack 2     CLR Version: 2.0.50727.3603  ( Net 2.0.50727.3603 )Default Encoding: System.Text.DBCSCodePageEncodingAvailable Frameworks:  Net 1.1.4322  Net 2.0.50727  Net 4.0.21006

另外,Microsoft Windows SDK 中的 ClrVer.exe 的运行结果:

E:\CS\ClrInfo> ClrVer.exeVersions installed on the machine:v1.1.4322v2.0.50727v4.0.21006

我们来看看源程序吧。下面是 ClrInfo.cs:

using System;using System.Text;namespace Skyiv{  public class ClrInfo  {    static void Main()    {      Console.WriteLine("      OS Version: {0}", Environment.OSVersion);      Console.WriteLine("     CLR Version: {0}  ( {1} )", Environment.Version, RuntimeFramework.CurrentFramework);      Console.WriteLine("Default Encoding: {0}", Encoding.Default);      Console.WriteLine();      Console.WriteLine("Available Frameworks:");      foreach (var frame in RuntimeFramework.AvailableFrameworks) Console.WriteLine("  " + frame);    }  }}

下面是 RuntimeFramework.cs (该程序是从 NUnit 的源程序中的同名文件改写而来的):

using System;using System.Reflection;using System.Collections.Generic;using Microsoft.Win32;namespace Skyiv{  public enum RuntimeType  {    Any,   // Any supported runtime framework    Net,   // Microsoft .NET Framework    NetCF, // Microsoft .NET Compact Framework    SSCLI, // Microsoft Shared Source CLI    Mono,  // Mono  }  // See http://nunit.org, this class from NUnit Project's RuntimeFramework.cs  // RuntimeFramework represents a particular version of a common language runtime implementation.  [Serializable]  public sealed class RuntimeFramework  {    public RuntimeType Runtime { get; private set; }    public Version Version { get; private set; }    public string DisplayName { get; private set; }    static RuntimeFramework currentFramework;    public static RuntimeFramework CurrentFramework    {      get      {        if (currentFramework == null)        {          var monoRuntimeType = Type.GetType("Mono.Runtime", false);          var runtime = monoRuntimeType != null ? RuntimeType.Mono : RuntimeType.Net;          currentFramework = new RuntimeFramework(runtime, Environment.Version);          if (monoRuntimeType != null)          {            var method = monoRuntimeType.GetMethod("GetDisplayName", BindingFlags.Static |              BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.ExactBinding);            if (method != null) currentFramework.DisplayName = (string)method.Invoke(null, new object[0]);          }        }        return currentFramework;      }    }    public static RuntimeFramework[] AvailableFrameworks    {      get      {        var frameworks = new List<RuntimeFramework>();        foreach (var framework in GetAvailableFrameworks(RuntimeType.Net)) frameworks.Add(framework);        foreach (var framework in GetAvailableFrameworks(RuntimeType.Mono)) frameworks.Add(framework);        return frameworks.ToArray();      }    }    public static bool IsMonoInstalled()    {      if (CurrentFramework.Runtime == RuntimeType.Mono) return true;      // Don't know how to do this on linux yet, but it's not a problem since we are only supporting Mono on Linux      if (Environment.OSVersion.Platform != PlatformID.Win32NT) return false;      var key = Registry.LocalMachine.OpenSubKey(@"Software\Novell\Mono");      if (key == null) return false;      var version = key.GetValue("DefaultCLR") as string;      if (string.IsNullOrEmpty(version)) return false;      return key.OpenSubKey(version) != null;    }    // Returns an array of all available frameworks of a given type, for example, all mono or all .NET frameworks.    public static RuntimeFramework[] GetAvailableFrameworks(RuntimeType rt)    {      var frameworks = new List<RuntimeFramework>();      if (rt == RuntimeType.Net && Environment.OSVersion.Platform != PlatformID.Unix)      {        var key = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\.NETFramework\policy");        if (key != null)          foreach (var name in key.GetSubKeyNames())            if (name.StartsWith("v"))              foreach (var build in key.OpenSubKey(name).GetValueNames())                frameworks.Add(new RuntimeFramework(rt, new Version(name.Substring(1) + "." + build)));      }      else if (rt == RuntimeType.Mono && IsMonoInstalled())      {        var framework = new RuntimeFramework(rt, new Version(1, 1, 4322));        framework.DisplayName = "Mono 1.0 Profile";        frameworks.Add(framework);        framework = new RuntimeFramework(rt, new Version(2, 0, 50727));        framework.DisplayName = "Mono 2.0 Profile";        frameworks.Add(framework);      }      return frameworks.ToArray();    }    public RuntimeFramework(RuntimeType runtime, Version version)    {      Runtime = runtime;      Version = version;      DisplayName = runtime.ToString() + " " + version.ToString();    }    public override string ToString()    {      return DisplayName;    }  }}

在 RuntimeFramework 类的 CurrentFramework 属性中,如果发现当前环境是 mono 的话,就通过反射调用 Mono.Runtime 类的静态方法 GetDisplayName 来设置 DisplayName 属性。

在 RuntimeFramework 类的静态方法 GetAvailableFrameworks 中,如果发现当前操作系统不是 Unix 的话,就通过遍历注册表的 Software\Microsoft\.NETFramework\policy 项来检测 .NET Framework CLR 版本。

下面是 makefile (关于 makefile,可以参见:GUN make 中文手册):

CSC = cscSRC1 = ClrInfo.cs RuntimeFramework.csClrInfo.exe: $(SRC1)$(CSC) -out:$@ $(SRC1)

在 Linux 操作系统下可以用 make 命令编译。在 Windows 操作系统下可以用 nmake 命令编译。

注意,Mono 的 C# 编译器是 gmcs,但是她有个别名叫 csc ,如下所示:

ben@ben-m4000t:~$ ls -l /usr/bin/csc /usr/bin/gmcslrwxrwxrwx 1 root root  4 2009-11-01 18:53 /usr/bin/csc -> gmcs-rwxr-xr-x 1 root root 75 2009-09-23 23:04 /usr/bin/gmcsben@ben-m4000t:~$ cat /usr/bin/gmcs#!/bin/shexec /usr/bin/mono $MONO_OPTIONS /usr/lib/mono/2.0/gmcs.exe "$@"ben@ben-m4000t:~$ gmcs --versionMono C# compiler version 2.4.2.3ben@ben-m4000t:~$ csc --versionMono C# compiler version 2.4.2.3
0 0
原创粉丝点击