Всем привет, с вами автор блога scriptcoding.ru. В этой статье мы продолжим изучать объектную модель Windows Script Host, мы изучим метод Exec класса Wscript_Shell, который отвечает за запуск приложения или скрипта.
Как я уже сказал, метод Exec WScript.Shell объекта, позволяет запускать программным путем другие приложения или сценарии, причем, они будут работать как дочерний процесс, то есть, им будут присущие те же переменные среды Windows, что и у процесса родителя. Вообще, использование метода Exec класса WScript Shell больше подходит для консольных приложений, которые выполняются в консольном окне. Мы уже рассматривали метод Run, который тоже управляет запуском приложения из сценария, но, они не будут дочерними, и поэтому, контролировать их нельзя.
Сам метод Exec содержит в себе объект, с помощью которого и можно обрабатывать запущенный процесс. Нам на данный момент интересны два его свойства – Status и ProcessID и метод Terminate()
ProcessID – Данное свойство хранит в себе идентификатор процесса, который был запущен с помощью метода Exec. Свойство полезно использовать вместе с функцией AppActivate, которая позволяет активировать приложение по имени или идентификатору.
Status – Содержит информацию о ходе выполнения запущенной задачи. Если задача еще выполняется – свойство вернет 0, если задача прекратила свою работу – свойство вернет значение 1.
Terminate() – Данный метод позволяет завершить дочерний процесс, созданный с помощью функции Exec. Фактически, процессу будет послана команда WM_CLOSE, если это не сработает, то процесс будет завершен принудительно.
Хорошо, что бы вам все это стало немного понятней, приступим к практической стороне вопроса, а именно, к программированию.
Для начала напишем такой программный код на языке vbscript:
'*********************************************************************************** ' wscript shell exec ' Запуск приложения ' сценарий выполнять в консольном окне через cscript.exe!!! ' script_exec.vbs '*********************************************************************************** Option Explicit dim WshShell, WshExec_1, WshExec_2, WshExec_3, WshExec_4 dim i, j, my_status my_status = true i=0 j=0 ' Создаем ссылку на объект WScript_Shell set WshShell = WScript.CreateObject("WScript.Shell") '----------------------------------------------------------------------- ' запускаем на выполнение две функции cmd '----------------------------------------------------------------------- set WshExec_1 = WshShell.Exec("xcopy /?") set WshExec_2 = WshShell.Exec("ipconfig /?") ' Проверяем статут выполнения Do With WScript if WshExec_1.Status = 0 then if i <>1 then .Echo "Выполняется_утилита_xcopy...." i=1 end if elseif WshExec_2.Status = 0 then if j <>1 then .Echo "Выполняется_утилита_ipconfig...." j=1 end if else .Echo "Выполнение_команд_завершено" & vbCrLf & "Идентификатор первой_команды: " & WshExec_1.ProcessID & vbCrLf & "Идентификатор второй_команды: " & WshExec_2.ProcessID exit do end if End With Loop While (my_status = true) '----------------------------------------------------------------------- ' выполнение запуска приложения калькулятор '----------------------------------------------------------------------- set WshExec_3 = WshShell.Exec("calc") i=0 j=0 ' следим за статусом Do With WScript if WshExec_3.Status = 0 then if i <>1 then .Echo "Работает программа калькулятор...." i=1 end if else .Echo "Программа калькулятор завершила работу" & vbCrLf & "Идентификатор процесса: " & WshExec_3.ProcessID exit do end if End With Loop While (my_status = true) '----------------------------------------------------------------------- ' запуск приложения блокнот '----------------------------------------------------------------------- set WshExec_4 = WshShell.Exec("notepad") WScript.Echo "Завершаем работу программы блокнот....." WScript.Sleep 5000 WshExec_4.Terminate() |
Возможно, сценарий вам покажется запутанным, но не волнуйтесь, сейчас я все поясняю. Условно, он разбит на три части:
Часть 1 – С помощью метода Exec объекта WScript Shell мы запускаем на выполнение «xcopy /?«, тем самым мы неявным образом получаем доступ к классу, ссылка на который хранится в переменной WshExec_1, о том, что это класс в языке vbscript нам говорит ключевое слово set. Аналогично, переменная WshExec_2 позволит обрабатывать и следить за «ipconfig /?«. Я говорю команда, хотя это условность, так как мы фактически делаем запуск «xcopy.exe» приложения и «ipconfig.exe«. Далее идет использование цикла do loop, он позволяет нам проследить статут выполняемых утилит с помощьюStatus и вывести их идентификаторы процессов с помощью ProcessID.
Часть 2 – тут мы запускаем приложение калькулятор, и также, следим за статусом его работы, как только мы закроем калькулятор, появится сообщение — «Программа калькулятор завершила работу» и выведется идентификатор его процесса.
Часть 3 – тут мы запускаем Блокнот приложение и далее завершаем его работу с помощью метода Terminate.
Хотя данный сценарий может работать и в оконном режиме, но лучше, выполнить его из командной строки с помощью cscript.exe, просто после cscript.exe прописываем в кавычках путь к сценарию.
Ну и напоследок, аналогичный пример использования Exec метода объекта WScript Shell, но уже на языке jscript:
//*********************************************************************************** // wscript shell exec // Запуск приложения // сценарий_выполнять в консольном окне через cscript.exe!!! // script_exec.js //*********************************************************************************** var WShell, WshExec_5, WshExec_6, WshExec_7, WshExec_8; var i=0, j=0; // Создаем ссылку на объект WScript_Shell WShell = WScript.CreateObject("WScript.Shell"); //----------------------------------------------------------------------- // запускаем на выполнение две функции cmd //----------------------------------------------------------------------- WshExec_5 = WShell.Exec("xcopy /?"); WshExec_6 = WShell.Exec("ipconfig /?"); // Проверяем статут выполнения команд for(;;){ with(WScript){ if (WshExec_5.Status == 0){ if (i!=1){ Echo ("Выполняется_функция_xcopy...."); i=1; } } if (WshExec_6.Status == 0){ if (j!=1){ Echo ("Выполняется_функция_ipconfig...."); j=1 } } if (WshExec_5.Status == 1 && WshExec_6.Status == 1){ Echo ("Выполнение_команд_завершено\nИдентификатор первой_команды: " + WshExec_5.ProcessID + "\nИдентификатор второй_команды: " + WshExec_6.ProcessID) ; break; } } } //----------------------------------------------------------------------- // выполнение запуска приложения калькулятор //----------------------------------------------------------------------- WshExec_7 = WShell.Exec("calc"); i=0; j=0; // следим за статусом for(;;){ with(WScript){ if (WshExec_7.Status == 0){ if (i!=1){ Echo ("Работает программа калькулятор...."); i=1; } }else{ Echo ("Программа калькулятор завершила работу\nИдентификатор процесса: " + WshExec_7.ProcessID); break; } } } //----------------------------------------------------------------------- // запуск приложения блокнот //----------------------------------------------------------------------- WshExec_8 = WShell.Exec("notepad"); WScript.Echo ("Завершаем работу программы блокнот....."); WScript.Sleep (5000); WshExec_8.Terminate(); |
В данном программном коде общая логика работы скрипта не изменилась, я только изменил имена переменных и все, также обратите внимание, что в обоих примерах я использовал оператор with, который позволяет сократить программный код, чтобы не писать лишний раз имя класса.