代码之家  ›  专栏  ›  技术社区  ›  wergeld

vbscript结束由.bat文件启动的进程

  •  0
  • wergeld  · 技术社区  · 15 年前

    我有一个场景设置,需要在其中测试.bat文件执行的结果是否返回结果。.bat文件调用另一个.exe文件,.bat文件有一个cmd dos窗口,该窗口从.exe向该dos框输出关键错误信息。如果.exe不能正确启动,我就可以检查SQL数据库中的结果。我需要关闭当前的.bat文件并重新启动它。 这看起来相当简单,我可以使用wmi调用获取processID。我可以使用terminate()命令终止进程。这适用于我用于测试的任何.exe:记事本、Calc、IExplorer等。当我运行vbscript杀死.bat文件时,它表示它终止pid(它确实终止了,因为我再也看不到pid),但是,DOS框仍然打开,从.bat文件调用的.exe仍在运行。如果我单击DOS框上的“X”或右键单击标题栏并选择“关闭”,则DOS框和.exe都将被杀死。如何使此脚本正确工作。服务器正在运行Windows Server 2003(有些是x32,另一些是x64)。有什么想法吗?这是我的代码版本,有几个版本:

    If colFiles.Count = 0 Then
    Wscript.Echo "The file does not exist on the remote computer."
    Else
    Wscript.Echo "The file exists on the remote computer."
    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process")
    For Each objItem in colProcessList
    If InStr(objItem.CommandLine, "r15_A.bat") Then
        Wscript.Echo "Batch file: " & objItem.CommandLine  & "  Process ID: " & objItem.ProcessID & "  Parent ID: " & objItem.ParentProcessID
        Call TerminateProcess(objItem.ParentProcessID)
        Call TerminateProcess(objItem.ProcessID)
    End If
    Next
    dim shell
    set shell=createobject("wscript.shell")
    shell.run BATDIR & BATFILE
    'set shell=nothing
    End If
    
    
    Function TerminateProcess(PID)
    
    Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
    Set colProcesses = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Handle = '" & PID & "'")
    For Each objProcess in colProcesses
    On Error Resume Next
    return = objProcess.Terminate()
    Set colProcesses = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Handle = '" & PID & "'")
    
    If Error Then
    
    TerminateProcess = FALSE
    Else
    TerminateProcess = TRUE
    msgBox colProcesses.Count
    End If
    Next
    
    End Function
    

    我甚至尝试使用sendkeys发送alt-f4、x、c等。AppActivate确实将正确的DOS框放在了前面。

        Set WshShell = CreateObject("WScript.Shell")
        WshShell.AppActivate "r15_A"
        'WshShell.SendKeys("+{F10}")
        WshShell.SendKeys("C")   
    

    提前谢谢

    编辑---------- 是的,我必须终止这个.bat文件调用的进程。唯一的缺点是这个DOS盒保持打开。很烦人,但我可以忍受。最后,我编写了一个类似于我的第一个脚本的脚本,但只通过检查命令行参数来检查我要杀死的实例:(第一位代码使用“-fail.txt”测试,查看是否存在失败文件,如果存在,则执行其余的scipts)

    Set colFiles = objWMIService. _
    ExecQuery("Select * From CIM_DataFile Where Name = 'S:\\servers\\Logs\\" & LOGFILE & "-FAIL.txt'")
    
    If colFiles.Count = 0 Then
    'Wscript.Echo "The file does not exist on the remote computer."
    Else
    'Wscript.Echo "The file exists on the remote computer."
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    Set colProcessList = objWMIService.ExecQuery _
    ("Select * from Win32_Process Where Name = 'AppStart.exe'")
    For Each objProcess in colProcessList
        IF instr(objProcess.CommandLine, "robo05-A") > 0 THEN 
            'msgBox "Found text"
            objProcess.Terminate()
            'This part restarts the failed .bat file.
            wscript.sleep (200) 
            dim shell
            set shell=createobject("wscript.shell")
            shell.run BATDIR & BATFILE
            'set shell=nothing
        ELSE
            'msgBox "Not found"
        END IF
    Next
    End If
    
    1 回复  |  直到 15 年前
        1
  •  0
  •   mrTomahawk    15 年前

    您的问题是批处理文件中正在调用的可执行文件仍在运行。我试图用球棒重新创建你的设置 ping -t %computername% ,当然,vbscript杀死了cmd.exe,但没有杀死ping(请注意,父PID是explorer.exe,因此您可能不想尝试杀死它)。现在我可以很容易地从任务管理器中杀死ping.exe,然后关闭窗口……但我只知道这样做,因为我知道蝙蝠在做什么,还有什么被打开。您可以对包含“ping.exe”的进程执行一个wmi搜索,获取pid,然后关闭它,这基本上是在做相同的事情。当然,在您的情况下,“ping.exe”可能与我的不同。如果exe不时发生更改,您可以从进程中获取命令行,找到包含R15_a.bat文件的文件路径的参数,然后使用filesystemobject打开此bat文件,查找它调用的任何可能仍在运行的可执行文件,然后终止这些文件……但实际上,这可能会对f或者你想要达到的目标。