当前位置: 移动技术网 > IT编程>开发语言>.net > .NET Framework CLR 版本检测

.NET Framework CLR 版本检测

2018年11月13日  | 移动技术网IT编程  | 我要评论

油价上调最新消息,纯种德国牧羊犬,焦豫汝

我写了一个 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.utf8encoding

available frameworks:
  mono 1.0 profile
  mono 2.0 profile

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

e:csclrinfo> 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.dbcscodepageencoding

available 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:csclrinfo> 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.dbcscodepageencoding
    
    available frameworks:
      net 1.1.4322
      net 2.0.50727
      net 4.0.21006
    

    另外,microsoft windows sdk 中的 clrver.exe 的运行结果:

    e:csclrinfo> clrver.exe
    versions installed on the machine:
    v1.1.4322
    v2.0.50727
    v4.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 https://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();
            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(@softwarenovellmono);
          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();
          if (rt == runtimetype.net && environment.osversion.platform != platformid.unix)
          {
            var key = registry.localmachine.opensubkey(@softwaremicrosoft.netframeworkpolicy);
            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 的话,就通过遍历注册表的 softwaremicrosoft.netframeworkpolicy 项来检测 .net framework clr 版本。

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

    csc = csc
    src1 = clrinfo.cs runtimeframework.cs
    
    clrinfo.exe: $(src1)
    	$(csc) -out:$@ $(src1)
    

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

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

    ben@ben-m4000t:~$ ls -l /usr/bin/csc /usr/bin/gmcs
    lrwxrwxrwx 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/gmcs
    ben@ben-m4000t:~$ cat /usr/bin/gmcs
    #!/bin/sh
    exec /usr/bin/mono $mono_options /usr/lib/mono/2.0/gmcs.exe $@
    ben@ben-m4000t:~$ gmcs --version
    mono c# compiler version 2.4.2.3
    ben@ben-m4000t:~$ csc --version
    mono c# compiler version 2.4.2.3

     

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网