Процесс завершения VBScript, запущенный файлом .bat - PullRequest
0 голосов
/ 24 марта 2009

У меня есть сценарий настройки, в котором мне нужно проверить, не дали ли результаты выполнения файла .bat результаты. Файл .bat вызывает другой файл .exe, а файл .bat имеет окно CMD DOS, которое выводит информацию о критических ошибках в этот ящик DOS из .exe. Если .exe не запускается правильно, я могу проверить результаты в нашей базе данных SQL. Мне нужно закрыть текущий файл .bat и перезапустить его. Это кажется довольно простым, я могу получить ProcessID с помощью вызова WMI. Я могу завершить процесс с помощью команды Terminate (). Это работает для любого .exe, который я использую для тестирования: блокнот, calc, iexplorer и т. Д. Когда я запускаю VBScript для уничтожения файла .bat, он говорит, что завершает PID (что он делает, так как я больше не вижу PID) Однако окно DOS все еще открыто, и файл .exe, вызываемый из файла .bat, все еще работает. Если я нажимаю «X» в окне DOS или щелкаю правой кнопкой мыши на строке заголовка и выбираю «Закрыть», окно 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 , если это так, то остальные скрипты выполняются)

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 Ответ

0 голосов
/ 25 марта 2009

Проблема в том, что исполняемый файл, вызываемый из вашего пакетного файла, все еще работает. Я попытался воссоздать вашу настройку с битой, которую только что сделал ping -t %computername%, и, конечно, vbscript убил cmd.exe, но не пинг (Обратите внимание, что PID PID был explorer.exe, поэтому вы, вероятно, не хотите попытка убить это). Теперь я мог легко убить ping.exe из диспетчера задач, который затем закрыл окно ... но я только знал, что делать, потому что я знал, что летучая мышь делала и что оставалось открытым. Вы можете выполнить WMI-поиск для процесса, который содержит «ping.exe», получить PID, а затем закрыть его, и это в основном будет делать то же самое. Конечно, в вашей ситуации «ping.exe», вероятно, не тот же исполняемый файл, что и мой. Если exe время от времени меняется, то вы можете получить командную строку из вашего процесса, найти параметр, который содержит путь к файлу в файле r15_A.bat, а затем с помощью объекта файловой системы открыть этот файл bat, найти любые исполняемые файлы, которые он вызывает возможно, все еще работает и затем убивает тех ... но на самом деле это может быть излишним для того, что вы пытаетесь достичь.

...