我有一个场景设置,我需要测试以查看.bat文件执行的结果是否返回结果。 .bat文件调用另一个.exe文件,.bat文件有一个CMD DOS窗口,它从.exe输出关键错误信息到该DOS框。如果.exe无法正确启动,我可以在SQL DB中检查结果。我需要关闭当前的.bat文件并重新启动它。 这看起来相当简单,我可以使用WMI调用获取ProcessID。我可以使用Terminate()命令终止进程。这适用于我用于测试的任何.exe:记事本,计算,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")
提前致谢
EDIT -------------- 是的,我将不得不杀死此.bat文件调用的进程。只有在这个DOS框保持打开的情况下。很烦人,但我可以忍受它。最后我编写了一个类似于我的第一个脚本的脚本,但只通过检查CommandLine参数来检查我要杀死的实例:(使用“-FAIL.txt”测试的第一段代码,看看是否存在FAIL文件,如果是,那么其余的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
答案 0 :(得分:0)
您遇到的问题是批处理文件中正在调用的可执行文件仍在运行。我试图用蝙蝠重新创建你的设置刚刚做了ping -t %computername%
,确定vbscript杀死了cmd.exe而不是ping(请注意,父PID是explorer.exe,所以你可能不会想要尝试杀死那个)。现在我可以轻松地从任务管理器中杀死ping.exe,然后关闭窗口...但我只知道这样做,因为我知道蝙蝠正在做什么以及什么是开放的。您可以对包含“ping.exe”的进程执行WMI搜索,获取PID然后关闭它,这基本上会做同样的事情。当然在您的情况下“ping.exe”可能与我的可执行文件不同。如果exe偶尔会改变,那么你可以从你的进程中获取命令行,找到包含r15_A.bat文件的文件路径的参数,然后使用filesystemobject打开这个bat文件,查找它调用的任何可执行文件可能仍然在运行,然后杀死那些......但实际上,这可能对你想要完成的事情有点过分。