vbs中实现启动两个应⽤程序,⼀直等到其中⼀个程序结
束,然后关闭另⼀个?
问:
嗨,脚本专家!这是我想要完成的任务:我想要⽤⼀个脚本启动两个可执⾏⽂件。第⼀个应⽤程序关闭后,我想让这个脚本关闭第⼆个应⽤程序,然后退出。如何完成上述任务?
-- MK
答:
您好,MK。您知道,这是我们喜欢的那种类型的问题。为什么?因为它听起来确实很复杂很棘⼿。如果有⼈想我们做什么事,我们就可以说“您知道,我正在尝试编写这样⼀个脚本:它能够启动两个应⽤程序,等到第⼀个关闭后,然后⾃动关闭第⼆个。”然后他们肯定会说“噢,很抱歉。很显然,你们很忙”,然后就不我们了。
当然,他们不知道,这只是听起来很困难。其实,它的难度也就相当于下⾯这个脚本⽽已:
vbs小程序代码大全复制代码代码如下:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2:Win32_Process")
errResult = objWMIService.Create("", null, null, intCalcID)
errResult = objWMIService.Create("", null, null, intNotepadID)
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colProcesses = objWMIService.ExecNotificationQuery _
("Select * From __InstanceDeletionEvent " _
& "Within 1 Where TargetInstance ISA 'Win32_Process'")
Do Until i = 999
Set objProcess = colProcesses.NextEvent
If objProcess.TargetInstance.ProcessID = intCalcID Then
Exit Do
End If
Loop
Set colProcesses = objWMIService.ExecQuery _
("Select * from Win32_Process Where ProcessID = " & intNotepadID)
For Each objProcess in colProcesses
objProcess.Terminate()
Next
真的,请相信我们:您了解了脚本所完成的⼯作后,这其实就变得相当简单了。我们⾸先连接到计算机上的 WMI 服务,具体地说,绑定到 Win32_Process 类。这就是我们现在要做的:
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2:Win32_Process")
然后,我们使⽤ Create ⽅法创建两个新进程: 和 。对于每个新进程,我们使⽤与下⾯这⾏代码类似的代码:
errResult = objWMIService.Create("", null, null, intCalcID)
我们剩下要做的只是调⽤跟有下列内容的 Create ⽅法:
• 可执⾏⽂件的名称(可能需要指定应⽤程序的完全路径名称,视您的计算机的设置⽽定)。
• ⼀对 Null 参数。使⽤这两个参数,我们可以为应⽤程序指定不同的⼯作⽂件夹和配置某些其他启动选项。在本⽰例代码中,我们不需要考虑这些事情,因此我们只是将参数值设置为 Null。
• 起“输出参数”作⽤的变量(名称为 intCalcID)。创建这些进程后,分配给进程的 ProcessID 号也分配给这些输出参数变量。
最终结果是我们启动“计算器”,并且变量 intCalcID 中包含分配给“计算器”实例的进程 ID。然后,我们启动“记事本”,并且变
量 intNotepadID 中包含分配给“记事本”实例的 ProcessID。这就是启动两个应⽤程序并且跟踪它们的⽅法。
下⼀步我们要做的是,嗯,基本没什么了:我们要此脚本暂停,直到关闭“计算器”。要完成此任务,我们重新连接到 WMI 服务,然后使⽤ ExecNotificationQuery 监视任何删除的进程。我们需要重新连接到 WMI 服务是因为在脚本的开始我们只是连接到 Win32_Process 类;因此,对象引⽤ (objWMIService) 只是引⽤此类。我们需要连接到“通⽤”WMI 服务,所以我们只是重新使⽤对象引⽤ objWMIService 并进⾏新连接:
Set colProcesses = objWMIService.ExecNotificationQuery _
("Select * From __InstanceDeletionEvent " _
& "Within 1 Where TargetInstance ISA 'Win32_Process'")
这么做的原因何在?每次删除⼀个进程,都要⽣成⼀个 __InstanceDeletionEvent 类实例。我们要检查每个实例,看这些实例的进程 ID 是否为⽬标 ID,也就是分配给 intCalcID 的 ID。如果删除的进程具有不同的 ID,则它不是“计算器”实例;在这种情况下,脚本将恢复监视。如果删除的进程具有与 intCalcID 相同的 ID,则它⼀定是“计算器”实例(因为进程 ID 必须是唯⼀的)。在这种情况下,我们要停⽌监视,然后关闭“记事本”。
下⾯是实际执⾏监视的代码:
Do Until i = 999
Set objProcess = colProcesses.NextEvent
If objProcess.TargetInstance.ProcessID = intCalcID Then
Exit Do
End If
Loop
这⾥我们做的是设置⼀个循环,该循环⼀直运⾏到变量 i 等于 999。现在,事实是变量 i 将始终不等于 999;这只是个⼩技巧,确保循环⼀直运⾏到“计算器”关闭。(我们如何知道变量 i 将始终不等于 999?是这样,我们没有为 i 赋值;因此,它取默认值 0。因为我们从未对该值进⾏任何更改,所以 i 始终为 0,因此将始终不等于 999。)
在循环中,我们使⽤此⾏代码等待下⼀个删除的进程:
Set objProcess = colProcesses.NextEvent
每次删除进程我们都检查 ProcessID 与分配给“计算器”的进程 ID 是否相符。如果相符,我们则使⽤ Exit Do 命令断开循环,继续脚本。如果不具有相同的 ID,则我们只需继续循环,等待下⼀个删除的进程。(正如我们上⾯所说的,i 将始终不等
于 999,但是没关系:使⽤ Exit Do 命令就可以脱离循环。)
注意。我们发现,我们有点草草掠过事件监视的整个思路。如果您对诸
如 __InstanceDeletionEvent 和 colProcesses.NextEvent 的内容有点糊涂,请参阅脚本专家⽹络⼴播防患于未然:WMI 事件简介(英⽂)。
现在,我们只需要终⽌我们启动的“记事本”实例。要完成此任务,我们使⽤此 WMI 查询检索具有分配给“记事本”的进程 ID 的所有进程的集合:
Set colProcesses = objWMIService.ExecQuery _
("Select * from Win32_Process Where ProcessID = " & intNotepadID)
获得此集合后,我们使⽤此代码块在整个进程集(只有⼀个进程)中循环,然后使⽤ Terminate ⽅法关闭应⽤程序:
For Each objProcess in colProcesses
objProcess.Terminate()
Next
顺便说⼀句,此⽅法既适⽤于远程计算机也适⽤本地计算机;只需将变量 strComputer 的值更改为远程计算机的名称。但是,要记住,在 Windows XP 和 Windows Server 2003 中,在远程计算机上启动的进程是在不可见的窗⼝中运⾏的;它们在屏幕上不可见。这意味着,处理远程计算机时,对于不需要任何⽤户交互的应⽤程序,此⽅法很有⽤;⽽对于确实需要⽤户⼲预的
应⽤程序,此⽅法远不及其他⽅法有⽤(实际上完全没⽤)。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论