VB使用WMI编程讲座.docx
- 文档编号:30133533
- 上传时间:2023-08-05
- 格式:DOCX
- 页数:64
- 大小:196.12KB
VB使用WMI编程讲座.docx
《VB使用WMI编程讲座.docx》由会员分享,可在线阅读,更多相关《VB使用WMI编程讲座.docx(64页珍藏版)》请在冰豆网上搜索。
VB使用WMI编程讲座
VB使用WMI编程讲座(原创)
一、认识WMI
通常VB程序员经常抱怨VB在编制Windows系统软硬件设备控制方面的程序比较困难,即使能实现一些功能,那也是要通过调用繁复的API函数,即难找寻到合适的函数,又难以理解设置函数中的各项参数,尤其是调试异常困难,动不动整个程序连带VB环境一起死悄悄。
此外,用API编程几乎完全抛弃了面向对象的编程方法,迫使我们回到过程方式的编程。
那怎么办呢?
^_^别急,微软在WIN2000系统中推出了VBScript脚本语言替代原来的批命令,同时提供了一个供VBScript管理Windows系统的对象WMI。
那这个WMI对象我们VB能用吗?
答案是肯定的,当然能用,而且用起来还非常方便,在网上也已经有了一些VB写的利用WMI实现Windows系统管理编程的例程,但却缺少系统性介绍使用VB对WMI编程的资料。
本文就针对此问题,进行一个尝试。
当然要学习WMI编程,需要有一定的VB基础,但要求不高,只要会用控件、对象,能理解和使用对象的方法、属性,但不需要任何API方面的知识和编程经验。
首先我们要知道什么是WMI?
WMI是WindowsManagementInstrumentation(Windows管理工具)的缩写,是内置在Windows2000、WindowsXP和WindowsServer2003系列操作系统中核心的管理支持技术。
基于由DistributedManagementTaskForce(DMTF)所监督的业界标准,WMI是一种规范和基础结构,通过它可以访问、配置、管理和监视所有的—几乎所有的Windows资源。
呵呵,不要对这段文字进行咬文嚼字,通俗的讲,就是WMI是一个用于管理Windows系统的对象,就像ADO对象是用于数据库操作的。
利用WMI我们可以管理Windows系统中的磁盘、事件日志、文件、文件夹、文件系统、网络组件、操作系统设置、性能数据、打印机、进程、注册表设置、安全性、服务、共享、用户、组等等。
而WMI适用的运得环境也是有些限制的,WMI附带在WindowsMe、Windows2000、WindowsXP和WindowsServer2003之中。
对于Windows98和WindowsNT4.0,可以访问ManagementInstrumentation(WMI)CORE1.5(Windows95/98/NT4.0)”。
注意:
在WindowsNT4.0上安装并运行WMI之前,需要首先安装ServicePack4或更高版本。
WMI需要的其他软件包括:
1.MicrosoftInternetExplorer5.0或更高版本。
2.WindowsScriptHost(WSH)。
Windows2000、WindowsXP、WindowsServer2003、和WindowsMe附带的WSH,而不是WindowsNT4或Windows98附带的WSH。
您可以从以下地址下载WSHWSH的最新版本——包括在WindowsXP和WindowsServer2003之中——是WSH5.6。
要使WMI脚本可以正常的运行,Windows里的WMI服务(winmgmt)保证是运行的,这样才可以实现WMI里的更多功能。
好了,关于WMI的一些基本的信息资料就说到这,要想看更多的可以到MicroSoft网站的MSDN找。
大家都喜欢通过例程来学东西,那我们也先编一段程序来看看。
不知道大家看到过没有本人在本论坛中曾经写过一篇“自己做进程管理器”的帖子,在那篇帖子里主要是采用API函数罗列出当前系统下正在运行的所有进程,下面我们利用WMI也来做一个进程管理器。
首先建立一个新工程具有Form1窗体,在菜单中的【工程】—【部件】下,添加“MicrosoftWindowsCommonControls6.0”,在菜单中的【工程】—【引用】下,添加“MicrosoftWMIScriptingV1.1Library”,然后在Form1窗体上添加1个ListView1和Command1、Command2,在代码窗口添加如下代码(例程1):
OptionExplicit
DimobjSWbemLocatorAsNewSWbemLocator
DimobjSWbemServicesAsSWbemServices
DimobjSWbemObjectSetAsSWbemObjectSet
DimobjSWbemObjectAsSWbemObject
PrivateSubForm_Load()
Me.Caption="进程管理器"
Command1.Caption="刷新"
Command2.Caption="结束进程"
ListView1.ColumnHeaders.Clear
ListView1.ColumnHeaders.Add,"a","进程ID",600
ListView1.ColumnHeaders.Add,"b","进程名",2000
ListView1.ColumnHeaders.Add,"c","路径",6000
ListView1.View=lvwReport
Command1_Click'刷新进程列表
EndSub
PrivateSubCommand1_Click()
DimiAsLong
ListView1.ListItems.Clear'清空ListView
SetobjSWbemServices=objSWbemLocator.ConnectServer() '连接到本机的WMI,返回一个对SWbemServices对象的引用
SetobjSWbemObjectSet=objSWbemServices.InstancesOf("Win32_Process") '返回Win32_Process类名标识的所有实例
i=0
ForEachobjSWbemObjectInobjSWbemObjectSet '枚举每一个Win32_Process的实例
ListView1.ListItems.Add,"a"&i,objSWbemObject.Handle'将进程ID添加到ListView1第一列
ListView1.ListItems("a"&i).SubItems
(1)=objSWbemObject.Name'将进程名添加到ListView1第二列
IfNotIsNull(objSWbemObject.ExecutablePath)Then_
ListView1.ListItems("a"&i).SubItems
(2)=objSWbemObject.ExecutablePath'将进程路径添加到ListView1第三列
i=i+1
Next
SetobjSWbemObjectSet=Nothing
EndSub
PrivateSubCommand2_Click()
DimTMBackAsLong
IfListView1.SelectedItem.Text<>""Then
IfMsgBox("确实要结束进程["&ListView1.SelectedItem.SubItems
(1)&"]吗?
",vbYesNo)=vbYesThen
SetobjSWbemObjectSet=objSWbemServices.ExecQuery("SELECT*FROMWin32_ProcessWHEREHandle='"&ListView1.SelectedItem.Text&"'") '查询Win32_Process类中Handle属性等于指定值的所有实例
ForEachobjSWbemObjectInobjSWbemObjectSet
TMBack=objSWbemObject.Terminate '终止指定进程
Next
IfTMBack=0Then
MsgBoxListView1.SelectedItem.SubItems
(1)&"已经被终止!
"
Else
MsgBoxListView1.SelectedItem.SubItems
(1)&"不能被终止!
"
EndIf
Command1_Click'刷新进程列表
EndIf
EndIf
EndSub
呵呵,我们没有用任何系统的API函数却千真万确的实现了进程管理这个系统级的应用,而且采用的是标准的面向对象的编程,其实这段代码仅仅实现了我们在前面提到的一篇“自己做进程管理器”的帖子中用API函数也能实现的功能。
嗯?
?
?
怎么?
还能比这更强?
哈哈,当然!
!
下一讲我们分析该例程时,还会告诉各位,将该例程稍加修改,就可以在你的局域网中对任何一台WIN2000以上的计算机进行进程管理!
晕!
那不是我就能在我的局域网中为所欲为了吗?
别急,那当然是有条件的,微软当然不会允许XX就可以随便控制其它的计算机的。
因为本人平时工作还是比较忙的,只有抽空就继续写,打算每星期写一讲,本次算是第一讲,下一讲主要结合本讲的例程,介绍在VB中使用WMI的基本方法。
二、VB中使用WMI的基本方法
上一讲我们初步了解了一下WMI,并在VB中使用WMI对象做了一个进程管理器,为加深各位的对WMI对象引用方法的程序结构印象和增加兴趣,我们再举一个例子,就是枚举当前系统所有服务的名称、状态和启动类型等。
与例程1一样,首先建立一个新工程具有Form1窗体,在菜单中的【工程】—【部件】下,添加“MicrosoftWindowsCommonControls6.0”,在菜单中的【工程】—【引用】下,添加“MicrosoftWMIScriptingV1.1Library”,然后在Form1窗体上添加1个ListView1,在代码窗口添加如下代码(例程2):
OptionExplicit
DimobjSWbemLocatorAsSWbemLocator
DimobjSWbemServicesAsSWbemServices
DimobjSWbemObjectSetAsSWbemObjectSet
DimobjSWbemObjectAsSWbemObject
DimstrComputerAsString,strNameSpaceAsString,strClassAsString
PrivateSubForm_Load()
DimiAsLong
Me.Caption="服务"
ListView1.ColumnHeaders.Clear
ListView1.ColumnHeaders.Add,,"名称",2600
ListView1.ColumnHeaders.Add,,"状态",1000
ListView1.ColumnHeaders.Add,,"启动类型",1000
ListView1.ColumnHeaders.Add,,"路径",2600
ListView1.ColumnHeaders.Add,,"登录身份",1400
ListView1.View=lvwReport
strComputer="." '计算机名,.为本机
strNameSpace="root\cimv2"'指定命名空间为root\cimv2
strClass="Win32_Service" '指定类为Win32_Service
SetobjSWbemLocator=CreateObject("WbemScripting.SWbemLocator") '建立1个WBEM对象的引用指针
SetobjSWbemServices=objSWbemLocator.ConnectServer(strComputer,strNameSpace) '连接到指定计算机、命名空间的WMI,返回一个对SWbemServices对象的引用
SetobjSWbemObjectSet=objSWbemServices.ExecQuery("SELECT*FROM"&strClass) '通过WQL查询,返回指定类的所有实例
ForEachobjSWbemObjectInobjSWbemObjectSet
ListView1.ListItems.Add,"a"&i,objSWbemObject.DisplayName'将服务名称添加到ListView1第一列
ListView1.ListItems("a"&i).SubItems
(1)=objSWbemObject.State'将服务的状态添加到ListView1第二列
ListView1.ListItems("a"&i).SubItems
(2)=objSWbemObject.StartMode'将服务的启动方式添加到ListView1第三列
ListView1.ListItems("a"&i).SubItems(3)=objSWbemObject.PathName'将服务程序的路径添加到ListView1第四列
ListView1.ListItems("a"&i).SubItems(4)=objSWbemObject.StartName'将服务的登录身份添加到ListView1第五列
i=i+1
Next
SetobjSWbemObject=Nothing
SetobjSWbemObjectSet=Nothing
EndSub
嘿,我们运行这个例程后,果然把自己计算机上所有的服务都列了出来,并且还知道这些服务目前的运行状态以及服务程序所在的目录和执行文件名。
美中不足的是似乎我们不能停止或启动某个服务,不要急,其实可以很方便的就增加停止或启动某个服务的功能,但因为本节主要是要讨论VB中使用WMI的基本方法,因此故意省略了其它一些功能的实现。
闲话少说言规正传,现在我们就开始讨论一下VB中使用WMI的基本方法。
例程2与例程1相比,除了功能不一样外,精简了程序结构,因此我们就以例程2的结构为主进行讨论。
我们先来观察一下例程1和例程2,可以看到它们都添加了“MicrosoftWMIScriptingV1.1Library”的引用,这个对象库(以下简称WMI脚本对象库)就是我们在VB的WMI编程中所要依赖的。
再看一下程序的定义部分和整个程序的首次执行过程,它们基本相同:
都定义了SwbemLocator、SwbemServices、SwbemObjectSet、SwbemObject对象;创建了SwbemLocator指针实例;通过SwbemLocator指针连接到WMI服务;检索一个WMI托管资源;枚举托管资源中的每个实例;显示各实例的一些属性。
其实这些步骤对于任何用于检索WMI托管资源信息的程序来说都是共同的,下面我们就详细的分析一下各步骤。
1)创建SwbemLocator指针
创建SwbemLocator指针的目的是为了建立一个引用WMI对象的实例,然后用这个实例操作WMI。
有没有注意到,例程1和例程2创建SwbemLocator指针稍有不同,例程1是在定义处用DimobjSWbemLocatorAsNewSwbemLocator定义语句直接创建了,而例程2是在执行过程Form_Load中用SetobjSWbemLocator=CreateObject("WbemScripting.SWbemLocator")语句创建的,其实可以将这条语句简化为SetobjSWbemLocator=NewSwbemLocator来创建。
不管用哪种方式创建SwbemLocator指针,都不影响下面的步骤。
SwbemLocator指针对象只有1个只读属性Security_(其实也是一个对象)和1个方法ConnectServer,第二步中我们就会讨论用此方法连接到WMI服务。
2)连接到WMI服务
要用WMI对象编程,必须连接到目标计算机的WMI服务,然后返回一个SwbemServices对象。
比较一下例程1和例程2的连接方法,它们都用SwbemLocator指针对象的ConnectServer方法实现,不过例程1没有用任何参数,例程2中增加了strComputer和strNameSpace二个参数。
ConnectServer方法共有8个参数,所有参数都是可选的,因此我们看到例程1中没有用任何参数,即全部使用缺省参数。
下面我们看一下这8个参数:
strServer计算机名字,如果这台远程计算机与你不是同一个主域,需要完整的带域名的全称,例如:
”cp1.xxxx.yyy”。
缺省为本机,本机也可以用”.”
strNamespace需要登录的CIM命名空间,例如:
"root\CIMV2"。
缺省为"root\CIMV2"。
(CIM就是一个存储库(架构),包括模型化托管环境和定义每个由WMI公开的数据块的对象储存库或类存储,WMI所有的类被分组到命名空间中,命名空间是表示一个特定的管理区域的类逻辑组,在这里就不深入分析了)
strUser用户名,一般必须为指定计算机上管理员帐号,也可以是指定主域的用户名,例如:
"DomainName\UserName"。
缺省为当前登录系统帐号的用户名。
strPassword口令(密码),对应用户名的口令
strLocale本地化代码,通常为空。
StrAuthority验证字符串,通常为空,如果不为空,则只能用于“Kerberos”或“NTLMDomain”。
iSecurityFlags延迟时间(注:
中文解释为本人理解,似乎和英文意思不一样),当为0时,直到连接成功为止,这就有可能因为连接不成功时长时间等待。
当为wbemConnectFlagUseMaxWait(数值为128),则确保不超过2分钟返回。
ObjwbemNamedValueSet为wbemNamedValueSet对象,在这里就不展开了。
如果连接到本机,通常情况下只需要设置strNamespace参数,其它参数都可以省略,但如果连接到远程计算机,一般需要对前4个参数进行设置。
这里要注意的是,连接到WMI服务是指连接到一个指定的CIM命名空间(如果还不能理解什么是CIM命名空间,也没关系,在后面的章节中还会讨论CIM命名空间),所以也可以认为本步骤就是:
连接到一个指定的CIM命名空间,即使你不设置strNamespace参数,那也是连接到缺省的CIM命名空间,通常缺省的CIM命名空间为"root\CIMV2",你可以通过你计算机上的注册表查看或修改HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WBEM\Scripting\DefaultNamespace项的值。
3)获得WMI托管资源(类)的实例集合
当完成了连接到WMI服务后,我们就需要根据要执行的任务,选择不同的类(这些类都是WMI的托管资源)。
在上一步中,我们已经知道是连接到一个指定的CIM命名空间,而每个命名空间都驻留了许多类,本步骤就是根据要求获得我们所需类的实例集合。
我们还是通过例程来讨论。
在例程1中,我们通过SwbemServices对象的InstancesOf方法,参数为我们所需的"Win32_Process"类,然后返回由指定类名标识("Win32_Process")的托管资源的所有实例。
而在实例2中,我们通过SwbemServices对象的ExecQuery方法,参数为"SELECT*FROMWin32_Service"(细心的读者可能发现参数好像与例程2中的并不完全相同,但你再看一下该语句执行前,已经对strClass变量赋予了"Win32_Service"值),然后返回的却是由指定类名标识("Win32_Service")的托管资源的所有实例。
2个例程用了2个方法都获得指定类名标识的托管资源的所有实例,那可不可以调换过来用呢?
当然可以!
在例程1中,我们完全可以用SetobjSWbemObjectSet=objSWbemServices.ExecQuery("SELECT*FROMWin32_Process")替换原语句,在例程2中用SetobjSWbemObjectSet=objSWbemServices.InstancesOf("Win32_Service")替换原语句。
既然可以互相替换,那是不是说这2种方法是一样的呢?
实际上这2种方法是有区别的。
InstancesOf方法就象其名字所体现的一样,返回所有指定类实例,所以用起来非常方便。
但方便往往与灵活和高效是矛盾的,假设您只想要实例或属性的一个子集的情形又怎么样呢?
假设您想要优化实例和属性恢复到最小的网络流量。
在这种情况下,您会非常高兴听到WMI支持大量强大的查询工具。
查询WMI是向匹配一些预定义条件的托管资源发出请求的过程。
例如,WMI查询只要求那些处于Stopped(停止)状态的服务,则例程2中,我们可以将该条语句改成:
SetobjSWbemObjectSet=objSWbemServices.ExecQuery("SELECT*FROMWin32_Service WHEREState='Stopped'")就可以了。
WMI查询为检索托管资源实例及其属性提供了比InstancesOf方法更有效率的机制。
WMI查询只返回那些匹配查询的实例和属性,但是InstancesOf总是返回一个指定资源的所有实例以及每个实例的所有属性。
同样,查询是在与对象路径中一致的目标计算机上进行的,而不是在运行的源计算机上。
因此,WMI查询可以显著地减
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VB 使用 WMI 编程 讲座
![提示](https://static.bdocx.com/images/bang_tan.gif)