C#如何实现获取电脑硬件配置信息.doc
我不知道你要的系统信息到底有哪些?有几个 ManagementClass 要看你要得到具体哪些具体 信息,比如要想获得盘符就只需一个 ManagementClass 这里是一个范例,或许对你有所帮助(附源码) http://dl3.9hao.com/20060619/_2/winsys/othersys/WMI%B5%C4%D2%BB%B8%F6%CA%B5%CF%D 6.htm 以下是相关资料 http://baike.baidu.com/view/442461.htm http://www.newasp.net/tech/net/8540.html http://www.ahaoz.com/Article/203/205/545/2005/20051120102957.html 一:WMI 基础知识 ================================================================================ ==== WMI 最初于 1998 年作为一个附加组件与 Windows NT 4.0 Service Pack 4 一起发行,是内 置在 Windows 2000、 Windows XP 和 Windows Server 2003 系列操作系统中核心的管理支 持技术。基于由 Distributed Management Task Force (DMTF) 所监督的业界标准,WMI 是 一种规范和基础结构,通过它可以访问、配置、管理和监视几乎所有的 Windows 资源。大多 用户习惯于使用众多的图形化管理工具来管理 Windows 资源,在 WMI 之前这些工具都是通过 Win32 应用程序编程接口(Application ProgrammingInterfaces,API)来访问和管理 Windows 资源的。只要你熟悉系统编程你就知道 API 有多么重要。但是大多数脚本语言都不 能直接调用 Win32 API,WMI 的出现使得系统管理员可以通过一种简便的方法即利用常见的 脚本语言实现常用的系统管理任务。 利用 WMI 需要和脚本如 WSH 和 VBScript 结合起来,可以实现的功能大家可以看微软的 MSDN 文档。 在编写我们自己的脚本之前,我们需要对 WMI 的体系结构有个基本的了解。如图一:(1.gif) 在 WMI 体系结构中我们最需要关心的就是 WMI 提供程序,WMI 提供程序在 WMI 和托管资源之 间扮演着中间方的角色。提供程序代表使用者应用程序和脚本从 WMI 托管资源请求信息,并 发送指令到 WMI 托管资源。下面是我们利用 WMI 编程经常要用到的 WMI 内置提供程序清单, 以供编程参考。 1.Active Directory 提供程序 链接库文件:dsprov.dll 命名空间:root\directory\ldap 作用:将 Active Directory 对象映射到 WMI。 2.事件日志提供程序 链接库文件:ntevt.dll 命名空间:root\cimv2 作用:管理 Windows 事件日志,例如,读取、备份、清除、复制、删除、监视、重命名、 压缩、解压缩和更改事件日志设置。 3.注册表提供程序 链接库文件:stdprov.dll 命名空间:root\default 作用:读取、写入、枚举、监视、创建、删除注册表项和值。 4.Win32 提供程序 链接库文件:cimwin32.dll 命名空间:root\cimv2 作用:提供关于计算机、磁盘、外围设备、文件、文件夹、文件系统、网络组件、操作系统、 打印机、进程、安全性、服务、共享、SAM 用户及组,以及更多资源的信息。 5.Windows 安装程序提供程序 链接库文件:msiprov.dll 命名空间:root\cimv2 作用:提供对已安装软件信息的访问。 从上面可以看出在 WMI 中类(即内置提供程序)被分组到命名空间中,命名空间可以看成是 一个组。比如,命名空间 root\cimv2 包括大部分表示通常与计算机和操作系统相关联的资 源的类。在使用类的时候要说明类所在的命名空间。类由属性和方法构成。这是可视化编程 中的两个重要的概念。属性描述的是对象的状态,方法是对象可以执行的操作。 理论知识学起来很枯燥,下面让我们边分析高手的脚本源码边进行理论知识的巩固吧。 二:解析 RTCS.VBS 主要代码 ================================================================================ ===== 有时候阅读别人的源码未尝不是一个好而且快捷的办法,下面就让我们来认真学习 zzzEVAzzz 编写的一个可以远程开启 telnet 服务的脚本 RTCS.VBS。 该脚本可以直接访问目标的 WMI,不依赖于目标的 ipc$,实现远程开启/关闭目标 telnet 服务, 为了方便大家学习我抽出了最主要的代码,具体分析如下: set objlocator=createobject(“wbemscripting.swbemlocator“) //创建 WbemScripting.SwbemLocator 对象(脚本接口)。 //可以看出 WMI 其实就是把 Com 组件 WbemScripting.SWbemLocator 封装起来罢了。 set objswbemservices=objlocator.connectserver(ipaddress,“root/default“,username,pass word) //通过 ConnectServer 函数请求连接到 WMI 控件服务上,root/default 为命名空间。 set objinstance=objswbemservices.get(“stdregprov“) //建立访问注册表的实例。 set objmethod=objinstance.methods_(“SetDWORDvalue“) //建立可以更改注册表键值的方法。 set objinparam=objmethod.inparameters.spawninstance_() //MethodData.InParameters 用于获取或设置方法的输入参数。这里用 spawninstance 方法 为它建立一个子实例,下面就可以将参数值赋予这个对象的属性。 objinparam.hdefkey=tlntsvr“) //注意:查询都是通过枚举来实现的。 for each objinstance in colinstances if objinstance.startmode=“Disabled“ then set objmethod=objinstance.methods_(“changestartmode“) //创建 changestartmode 方法来改变 tlntsvr 的启动方式。 set objinparam=objmethod.inparameters.spawninstance_() objinparam.startmode=“Manual“ //将启动方式改为手动方式。 set objoutparam=objinstance.execmethod_(“changestartmode“,objinparam) end if //下面启动我们的 telnet 服务。这里 zzzEVAzzz 的思路好象有点不对,也不知道是不是他 的疏忽,我个人认为当 telnet 服务已经启动时不应该用 stopservice 方法停止服务。 if objinstance.started=true then intstatus=objinstance.stopservice() //stopservice 是 WMI 中用于停止服务实例的服务的方法。 else intstatus=objinstance.startservice() end if next 三:手把手教你编写 WMI 版本的 ROTS.vbs 来开启 3389 ================================================================================ ===== zzzVEAzzz 的脚本就分析到这里吧,怎么样?很 EASY 吧?!我相信大家现在一定蠢蠢欲动 了?:)好,一起来写一个什么程序呢?ROTS.vbs 我想大家一定都用过吧?什么东东啊? 我……砸!大家应该知道这个 ROTS 是有它的使用条件的,不仅要有管理员帐号,还要允许进 行 ipc 连接,在这个到处都是墙的年代,ipc 早就不实用了,而且 ROTS.vbs 早就被查杀了, 那该怎么办?当然是自己动手了。能不能实现 ROTS 的一样的远程开启 3389 的功能而不受 ipc 的限制呢?答案自从我写了这篇文章后成为肯定的,哈哈,吹吹了。 当然我们也是要求系统至少是 2000server 及以上的,最近看到有个软件可以给 2000pro 开 3389,由于比较忙,也没怎么去理它,这里我们暂且不说它,知道了原理一样好办。 开启 3389 有个注册表导入的方法,其它一些软件的开法,我想也大多是通过修改注册表实 现的。这个方法需要导入如下的注册表: Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\netcache] “Enabled“=“0“ [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon] “ShutdownWithoutLogon“=“0“ [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer] “EnableAdminTSRemote“=dword:00000001 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server] “TSEnabled“=dword:00000001 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TermDD] “Start“=dword:00000002 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TermService] “Start“=dword:00000002 [HKEY_USERS\.DEFAULT\Keyboard Layout\Toggle] “Hotkey“=“1“ 原理知道了就没什么难的了,先理清我们的思路,我们的主要任务是更改注册表里的键值。 首先是创建 WMI 对象,然后是连接到远程 WMI 服务器,最后修改注册表键值。 部分主要代码如下(完整的代码和详细的注释请看附带的软件包) on error resume next //防止出现意外。 set outstreem=wscript.stdout if (lcase(right(wscript.fullname,11))=“wscript.exe“) then set objShell=wscript.createObject(“wscript.shell“) objShell.Run(“cmd.exe /k cscript //nologo “ /// for (int i = 0; i /// public sealed class WMI { private ArrayList mocs; private StringDictionary names; // 用来存储属性名,便于忽略大小写查询正确名称。 /// /// 信息集合数量 /// public int Count { get { return mocs.Count; } } /// /// 获取指定属性值,注意某些结果可能是数组。 /// public object this[int index, string propertyName] { get { try { string trueName = names[propertyName.Trim()]; // 以此可不区分大小写获得正确的属 性名称。 Hashtable h = (Hashtable)mocs[index]; return h[trueName]; } catch { return null; } } } /// /// 返回所有属性名称。 /// /// /// public string[] PropertyNames(int index) { try { Hashtable h = (Hashtable)mocs[index]; string[] result = new string[h.Keys.Count]; h.Keys.CopyTo(result, 0); Array.Sort(result); return result; } catch { return null; } } /// /// 返回测试信息。 /// /// public string Test() { try { StringBuilder result = new StringBuilder(1000); for (int i = 0; i /// 构造函数 /// /// public WMI(string path) { names = new StringDictionary(); mocs = new ArrayList(); try { ManagementClass cimobject = new ManagementClass(path); ManagementObjectCollection moc = cimobject.GetInstances(); bool ok = false; foreach(ManagementObject mo in moc) { Hashtable o = new Hashtable(); mocs.Add(o); foreach (PropertyData p in mo.Properties) { o.Add(p.Name, p.Value); if (!ok) names.Add(p.Name, p.Name); } ok = true; mo.Dispose(); } moc.Dispose(); } catch(Exception e) { throw new Exception(e.Message); } } /// /// 构造函数 /// /// public WMI(WMIPath path): this(path.ToString()) { } } }