|
楼主 |
发表于 2011-6-23 08:46
|
显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用 · 内置多项VBA编程加强工具 ★ 免费下载 ★ ★ 使用手册★
无论大家是否感性趣,继续写完。
WMI的体系结构
下面的内容很枯燥乏味,建议你耐心看看,原因有三个:
1、你可以理解WMI的内部运作机制,即你的程序是如何一步步运行,最后得到你想要的结果的。
2、你可以知道WMI有多少类,哪些我们可以使用,各个类负责操控的系统资源是什么。比如要想获得硬盘的信息用什么类?学习下面的内容你自己就可以找到。
3、每个类都能提供什么信息,比如要想的到逻辑磁盘的卷标怎么办?你也可以自己找到。
先来看看WMI的体系结构图
不会插入图片啊?
1、托管资源:是所有逻辑或物理组件,也就是计算机系统、磁盘、外围设备、事件日志、文件、文件夹、文件系统、网络组件、操作系统子系统、打印机、进程、注册表设置、安全性、服务、共享、SAM 用户和组、等Windows 资源。就是我们编程想要的得到的东西。
2、WMI 提供程序:在 WMI 和托管资源之间扮演着通讯员的角色。它把使用者请求使用托管资源的信息发送到 WMI 托管资源。
3、CIMOM(读作 see-mom)处理使用者(就是我们)和提供程序之间的交互,也就是规范和管理使用者如何与WMI 提供程序之间交互。它负责根据使用者请求使用的托管资源的具体内容找到合适的提供程序。
4、CIM 储存库 :wmi要求托管资源用一个统一的架构表示来自不同源的配置和管理信息。也就是不同种类的托管资源要按照统一的结构和模式进行配置和管理以方便编程者使用,CIM 储存库就是这个模板。
5、WMI 脚本库:提供自动化对象集,脚本语言(如 VBScript、Jscript等)利用它访问 WMI 基础结构。就是我们编程使用的语句(代码),必须符合WMI 脚本库的要求。
下面以例1为例说明内部工作流程:
第一步、把我们的要求以代码的形式给出(就是写代码了),经WMI 脚本库检查符合要求后,把我们要得到的具体托管资源的信息发送给CIMOM。
第二步、我们要求获得有关系统服务(Win32_Service)的托管资源信息,CIMOM据此为我们找到了合适的WMI 提供程序(Win32 提供程序)。
第三步、WMI 提供程序根据我们的要求从托管资源中提取Win32_Service类并返回给CIMOM。
第四步、CIMOM根据CIM 储存库架构的要求对Win32_Service类中的信息进行整理,最后提供给使用者。(我们得到了系统的所有服务)
如果你实在是不明白也没关系,毕竟是内部工作机制,不妨碍我们使用。下面的内容很重要!!!
要想根据自己的要求利用WMI获得更多系统信息,你比须了解CIM 储存库的结构。
CIM 储存库的结构化视图 — WMI 架构
1、命名空间:是 CIM 使用的分区机制,控制托管资源类定义的范围和可见性。我们在代码中使用的类(托管资源)根据功能,位置等等被划分为很多组分别存储在多个命名空间中。这里你可以把命名空间看做多个独立的数据库,就像ADO可以操作数据库一样,WMI就是用来操作命名空间这些特殊的数据库的工具。
多数为 Windows 托管资源的类驻留在 root/cimv2 命名空间中(我们编程主要使用这个空间),另一方面,如果要操作注册表你要用到root\DEFAULT 命名空间。
例5、该程序枚举机器上的命名空间,添加CommandButton1,代码如下:
Dim WMILocator As New SWbemLocator
Dim WMIServices As SWbemServices
Dim WMIObjectSet As SWbemObjectSet
Dim WMIObject As SWbemObject
Private Sub CommandButton1_Click()
Sheet1.Cells.Clear
i = 1
Sheet3.Cells.Clear
i = 1
Set WMIServices = WMILocator.ConnectServer(".", "root")
建立到机器根命名空间的链接
Set WMIObjectSet = WMIServices.InstancesOf("__NAMESPACE")
"__NAMESPACE"类中存储所有命名空间的名字
For Each WMIObject In WMIObjectSet
Sheet3.Range("a" & i) = WMIObject.Name
i = i + 1
NextFor Each WMIObject In WMIObjectSet
Sheet1.Range("a" & i) = WMIObject.Name
i = i + 1
Next
End Sub
如上代码只是枚举了上图中“\root”下的空间名,如果你需要所有空间名,您需要修改例5 来递归地连接并枚举每个命名空间。附件中有。
2、类表示计算机所拥有的东西。就像前面的几个例子一样,不同的类里存放了不同的系统资源的信息。你可以把类看做是数据库(命名空间)里的一张表,类的每个实例和它的属性、方法就构成了该表的多个记录。你可以把类的属性看做记录的字段。
例2中Set WMIServices = WMILocator.ConnectServer(".", "root\CIMV2") 这句连接到CIMV2这个数据库。
Set WMIObjectSet = WMIServices.InstancesOf("Win32_USBHub")这句打开了Win32_USBHub这张表。
For Each WMIObject In WMIObjectSet
.Range("a" & i).Value = "U盘" & i
.Range("b" & i).Value = Split(WMIObject.DeviceID, "\")(2) '物理序列号添加到B列
i = i + 1
Next
通过循环枚举类的每个实例并列举了类的几个属性(这相当于我们查询了表里的每条记录并获取了记录中我们想要的字段的值)。
如上图所示,类被分为三大类:
A、系统类:是支持内部 WMI 配置和操作(例如,命名空间配置、命名空间安全性、提供
程序注册以及事件订阅和通知)的类。其特征是类名前有一条下划线。
B、核心和公共类:它们表现抽象类用于派生和创建特定技术的扩展类。其特征是类名前有 CIM_ 前缀。图 1 中四个以 CIM_ 开头的类是核心和公共类。
C、扩展类:是由系统和应用程序软件开发人员创建的特定技术类。其特征是类名前有 WIN32_ 前缀。但是,StdRegProv 类是用于注册表管理任务的扩展类。并且StdRegProv 类在 root\DEFAULT 命名空间而非 root\cimv2 中。
类还可以被划分为以下三类:
A、抽象类 :是用于定义新类的模版。即其他类都是由抽象类构建(或派生)的。其特征
为:拥有Abstract 类限定符(后面会说到)并且其值为TRUE。抽象类极少在 WMI 脚本中使用,这是因为您不能检索抽象类的实例。
B、动态类 :是为从提供程序动态检索的 WMI 托管资源建模的类。其特征为:拥有
Dynamic 类限定符。动态类是我们在 WMI中使用的最常见的类。
C、静态类 :定义物理存储在 CIM 储存库中的数据。其特征为:既没有Abstract 类限定符也没有Dynamic 类限定符。静态类类型最常用于系统类的定义。静态类极少在 WMI 脚本中使用。
总结一下:
1、系统类可以是抽象的或静态的。我们不会用到系统类,除非你要订阅 WMI 事件。
2、核心和公共类中除了CIM_DataFile、CIM_DirectoryContainsFile、CIM_ProcessExecutable 和 CIM_VideoControllerResolution可以为我们利用外,其他全是抽象类。(我们几乎不用它)
3、扩展类几乎全是动态类,这意味着扩展类是您将要在 WMI中使用的主要的类。
4、我们只需关注以WIN32_开头的类,还有四个以CIM_的类以及StdRegProv 类。
例6、该程序以root\CIMV2命名空间为例枚举该命名空间下的类,如果需要其他命名空间的类列表,只需更换root\CIMV2为其他空间名即可,添加CommandButton1,代码如下:
Dim WMILocator As New SWbemLocator
Dim WMIServices As SWbemServices
Dim WMIObjectSet As SWbemObjectSet
Dim WMIObject As SWbemObject
Private Sub CommandButton1_Click()
Sheet1.Cells.Clear
Set WMIServices = WMILocator.ConnectServer(".", "root\CIMV2")
Set WMIObjectSet = WMIServices.SubclassesOf()
SubclassesOf方法返回指定命名空间下所有的类及其子类
i = 1
For Each WMIObject In WMIObjectSet
Sheet1.Range("a" & i) = Split(WMIObject.Path_.Path, ":")(1)
类的实例中的.Path_.Path属性含有类的名字
i = i + 1
Next
End Sub
通过以上学习,你应该可以根据自己的需要在合适的命名空间找到需要的类了。下面通过一个例子说明如何根据需要找到合适的资源。
例7、我现在想要得到磁盘的物理序列号该怎么做(不是逻辑的,注意dir命令显示的那串数字不用格式化就可以轻松更改,网上软件一大堆,这个物理序列号用软件是无法更改的,出厂时就定型了)根据了解的命名空间的知识很容易知道我们应该连接到"root\CIMV2"命名空间,根据了解的类的知识,自然的我们会在带WIN32_ 前缀的类中查找,如果你的英语好的话,你会发现Win32_PhysicalMedia这个类,PhysicalMedi直译为物理媒体,就是硬件了,试一下吧,查看Win32_PhysicalMedia的属性(下面会给出枚举类的属性的例子)发现有个SerialNumber,翻译为串号,就是序列号了,一切就绪,动手吧!SHEET里添加CommandButton1,代码如下:
Option Explicit
Dim WMILocator As New SWbemLocator
Dim WMIServices As SWbemServices
Dim WMIObjectSet As SWbemObjectSet
Dim WMIObject As SWbemObject
Private Sub CommandButton1_Click()
Dim i As Long
Sheet4.Cells.Clear
Set WMIServices = WMILocator.ConnectServer(".", "root\CIMV2") '可以省略,写上是为了更好理解参数的使用
Set WMIObjectSet = WMIServices.InstancesOf("Win32_PhysicalMedia")
i = 1
With Sheet4
For Each WMIObject In WMIObjectSet
.Range("a" & i).Value = "磁盘" & i
.Range("b" & i).Value = Trim(WMIObject.SerialNumber) '物理序列号添加到B列
i = i + 1
Next
End With
Set WMIObject = Nothing
Set WMIObjectSet = Nothing
End Sub
再举一个例子
例8、我现在想要得到机器上所有共享文件夹该怎么做?首先我们应该连接到"root\CIMV2"命名空间,在带WIN32_ 前缀的类中查找,你会发现"Win32_Share"这个类,Share就是共享,试一下吧!CommandButton1,代码如下:
Option Explicit
Dim WMILocator As New SWbemLocator '定义一个指向WMI的指针
Dim WMIServices As SWbemServices
Dim WMIObjectSet As SWbemObjectSet
Dim WMIObject As SWbemObject
Private Sub CommandButton1_Click()
Dim i As Long
Sheet1.Cells.Clear
Sheet1.Range("a1:b1") = Array("共享名", "路径")
Set WMIServices = WMILocator.ConnectServer()
Set WMIObjectSet = WMIServices.InstancesOf("Win32_Share")
i = 2
With Sheet1
For Each WMIObject In WMIObjectSet
.Range("a" & i).Value = WMIObject.Name
.Range("b" & i).Value = WMIObject.Path
i = i + 1
Next
End With
Set WMIObject = Nothing
Set WMIObjectSet = Nothing
End Sub下一节内容学习类的属性和方法,让例1的服务管理器和进程管理器实现一些操作,再配合几个例子说明。
例7在9楼。75楼继续
[ 本帖最后由 wpxxsyzx 于 2011-6-24 11:25 编辑 ]
|
|