手机
当前位置:查字典教程网 >脚本专栏 >vbs >vbs中实现启动两个应用程序,一直等到其中一个程序结束,然后关闭另一个?
vbs中实现启动两个应用程序,一直等到其中一个程序结束,然后关闭另一个?
摘要:问:嗨,脚本专家!这是我想要完成的任务:我想要用一个脚本启动两个可执行文件。第一个应用程序关闭后,我想让这个脚本关闭第二个应用程序,然后退出...

问:

嗨,脚本专家!这是我想要完成的任务:我想要用一个脚本启动两个可执行文件。第一个应用程序关闭后,我想让这个脚本关闭第二个应用程序,然后退出。如何完成上述任务?

--MK

答:

您好,MK。您知道,这是我们喜欢的那种类型的问题。为什么?因为它听起来确实很复杂很棘手。如果有人想找我们做什么事,我们就可以说“您知道,我正在尝试编写这样一个脚本:它能够启动两个应用程序,等到第一个关闭后,然后自动关闭第二个。”然后他们肯定会说“噢,很抱歉。很显然,你们很忙”,然后就不找我们了。

当然,他们不知道,这只是听起来很困难。其实,它的难度也就相当于下面这个脚本而已:

复制代码 代码如下:

strComputer="."

SetobjWMIService=GetObject("winmgmts:"&strComputer&"rootcimv2:Win32_Process")

errResult=objWMIService.Create("calc.exe",null,null,intCalcID)

errResult=objWMIService.Create("notepad.exe",null,null,intNotepadID)

SetobjWMIService=GetObject("winmgmts:"&strComputer&"rootcimv2")

SetcolProcesses=objWMIService.ExecNotificationQuery_

("Select*From__InstanceDeletionEvent"_

&"Within1WhereTargetInstanceISA'Win32_Process'")

DoUntili=999

SetobjProcess=colProcesses.NextEvent

IfobjProcess.TargetInstance.ProcessID=intCalcIDThen

ExitDo

EndIf

Loop

SetcolProcesses=objWMIService.ExecQuery_

("Select*fromWin32_ProcessWhereProcessID="&intNotepadID)

ForEachobjProcessincolProcesses

objProcess.Terminate()

Next

真的,请相信我们:您了解了脚本所完成的工作后,这其实就变得相当简单了。我们首先连接到计算机上的WMI服务,具体地说,绑定到Win32_Process类。这就是我们现在要做的:

SetobjWMIService=GetObject("winmgmts:"&strComputer&"rootcimv2:Win32_Process")

然后,我们使用Create方法创建两个新进程:Calc.exe和Notepad.exe。对于每个新进程,我们使用与下面这行代码类似的代码:

errResult=objWMIService.Create("calc.exe",null,null,intCalcID)

我们剩下要做的只是调用跟有下列内容的Create方法:

•可执行文件的名称(可能需要指定应用程序的完全路径名称,视您的计算机的设置而定)。

•一对Null参数。使用这两个参数,我们可以为应用程序指定不同的工作文件夹和配置某些其他启动选项。在本示例代码中,我们不需要考虑这些事情,因此我们只是将参数值设置为Null。

•起“输出参数”作用的变量(名称为intCalcID)。创建这些进程后,分配给进程的ProcessID号也分配给这些输出参数变量。

最终结果是我们启动“计算器”,并且变量intCalcID中包含分配给“计算器”实例的进程ID。然后,我们启动“记事本”,并且变量intNotepadID中包含分配给“记事本”实例的ProcessID。这就是启动两个应用程序并且跟踪它们的方法。

下一步我们要做的是,嗯,基本没什么了:我们要此脚本暂停,直到关闭“计算器”。要完成此任务,我们重新连接到WMI服务,然后使用ExecNotificationQuery监视任何删除的进程。我们需要重新连接到WMI服务是因为在脚本的开始我们只是连接到Win32_Process类;因此,对象引用(objWMIService)只是引用此类。我们需要连接到“通用”WMI服务,所以我们只是重新使用对象引用objWMIService并进行新连接:

