'*******************************************************************
' Имя: RunDOSCom.vbs
' Язык: VBScript
' Описание: Выполнение внутренних команд DOS
'*******************************************************************
Option Explicit
Dim WshShell, Code ' Объявляем переменные
' Создаем объект WshShell
Set WshShell = WScript.CreateObject("WScript.Shell")
' Запускаем внутреннюю команду COPY
WshShell.Run "%COMSPEC% /k copy /?",1
' Запускаем внутреннюю команду DIR
WshShell.Run "%COMSPEC% /c dir %WINDIR% > windir.txt",1
'************* Конец *********************************************/
Запуск дочерних консольных приложений и команд DOS, использование их входных и выходных потоков
Консольное приложение или команду DOS можно запустить из сценария как дочернюю задачу, т.е. с теми же переменными среды, что у процесса-родителя. При этом информация, выводимая дочерним процессом, на экран дублироваться не будет, однако из родительского сценария можно считывать информацию из выходного потока и посылать данные во входной поток дочерней задачи (это напоминает конвейеризацию команд DOS, при которой данные выходного потока одной команды поступают во входной поток другой команды, например DIR | MORE
В качестве примера рассмотрим сценарий ExecConApp.js (листинг 2.36), который выводит на экран общее количество файлов в текущем каталоге и их имена (рис. 2.13).
Рис. 2.13.
Результат выполнения сценария ExecConApp.jsКак нетрудно заметить, имена файлов выводятся на экран в том же виде, что и при использовании команды DIR /B
Таким образом, для получения нужной информации необходимо запустить в качестве дочернего процесса команду DIR
/B:ObjExec=WshShell.Exec("%COMSPEC% /с dir /b");
и полностью считать данные, появляющиеся в выходном потоке этого процесса. Для этого в цикле вызывается метод ReadAll, считывающий всю информацию, имеющуюся к тому времени в потоке StdOut объекта ObjExec в переменную s:
IsBreak=false;
for (;;) { //Бесконечный цикл
//Проверяем, достигнут ли конец выходного потока команды DIR
if (!ObjExec.StdOut.AtEndOfStream)
//Считываем полностью выходной поток команды DIR
s+=ObjExec.StdOut.ReadAll();
if (IsBreak) break; //Выходим из цикла
if (ObjExec.Status==1) //Проверяем, не завершилось ли выполнение DIR
IsBreak=true;
else WScript.Sleep(100); //Приостанавливаем сценарий на 0,1 сек
}
Рис. 2.14.
Результат выполнения командыDIR /BРодительский и дочерний процессы работают асинхронно, поэтому пока команда DIR
Status объекта ObjExec не станет равным 1, выполнение сценария с помощью метода WScript.Sleep периодически приостанавливается на 0,1 секунды.После того как считаны все данные из выходного потока команды DIR
ObjExec.StdOut.AtEndOfStream равно true), происходит выход из цикла и формирование из переменной s массива выведенных строк:ArrS=s.split("\n");
После этого только остается подсчитать количество файлов в каталоге, которое на единицу меньше количества строк в массиве ArrS
ColFiles=ArrS.length-1;
и вывести нужные строки на экран:
WScript.StdOut.WriteLine("Всего файлов в текущем каталоге: "+ColFiles);
for (i=0;i<=ColFiles-1; i++ )
WScript.StdOut.WriteLine(ArrS[i]); //Выводим строки на экран