.NET Framework CLR 版本检测
我写了一个 c# 程序来检测 .net framework clr 版本。
在 ubuntu 操作中的运行结果:
在 windows vista 操作系统中的运行结果:
注意,这个程序检测的是 .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 操作系统中的运行结果:
另外,microsoft windows sdk 中的 clrver.exe 的运行结果:
我们来看看源程序吧。下面是 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 中文手册):
在 linux 操作系统下可以用 make 命令编译。在 windows 操作系统下可以用 nmake 命令编译。
注意,mono 的 c# 编译器是 gmcs,但是她有个别名叫 csc ,如下所示:
推荐阅读
-
【转载】Visual Studio中WinForm窗体程序如何切换.NET Framework版本
-
.NET Framework CLR 版本检测
-
查看Windows电脑上.NET Framework版本的方法(找了好久的方法)
-
Powershell小技巧之查看安装的.Net framework版本信息
-
.NET Framework各版本(.NET2.0 3.0 3.5 4.0)区别
-
.NET Framework未来版本将支持Mac
-
【转载】如何确定计算机上安装的 .NET Framework 版本和 Service Pack 级别。
-
.NET Framework CLR 版本检测
-
【转载】Visual Studio中WinForm窗体程序如何切换.NET Framework版本
-
Powershell小技巧之查看安装的.Net framework版本信息