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
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 命令就可以脱离循环。)
For Each objProcess in colProcesses objProcess.Terminate() Next
顺便说一句,此方法既适用于远程计算机也适用本地计算机;只需将变量 strComputer 的值更改为远程计算机的名称。但是,要记住,在 Windows XP 和 Windows Server 2003 中,在远程计算机上启动的进程是在不可见的窗口中运行的;它们在屏幕上不可见。这意味着,处理远程计算机时,对于不需要任何用户交互的应用程序,此方法很有用;而对于确实需要用户干预的应用程序,此方法远不及其他方法有用(实际上完全没用)。