|
楼主 |
发表于 2011-6-22 11:04
|
显示全部楼层
建立对WMI对象的引用的方法
例1中第二步Set WMIServices = WMILocator.ConnectServer()中使用ConnectServer方法建立了对WMI对象的引用实例,该方法的句法如下:
WMILocator.ConnectServer(strServer, strNamespace, strUser, strPassword, strLocale, StrAuthority, iSecurityFlags, ObjwbemNamedValueSet)
下面说一下这八个参数(前六个参数全是字符类型):
1、strServer: 计算机名字。缺省为本机,本机也可以用”.”表示,如果对局域网中的其他机器操作,在此处将”.”换成该机器名字。
2、strNamespace :需要登录的CIM命名空间,缺省值为:"root\CIMV2",代表我们工作的WIN32环境。(CIM就是一个存储库,WMI所有的类被分组存储到不同的命名空间中,命名空间是表示一个特定的管理区域的类的逻辑组,关于命名空间我们后面再说并给出枚举所有命名空间的例子)。例如:
Set WMIServices = WMILocator.ConnectServer(“.”, "root\CIMV2"),连接到本地计算机的" "root\CIMV2"命名空间,返回一个对 SWbemServices 对象的引用。
3、strUser :用户名,一般为指定计算机上管理员帐号,仅用于远程操作。
4、strPassword:密码,对应用户名的密码,和第三部分一起使用。例如:
Set WMIServices = WMILocator.ConnectServer(“pc1” , "root\CIMV2",”administrator”,”123”),以administrator用户(密码为:123)连接到PC1的计算机的"root\CIMV2"命名空间,返回一个对 SWbemServices 对象的引用。
5、strLocale :本地化代码(和语言有关),通常省略。
6、StrAuthority :权限信息,很少使用,可以省略。
7、iSecurityFlags :没有实现,如果指定必须为0。
8、ObjwbemNamedValueSet:很少使用,当为连接请求提供服务时,一些提供程序可能需要使用这个参数。
了解了这些后,回到例1,Set WMIServices = WMILocator.ConnectServer()这句的完整写法应该为:
Set WMIServices = WMILocator.ConnectServer(“.”, "root\CIMV2")。
我们的例子中()里参数为空,就是所有参数使用了默认值,因为ConnectServer方法的所有参数都是可选的。
如果连接到本机,通常情况下只需要设置strNamespace参数,其它参数都可以省略,但如果连接到远程计算机,一般需要对前4个参数进行设置。
下面讨论获得WMI类的实例集合的几种方法
1、InstancesOf方法。
该方法用于获得指定类中所有实例,语法如下:
SwbemServices.InstancesOf(strClass,[iFlags][objWbemNamedValueSet])
strClass:要查询的类名(字符串)
iFlags:操作标志,一般使用缺省值(即wbemFlagReturnImmediately),可省略。
objWbemNamedValueSet:未用。
例2:本例枚举你机器上所有U盘的物理序列号(不是卷标哦)U盘的信息存储在Win32_USBHub类中。添加一个CommandButton1到sheet1,代码如下:
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
Set WMIServices = WMILocator.ConnectServer(".", "root\CIMV2") '可以省略,写上是为了更好理解参数的使用
Set WMIObjectSet = WMIServices.InstancesOf("Win32_USBHub")
i = 1
With Sheet1
For Each WMIObject In WMIObjectSet
.Range("a" & i).Value = "U盘" & i
.Range("b" & i).Value = Split(WMIObject.DeviceID, "\")(2) '物理序列号添加到B列
i = i + 1
Next
End With
Set WMIObject = Nothing
Set WMIObjectSet = Nothing
End Sub
因为是枚举了所有USB实例,所以除了U盘还包括机器上的USB接口,我的机器上真正的U盘只一个。(其实你可以利用后面的方法把USB接口排除只留U盘)
它的缺点显而易见:
1、类的实例较多时速度会慢(如果针对局域网中其他计算机使用WMI,网络流量较大)。
2、再者,你只需要特定的几个或一个类的实例时,显然这种方法效率不高。
针对以上情况,我们可以使用以下方法获取类的一个或符合条件的一组实例:
2、使用ExecQuery方法。
该方法配合WQL语句用于获得指定类中所有实例或符合条件的一组实例,语法参数格式如下:
SwbemServices.ExecQuery(strQuery,[strQueryLanguage],[iFlags],[objWbemNamedValueSet])
strQuery:WQL查询语句。
strQueryLanguage:表示所使用的查询语言,可以省去,如添加的话,只能用"WQL"。
iFlags和objWbemNamedValueSet的解释同InstancesOf方法。
例3:获取机器上网卡的名称和其物理地址(它的信息存储在Win32_NetworkAdapterConfiguration类)使用ExecQuery方法和WQL语句排除系统的红外、VPN WAN等端口。添加一个CommandButton1到sheet2,代码如下:
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
Sheet2.Cells.Clear
Sheet2.Range("a1:e1") = Array("名字", "物理地址", "IP地址", "子网掩码", "网关")
Set WMIServices = WMILocator.ConnectServer() '省略参数
Set WMIObjectSet = WMIServices.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE DatabasePath Is Not NULL ")
i = 2
With Sheet2
For Each WMIObject In WMIObjectSet
.Range("a" & i).Value = WMIObject.Description '名字添加到a列
.Range("b" & i).Value = WMIObject.MACAddress '物理地址添加到B列
.Range("c" & i).Value = WMIObject.IPAddress
.Range("d" & i).Value = WMIObject.IPSubnet
.Range("e" & i).Value = WMIObject.DefaultIPGateway
i = i + 1
Next
End With
Set WMIObject = Nothing
Set WMIObjectSet = Nothing
End Sub
“SELECT * FROM Win32_NetworkAdapterConfiguration WHERE DatabasePath Is Not NULL "这句是否很熟悉,这是WQL语句(SOL的子集,具体的使用方法我还没找到,估计和SQL的方法一样)。
说明:
A、如果要在例1中只返回启动方式为“自动”的服务只需改Set WMIObjectSet = WMIServices.InstancesOf("Win32_Service")为Set WMIObjectSet = WMIServices.ExecQuery("SELECT * FROM Win32_Service WHERE StartMode='auto'")就可以了。该句的意思为:从Win32_Service类中返回StartMode属性为auto的所有实例(包括实例的所有属性),“*”代表选择实例的所有属性。
B、“SELECT * FROM Win32_NetworkAdapterConfiguration WHERE DatabasePath Is Not NULL "把这句的where子句全删除,你会发现多出来许多东西。
C、语句中使用了“*” ,说明获得实例的所有属性,如果只需实例的要一个或几个属性该如何呢?例如例中我们只用到了名称和地址两个属性,把该句改为:"SELECT Description, MACAddress FROM Win32_NetworkAdapter WHERE DatabasePath Is Not NULL " 。效果是一样的。以上三点自己动手试一下。
3、使用Get方法。
该方法用于获得指定类中符合条件的一个实例,语法参数格式如下:
SwbemServices.Get([strObjectPath][.KeyProperty='Value'],[iFlags],[objWbemNamedValueSet])
strObjectPath:类的名字
KeyProperty:主键属性名,Value是指定的主键属性值。通过指定此项就可返回类中KeyProperty属性值为Value的唯一的实例。
iFlags和objWbemNamedValueSet与ExecQuery方法中的说明相同。
例4:CPU的信息存储在Win32_Processor类里。通常我们只有一个CPU,再用上面枚举全部或部分实例的方法显得多余,本例获取我们的第一个CPU的相关信息。添加一个CommandButton1到sheet3,代码如下:
Option Explicit
Dim WMILocator As New SWbemLocator
Dim WMIServices As SWbemServices
Dim WMIObject As SWbemObject
Private Sub CommandButton1_Click()
Sheet3.Cells.Clear
Sheet3.Range("a1:e1") = Array("类型", "频率", "二级缓存", "接口类型", "核心数")
Set WMIServices = WMILocator.ConnectServer() '省略参数
Set WMIObject = WMIServices.Get("Win32_Processor.DeviceID='cpu0'")
With Sheet3
.Range("a2").Value = WMIObject.Name '添加cpu类型,cpu发展太快,wmi没跟上,可能和实际不符
.Range("b2").Value = WMIObject.CurrentClockSpeed / 1000 & "GHz"
.Range("c2").Value = WMIObject.L2CacheSize & "K"
.Range("d2").Value = WMIObject.SocketDesignation
.Range("e2").Value = WMIObject.NumberOfLogicalProcessors & "核"
.Range("f2").Value = WMIObject.ProcessorId
End With
Set WMIObject = Nothing
End Sub
好了,现在你对使用WMI应该比较熟悉了吧。如果你感觉还是比较混乱的话,我们在回顾一下:
1、用Dim WMILocator As New SwbemLocator建立对WMI对象的引用实例
2、用Set WMIServices = WMILocator.ConnectServer(机器名,命名空间)连接到指定计算机的指定名字空间的WMI服务
3、用Set WMIObjectSet = WMIServices.InstancesOf(“类名”),返回指定类名的所有实例
现在令你感到困惑的可能是:类有多少,在哪,各是什么作用,什么是命名空间等等,这关系到WMI的体系结构,下一节学习。吃饭去喽。24楼继续
[ 本帖最后由 wpxxsyzx 于 2011-6-23 09:01 编辑 ] |
评分
-
2
查看全部评分
-
|