SetcolProcesses=objWMIService.ExecNotificationQuery_

("Select*From__InstanceDeletionEvent"_

&"Within1WhereTargetInstanceISA'Win32_Process'")

这么做的原因何在?每次删除一个进程,都要生成一个__InstanceDeletionEvent类实例。我们要检查每个实例,看这些实例的进程ID是否为目标ID,也就是分配给intCalcID的ID。如果删除的进程具有不同的ID,则它不是“计算器”实例;在这种情况下,脚本将恢复监视。如果删除的进程具有与intCalcID相同的ID,则它一定是“计算器”实例(因为进程ID必须是唯一的)。在这种情况下,我们要停止监视,然后关闭“记事本”。

下面是实际执行监视的代码:

DoUntili=999

SetobjProcess=colProcesses.NextEvent

IfobjProcess.TargetInstance.ProcessID=intCalcIDThen

ExitDo

EndIf

Loop

这里我们做的是设置一个循环,该循环一直运行到变量i等于999。现在,事实是变量i将始终不等于999;这只是个小技巧,确保循环一直运行到“计算器”关闭。(我们如何知道变量i将始终不等于999?是这样,我们没有为i赋值;因此,它取默认值0。因为我们从未对该值进行任何更改,所以i始终为0,因此将始终不等于999。)

在循环中,我们使用此行代码等待下一个删除的进程:

SetobjProcess=colProcesses.NextEvent

每次删除进程我们都检查ProcessID与分配给“计算器”的进程ID是否相符。如果相符,我们则使用ExitDo命令断开循环,继续脚本。如果不具有相同的ID,则我们只需继续循环,等待下一个删除的进程。(正如我们上面所说的,i将始终不等于999,但是没关系:使用ExitDo命令就可以脱离循环。)

注意。我们发现,我们有点草草掠过事件监视的整个思路。如果您对诸如__InstanceDeletionEvent和colProcesses.NextEvent的内容有点糊涂,请参阅脚本专家网络广播防患于未然:WMI事件简介(英文)。

现在,我们只需要终止我们启动的“记事本”实例。要完成此任务,我们使用此WMI查询检索具有分配给“记事本”的进程ID的所有进程的集合:

SetcolProcesses=objWMIService.ExecQuery_

("Select*fromWin32_ProcessWhereProcessID="&intNotepadID)

获得此集合后,我们使用此代码块在整个进程集(只有一个进程)中循环,然后使用Terminate方法关闭应用程序:

ForEachobjProcessincolProcesses

objProcess.Terminate()

Next

顺便说一句,此方法既适用于远程计算机也适用本地计算机;只需将变量strComputer的值更改为远程计算机的名称。但是,要记住,在WindowsXP和WindowsServer2003中,在远程计算机上启动的进程是在不可见的窗口中运行的;它们在屏幕上不可见。这意味着,处理远程计算机时,对于不需要任何用户交互的应用程序,此方法很有用;而对于确实需要用户干预的应用程序,此方法远不及其他方法有用(实际上完全没用)。

【vbs中实现启动两个应用程序,一直等到其中一个程序结束,然后关闭另一个?】相关文章:

VBS教程:方法-Copy 方法

几段非常有用的脚本(来自微软网站,由downmoon精心收集)

用vbs 实现从剪贴板中抓取一个 URL 然后在浏览器中打开该 Web 站点

用vbs列出注册表中 Run 项中的所有项目

通过vbs修改目录名称与快捷方式名称的实现代码

查看或修改Windows系列系统的序列号的vbs

用vbs控制iis创建虚拟目录的代码

VBS教程:运算符-运算符优先级

vbscript 调用WebService实现代码

用vbs实现按创建日期的顺序列出一个文件夹中的所有文件

精品推荐
分类导航