Windows Script Host для Windows 2000/XP

Андрей Владимирович Попов

Глава 2.. Примеры использования  стандартных объектов WSH (JScript и VBScript)

В этой главе мы на примерах подробно рассмотрим, как с помощью стандартных объектов WSH 5.6, описание которых приведено в главе 1, можно решать некоторые практические задачи, связанные, в частности, с выводом и вводом текстовой информации, запуском других приложений (как на локальной, так и на удаленной машине), созданием ярлыков в различных папках, работой с системным реестром и локальной сетью. Практически все сценарии приведены как на языке JScript, так и на VBScript, и снабжены подробными комментариями.

Вывод на экран текстовых строк

Сформированные в сценарии строки текста можно выводить в стандартный выходной поток (в консольном режиме) или в графическое диалоговое окно несколькими способами:

• с помощью метода Echo объекта WScript;

• с помощью методов Write и WriteLine объекта WScript.StdOut;

• с помощью функции MsgBox языка VBScript;

• с помощью метода Popup объекта WshShell.

Метод Echo объекта WScript

Примеры использования метода WScript.Echo в сценариях, написанных на языках JScript и VBScript, представлены соответственно в листингах 2.1 и 2.2.

!

Для корректного отображения с помощью метода Echo символов кириллицы, эти символы должны быть представлены в Windows-кодировке (CP 1251).

Листинг 2.1. Вывод строк в Win-кодировке с помощью метода WScript.Echo (JScript)
Листинг 2.2. Вывод строк в Win-кодировке с помощью метода WScript.Echo (VBScript)

Если сценарий Echo1.js (Echo1.vbs) был запущен с помощью cscript.exe, то строки выводятся в командное окно (рис. 2.1).

Если же этот сценарий выполнялся с помощью wscript.exe, то строки по очереди выводятся в диалоговые окна с единственной кнопкой OK (рис. 2.2).

Часто бывает необходимо выводить в диалоговое окно не по одной строке текста, а сразу несколько таких строк (рис. 2.3). Для этого нужно формировать строки, содержащие символы перевода строки: escape-последовательность "\n" для JScript и предопределенная именованная константа vbCrLf для VBScript (соответствующие примеры сценариев приведены в листингах 2.3 и 2.4).  

Рис. 2.1. Результат выполнения Echo1.js с помощью cscript.exe


Рис. 2.2. Результат выполнения Echo1.js с помощью wscript.exe


Рис. 2.3. Диалоговое окно с несколькими строками текста


Листинг 2.3. Вывод в диалоговое окно нескольких строк (JScript)
Листинг 2.4. Вывод в диалоговое окно нескольких строк (VBScript)

Методы Write и WriteLine объекта WScript.StdOut

Для вывода строк в сценариях, выполняющихся в консольном режиме, можно использовать стандартный выходной поток WScript.StdOut (листинги 2.5 и 2.6). Напомним, что запускать сценарий, обращающийся к потоку StdOut, можно только в консольном режиме с помощью cscript.exe. Если же попробовать выполнить, например, сценарий StdOut1.js с помощью wscript.exe, то произойдет ошибка (рис. 2.4).

Рис. 2.4. Ошибка, возникающая при обращении к StdOut в графическом режиме


Листинг 2.5. Вывод строк в стандартный выходной поток (JScript)
Листинг 2.6. Вывод строк в стандартный выходной поток (VBScript)
!

В Windows ХР символы кириллицы, посылаемые из сценария в стандартный выходной поток, должны быть представлены в Windows-кодировке (CP 1251). В предыдущих версиях Windows для корректного отображения на экране символы кириллицы при использовании потока WScript.StdOut должны быть в DOS-кодировке (OEM 866).

Как и при использовании метода WScript.Echo, в качестве параметра метода WriteLine можно указывать строки, содержащие символы перевода строки (листинги 2.7 и 2.8).

Листинг 2.7. Вывод в StdOut сразу нескольких строк (JScript)
Листинг 2.8. Вывод в StdOut сразу нескольких строк (VBScript)

Для создания более компактного текста сценария можно сразу сохранить ссылку на стандартный выходной поток WScript.StdOut в отдельную переменную и затем при вызове методов Write и WriteLine использовать эту переменную (листинги 2.9 и 2.10).

Листинr 2.9. Сохранение ссылки на поток StdOut в переменной (JScript)
Листинr 2.10. Сохранение ссылки на поток StdOut в переменной (VBScript)

Функция MsgBox языка VBScript

В языке VBScript существует специальная функция MsgBox, с помощью которой можно выводить информацию в диалоговое окно с несколькими кнопками; также в этом окне можно задавать заголовок и значок (рис. 2.5).

Рис. 2.5. Диалоговое окно, созданное с помощью функции MsgBox


Пример сценария, создающего такое диалоговое окно, приведен в листинге 2.11.

!

В языке JScript аналога функции MsgBox нет.

Листинг 2.11. Создание диалогового окна с помощью функции MsgBox (VBScript)

Подробное описание функции MsgBox приведено в приложении 1. Здесь же мы отметим только то, что значением функции MsgBox является константа, соответствующая нажатой в диалоговом окне кнопки (в нашем примере такими константами являются vbOk и vbCancel). Таким образом, MsgBox может использоваться в сценариях для организации выбора пользователем одного из возможных вариантов, однако это не совсем удобно, т.к. надписи на кнопках нельзя задавать произвольным образом (можно указать только OK, Отмена, Стоп, Повтор, Пропустить, Да и Нет).

Метод Popup объекта WshShell

С помощью метода Popup (подробное описание метода приведено в главе 1) можно создавать такие же диалоговые окна, как и при помощи функции MsgBox, причем этот метод можно использовать как в VBScript-, так и в JScript-сценариях (листинги 2.12 и 2.13).

Листинг 2.12. Создание диалогового окна с помощью метода Popup (JScript)
Листинг 2.13. Создание диалогового окна с помощью метода Popup (VBScript)

Главным отличием метода Popup от функции MsgBox является наличие параметра nSecToWait, задающего время (в секундах), по истечении которого диалоговое окно будет автоматически закрыто. Если этот параметр равен нулю, как в приведенных выше примерах, то окно будет закрыто только после нажатия какой-либо кнопки в нем.

Ввод строк текста

Для организации в сценариях диалога с пользователем необходимо уметь принимать вводимые с клавиатуры строки текста. В консольном и графическом режимах ввод информации осуществляется по-разному: при запуске сценария с помощью cscript.exe мы имеем доступ к стандартному входному потоку StdOut, при использовании wscript.exe можно применять функцию InputBox языка VBScript.

Ввод строк в консольном режиме

Самый простой способ ввести строку в консольном режиме предоставляет метод WScript.StdIn.ReadLine, при использовании этого метода ввод завершается нажатием клавиши <Enter>.

Отметим, что при использовании стандартного входного потока WScript.StdIn в Windows ХР (по крайней мере в той версии, которой пользовался автор) возникает проблема, связанная с кодировкой символов кириллицы. Дело в том, что метод WScript.StdIn.ReadLine возвращает строку в DOS-кодировке, а для вывода на экран с помощью методов WScript.StdOut.WriteLine или WScript.Echo строка должна быть в Windows-кодировке (в предыдущих версиях Windows метод WScript.StdOut.WriteLine требовал строку в DOS-кодировке). Поэтому для корректного отображения символов кириллицы на экране приходится применять дополнительные функции конвертации из DOS- в Windows-кодировку. Стандартных методов или функций, предназначенных для этой цели, в языках JScript и VBScript нет, поэтому такие функции следует написать самостоятельно.

Рассмотрим сначала написанную на JScript функцию конвертации DosToWin из листинга 2.14:

function DosToWin(s) {
 var i,ss;  //Объявляем переменные
 //Проверяем, создан ли объект RusDict
 if (typeof(RusDict)=="undefined")
  //Если объект RusDict не создан, создаем его
  MakeRusDict();
 ss="";
 for (i=0;i<s.length;i++) {  //Цикл по всем символам в строке
  if (RusDict.Exists(s.charAt(i)))  //Проверяем наличие символа в словаре
   //Преобразуем i-й символ в Windows-кодировку
   ss+=RusDict.Item(s.charAt(i));
  else ss+=s.charAt(i);
 }
 return ss;
}

Как мы видим, эта функция преобразует переданную в качестве параметра строку следующим образом: все символы кириллицы в этой строке переводятся в Windows-кодировку, остальные символы остаются без изменений. Основным в функций DosToWin является использование объекта Dictionary (аналог ассоциативного массива) с именем RusDict. Этот объект формируется в функции MakeRusDict и содержит пары "ключ"–"значение" для всех букв русского алфавита, причем в качестве ключа указывается буква в DOS-кодировке, а в качестве значения — символ с кодом, который соответствует этой букве в Windows-кодировке:

function MakeRusDict() {
 //Создаем объект Dictionary
 RusDict = WScript.CreateObject("Scripting.Dictionary");
 //Заполняем пары "ключ" (символ в DOS-кодировке)-"значение" (символ в
 //Window-кодировке) для всех букв русского алфавита
 RusDict.add("Ђ", "А"); RusDict.add("Ѓ", "Б"); RusDict.add("‚", "В");
 RusDict.add("ѓ", "Г"); RusDict.add("„", "Д"); RusDict.add("…", "Е");
 RusDict.add("р", "Ё"); RusDict.add("†", "Ж"); RusDict.add("‡", "З");
 RusDict.add("€", "И"); RusDict.add("‰", "Й"); RusDict.add("Љ", "К");
 RusDict.add("‹", "Л"); RusDict.add("Њ", "М"); RusDict.add("Ќ", "Н");
 RusDict.add("Ћ", "О"); RusDict.add("Џ", "П"); RusDict.add("ђ", "Р");
 RusDict.add("‘", "С"); RusDict.add("’", "Т"); RusDict.add("“", "У");
 RusDict.add("”", "Ф"); RusDict.add("•", "Х"); RusDict.add("–", "Ц");
 RusDict.add("—", "Ч"); RusDict.add("˜", "Ш"); RusDict.add("™", "Щ");
 RusDict.add("љ", "Ъ"); RusDict.add("›", "Ы"); RusDict.add("њ", "Ь");
 RusDict.add("ќ", "Э"); RusDict.add("ћ", "Ю"); RusDict.add("џ", "Я");
 RusDict.add(" ", "а"); RusDict.add("Ў", "б"); RusDict.add("ў", "в");
 RusDict.add("Ј", "г"); RusDict.add("¤", "д"); RusDict.add("Ґ", "е");
 RusDict.add("с", "ё"); RusDict.add("¦", "ж"); RusDict.add("§", "з");
 RusDict.add("Ё", "и"); RusDict.add("©", "й"); RusDict.add("Є", "к");
 RusDict.add("«", "л"); RusDict.add("¬", "м"); RusDict.add("­", "н");
 RusDict.add("®", "о"); RusDict.add("Ї", "п"); RusDict.add("а", "р");
 RusDict.add("б", "с"); RusDict.add("в", "т"); RusDict.add("г", "у");
 RusDict.add("д", "ф"); RusDict.add("е", "х"); RusDict.add("ж", "ц");
 RusDict.add("з", "ч"); RusDict.add("и", "ш"); RusDict.add("й", "щ");
 RusDict.add("к", "ъ"); RusDict.add("л", "ы"); RusDict.add("м", "ь");
 RusDict.add("н", "э"); RusDict.add("о", "ю"); RusDict.add("п", "я");
}

В функции DosToWin из VBScript-сценария StdIn1.vbs (листинг 2.15) реализован другой подход к переводу строки в Windows-кодировку, связанный с преобразованием ANSI-кодов символов:

Function DosToWin(s)
Dim i,k,ss
 ss=""
 For i=1 To Len(s)  ' Цикл по всем символам в строке
  k = Asc(Mid(s,i,1))  ' Определяем ANSI-код i-го символа
  ' Изменяем код k на код соответствующего символа в
  ' Windows-кодировке
  If (128 <= k) And (k <= 175) Then
   k=k+64
  ElseIf (224 <= k) And (k <= 239) Then
   k=k+16
  ElseIf k = 240 Then
   k=168
  ElseIf k = 241 Then
   k=184
  End If
  ss=ss+Chr(k)  ' Возвращаем преобразованную строку
 Next
 DosToWin=ss
End Function

Весь алгоритм этой функции состоит в вычислении по ANSI-коду буквы русского алфавита в DOS-кодировке кода символа в Windows-кодировке, соответствующего этой букве.

Листинг 2.14. Ввод одной строки с помощью метода StdIn.ReadLine (JScript)
Листинг 2.15. Ввод одной строки с помощью метода StdIn ReadLine (VBScript)

Используя метод WScript.StdIn.ReadAll, можно ввести сразу несколько строк подряд, ввод при этом прекращается после нажатия клавиш <Ctrl>+<Z>. Из введенной таким образом переменной можно затем сформировать массив, содержащий все строки. Для этого в JScript применяется метод split объекта string, а в VBScript — одноименная внутренняя функция Split (листинги 2.16 и 2.17). 

Листинг 2.16. Ввод нескольких строк с помощью метода StdIn.ReadAll (JScript)
Листинг 2.17. Ввод нескольких строк с помощью метода StdIn.ReadAll (VBScript)

Ввод строк в графическом режиме 

В сценариях VBScript в графическом режиме информацию можно вводить с помощью диалогового окна, создаваемого внутренней функцией InputBox(рис. 2.6).

Рис. 2.6. Диалоговое окно со строкой ввода


 Пример сценария, использующего функцию InputBox, представлен в листинге 2.18 (подробное описание параметров функции InputBox см. в приложении 1).

Листинг 2.18. Ввод одной строки с помощью функции InputBox (VBScript)

К сожалению, ни в языке JScript, ни в объектной модели WSH нет функции или метода, позволяющих напрямую создавать диалоговые окна со строкой ввода. Однако при помощи файлов сценариев с XML-разметкой, описанных в главе 3, функции языка VBScript (InputBox в частности) можно использовать внутри JScript-сценария (соответствующий пример приведен в листинге 3.11).

Получение свойств WSH и запущенного сценария

На практике часто бывает необходимо знать определенные атрибуты WSH (например, с помощью какого приложения-сервера был запущен сценарий) и сценария, работающего в данный момент (например, имя этого сценария или путь к каталогу, в котором он находится). Некоторые параметры WSH и исполняемого сценария можно определить непосредственно с помощью соответствующих методов объекта WScript:

• полный путь к приложению-серверу (cscript.exe или wscript.exe);

• имя каталога, в котором находится приложение-сервер;

• номер используемой версии WSH;

• полный путь к исполняемому сценарию;

• имя исполняемого сценария.

Для проверки режима, в котором был запущен сценарий, можно предложить функцию IsCScript (ниже приведена реализация этой функции на языке JScript), которая будет возвращать true, если использовался хост cscript.exe (консольный режим), и false, если использовался wscript.exe (графический режим):

function IsCScript() {
 //Проверка режима, в котором запущен сценарий
 return ("с"== WScript.FullName.toLowerCase().charAt(WScript.FullName.length - 11));
}

Как мы видим, вся работа функции IsCScript состоит в определении того, с какой буквы начинается имя приложения-сервера ("с" для cscript.exe или "w" для wscript.exe).

Полный путь к текущему каталогу, т.е. к каталогу, из которого был запущен сценарий, хранится в свойстве CurrentDirectory объекта WshShell.

Если сценарий был запущен не из того каталога, в котором находится сам файл со сценарием, то текущий каталог не будет совпадать с каталогом сценария. Для того чтобы получить путь к каталогу сценария, нужно выделить этот путь из свойства WScript.ScriptFullName, содержащему полный путь к выполняемому сценарию (включая имя файла). На языке JScript это можно реализовать с помощью функции GetScriptDir следующего содержания:

function GetScriptDir() {
 var ScriptDir;
 ScriptDir = WScript.ScriptFullName;
 ScriptDir = ScriptDir.substring(0, ScriptDir.lastIndexOf("\\"));
 return ScriptDir;
}

Полные тексты сценариев на языках JScript (PropScript.js) и VBScript (PropScript.vbs), выводящих на экран сведения о свойства WSH и запущенного сценария, приведены в листингах 2.19 и 2.20 соответственно; результат работы сценария PropScript.js представлен на рис. 2.7.

Рис. 2.7. Результаты выполнения сценария PropScript.js в графическом режиме


Листинг 2.19. Вывод свойств WSH и запущенного сценария (JScript)
Листинг 2.20. Вывод свойств WSH и запущенного сценария (VBScript)

Работа с параметрами командной строки сценария

Используя аргументы командной строки, в сценарии можно передавать различную информацию, скажем, те или иные переключатели или имена пользователей и рабочих станций. При задании аргумента можно указать либо только его значение, либо имя вместе со значением в следующем формате: "Имя_аргумента:Значение".

!

Как в имени аргумента, так и в его значении могут использоваться символы кириллицы.

Например, выполнив в командном окне строку

cscript Example.js /Имя:"Андрей Попов" /Возраст:30

или

cscript Example.js /Возраст:30 /Имя:"Андрей Попов"

мы передадим в сценарий Example.js два параметра: "Имя" со значением "Андрей Попов" и "Возраст" со значением "30". Значения этих параметров можно было передать и как безымянные параметры:

cscript Example.js "Андрей Попов" 30

Однако в последнем случае при задании безымянных аргументов будет важен порядок их указания в командной строке.

В WSH для обработки параметров командной строки служат следующие объекты-коллекции:

WshArguments (содержит все параметры, как именные, так и безымянные);

WshNamed (содержит только именные параметры);

WshUnnamed (содержит только безымянные параметры).

!

Описание аргументов командной строки в сценариях можно задавать с помощью XML-элементов <runtime>, <named> и <unnamed> (см. главу 3).

Для доступа к коллекциям, содержащим аргументы командной строки, в сценарии сначала нужно создать переменную-экземпляр объекта WshArguments; для этого используется свойство Arguments объекта WScript. Пример на языке JScript:

var objArgs=WScript.Arguments;

Для создания экземпляров коллекций WshNamed и WshUnnamed используются соответственно методы Named и Unnamed объекта WshArguments. Например:

var objNamedArgs=objArgs.Named;
var objUnnamedArgs=objArgs.Unnamed;

Методы и свойства коллекций WshArguments, WshNamed и WshUnnamed подробно описаны в главе 1. Отметим здесь только, что для корректной работы с параметрами командной строки, имена которых содержат символы кириллицы, эти имена в сценарии должны быть написаны в кодировке Windows.

В листингах 2.21 и 2.22 приведены примеры сценариев на языках JScript и VBScript, которые выводят на экран общее количество параметров командной строки, количество именных и безымянных аргументов, а также значения каждой из этих групп параметров. Результат работы этих сценариев, запущенных в консольном режиме, представлен на рис. 2.8.

Рис. 2.8. Результат работы сценария Args.js


Листинг 2.21. Доступ к параметрам командной строки запущенного сценария (JScript)
Листинг 2.22. Доступ к параметрам командной строки запущенного сценария (VBScript)

Выход из сценария с определенным кодом завершения

Любое приложение при завершении своей работы может возвращать операционной системе целое число — код выхода (обычно ненулевое значение этого кода указывает на то, что выполнение программы прервалось в силу той или иной ошибки).

!

Сама операционная система Windows не проверяет код завершения приложений.

В WSH код выхода из сценария задается с помощью параметра метода Quit объекта WScript. В листингах 2.23 и 2.24 приведены сценарии, в которых код завершения выбирается в зависимости от того, какая кнопка нажата в диалоговом окне (рис. 2.9): кнопке OK соответствует код 1, кнопке Отмена — код 0.

Рис. 2.9. Диалоговое окно, создаваемое в сценарии Quit.js


Листинг 2.23. Выход из сценария с заданным кодом завершения (JScript)
Листинr 2.24. Выход из сценария с заданным кодом завершения (VBScript)

Если сценарий запускался с помощью командного файла, то код выхода можно проанализировать с помощью оператора IF ERRORLEVEL.

Пример подобного ВАТ-файла приведен в листинге 2.25. Здесь сценарий Quit.js запускается с помощью команды START с ключом /WAIT, указывающим на то, что выполнение ВАТ-файла должно быть приостановлено до окончания работы Quit.js. После этого, если код завершения pавен 1 (в диалоговом окне сценария была нажата кнопка OK), происходит переход к метке :Ok и выдача с помощью команды ECHO соответствующего сообщения на экран.

!

Для корректного отображения на экране символов кириллицы в BAT-файлах должна использоваться DOS-кодировка.

Если же код завершения сценария Quit.js был равен 0 (в диалоговом окне была нажата кнопка Отмена), то управление перейдет к строке

ECHO Для выхода из Quit.js была нажата кнопка Отмена
Листинг 2.25. Анализ кода выхода сценария Quit.js (Check.bat)

Использование внешних объектов автоматизации (на Microsoft Word)

Для того чтобы из сценария получить доступ к свойствам или методам внешнего сервера автоматизации, вначале надо "создать" соответствующий объект, т.е. загрузить в память экземпляр нужного СОМ-объекта и сохранить в переменной ссылку на этот объект. Напомним, что объект в сценарии может создаваться несколькими способами:

• с помощью метода CreateObject объекта WScript (объектная модель WSH);

с помощью конструкции new ActiveXObject (язык JScript);

• с помощью функции CreateObject (язык VBScript).

В любом случае в используемый метод или функцию в качестве параметра передается программный идентификатор объекта (ProgID), заключенный в скобки. Пример на языке JScript:

var WA=WScript.CreateObject("Word.Application");

То же самое на VBScript:

Set WA=WScript.CreateObject("Word.Application")

Перед точкой в ProgID стоит имя библиотеки типов (type library) для объекта, которая может существовать как в виде отдельного файла с расширением tlb, так и в виде части файла с исполняемым кодом объекта (библиотека типов, содержащая сведения о СОМ-объекте, регистрируется в системном реестре при установке приложения, использующего этот объект). После точки в ProgID указывается имя класса, содержащего свойства и методы, доступные для использования другими приложениями.

Выполняя метод CreateObject, интерпретатор сценария через ProgID получает из системного реестра путь к файлам нужной библиотеки типов. Затем с помощью этой библиотеки в память загружается экземпляр запрашиваемого объекта, и его интерфейсы становятся доступными для использования в сценарии. Ссылка на созданный объект сохраняется в переменной; в дальнейшем, используя эту переменную, мы получаем доступ к свойствам и методам объекта, а также к его вложенным объектам (если они имеются).

Для примера рассмотрим, каким образом из сценария можно управлять работой Microsoft Word, который является сервером автоматизации (листинги 2.26 и 2.27).

!

Более подробно объектная схема Microsoft Word описывается в главе 9.

Сначала создается главный объект Word.Application, который запускает приложение Microsoft Word:

WA=WScript.CreateObject("Word.Application");

Затем создается новый пустой документ, в результате в переменную WD заносится ссылка на объект Document:

WD=WA.Documents.Add();

Наконец, в переменную Sel заносится ссылка на объект Selection, с помощью которого можно задать тип и размер шрифта, тип выравнивания абзацев и напечатать в документе строки текста:

Sel=WA.Selection;

В результате выполнения сценариев PrintInWord.js или PrintInWord.vbs в новом документе Word печатаются две строки текста (рис. 2.10), после чего с помощью метода PrintOut объекта Document содержимое документа выводится на принтер:

WD.PrintOut();

Рис. 2.10. Результат выполнения сценариев PrintInWord.js


Листинг 2.26. Использование сервера автоматизации Microsoft Word (JScript)
Листинr 2.27. Использование сервера автоматизации Мiсrоsоft Word (VBScript)

Запуск из сценариев внешних программ 

Внешние программы и команды можно запускать из сценариев различными способами.

Запуск приложений Windows

Запустить из сценария WSH другое приложение можно с помощью методов Run или Exec объекта WshShell.

При использовании метода Run для запускаемого приложения можно задать тип окна (при условии, что приложение поддерживает этот тип). Например, в результате выполнения следующих двух строк JScript-кода:

var WshShell = WScript.CreateObject("WScript.Shell");
WshShell.Run("notepad", 3);

программа Блокнот (notepad.exe) будет запущена в максимизированном (распахнутом на весь экран) окне (список всех возможных значений параметров метода Run приведен в табл. 1.13).

!

Метод Run всегда создает новый экземпляр запускаемого процесса, с его помощью нельзя ни повторно активизировать окно запущенного приложения (для этого используется метод AppActivate), ни свернуть или развернуть его.

Другим вариантом запуска из сценария приложения Windows является применение метода Exec. Этот метод запускает приложение, путь к которому указан как параметр метода, и возвращает объект WshScriptExec.

Например:

var WshShell = WScript.CreateObject("WScript.Shell");
var theNotepad = WshShell.Exec("calc");
!

При подобном запуске приложения, в отличие от метода Run, нельзя задать тип окна.

Объект WshScriptExec позволяет контролировать ход выполнения запущенного приложения с помощью свойства Status — если Status равен 0, то приложение выполняется, если Status равен 1, то приложение завершено. Кроме этого, используя метод Terminate, можно принудительно завершить работу того приложения, которому соответствует объект WshScriptExec.

В листинге 2.28 приведен сценарий на языке JScript, в котором с помощью метода Exec запускается Блокнот (notepad.exe); ссылка на соответствующий объект WshScriptExec сохраняется в переменной theNotepad:

theNotepad = WshShell.Exec("notepad");

После этого выполнение сценария приостанавливается на 1 секунду (пауза необходима для того, чтобы окно Блокнота успело появиться на экране), после чего выводится диалоговое окно с информацией о статусе запущенного приложения и вопросом о необходимости закрытия Блокнота (рис. 2.11):

WScript.Sleep(1000);
Text="Блокнот запущен(Status="+theNotepad.Status+")\nЗакрыть Блокнот?";
Title="";
Res=WshShell.Popup(Text, 0, Title, vbQuestion+vbYesNo);

Рис. 2.11. Диалоговое окно, формируемое в сценарии ExecWinApp.js


В случае утвердительного ответа происходит закрытие Блокнота с помощью метода Terminate:

if (Res==vbYes) {
 theNotepad.Terminate();
 WScript.Sleep(100);
 WScript.Echo("Блокнот закрыт (Status="+theNotepad.Status+")");
}
Листинг 2.28. Запуск и принудительное закрытие приложения (JScript)

Тот же самый пример на языке VBScript приведен в листинге 2.29.

Листинr 2.29. Запуск и принудительное закрытие приложения (VBScript)

Переключение между приложениями, имитация нажатий клавиш

Производить переключение между окнами нескольких запущенных приложений позволяет метод AppActivate объекта WshScript. В качестве аргумента этого метода нужно указывать либо заголовок активизируемого окна, либо программный идентификатор (PID) процесса, который запущен в этом окне. Предпочтительным является использование PID, который можно получить с помощью свойства ProcessID объекта WshScriptExec, соответствующего активизируемому приложению. Недостатки применения в методе AppActivate заголовка окна:

• при написании сценария необходимо знать точное название заголовка;

• само приложение может изменить текст в заголовке окна;

• в случае нескольких окон с одинаковыми заголовками AppActivate всегда будет активизировать один и тот же экземпляр, доступ к другим окнам получить не удастся.

Активизировав то или иное окно, в котором выполняется приложение Windows, можно из сценария сымитировать нажатия клавиш в этом окне. Для этого используется метод SendKeys объекта WshShell (подробное описание этого метода приведено в главе 1).

!

Для нормальной работы метода SendKeys необходимо, чтобы языком по умолчанию в операционной системе был назначен английский язык.

Рассмотрим пример сценария Run&ExecWinApp.js (листинг 2.30), в котором запускается Калькулятор (calc.exe), и в его окно с помощью SendKeys последовательно посылаются нажатия клавиш <1>, <+>, <2> и <Enter>:

theCalculator = WshShell.Exec("calc");
WScript.Sleep(1000);
WshShell.AppActivate(theCalculator.ProcessID);
WshShell.SendKeys("1{+}");
WshShell.SendKeys("2");
WshShell.SendKeys("~"); //Клавиша <Enter>

Затем выполнение сценария приостанавливается на 1 секунду, чтобы результат вычислений был виден на экране:

WScript.Sleep(1000);

после чего результат вычислений (символ "3") копируется в буфер с помощью "нажатия" клавиш <Ctrl>+<C>:

WshShell.SendKeys ("^c");

После этого на экран выводится сообщение о том, что Калькулятор будет закрыт:

WScript.Echo("Закрываем калькулятор");

в результате чего окно Калькулятора теряет фокус. Для того чтобы вновь активизировать это окно, используется метод AppActivate, параметром которого служит PID Калькулятора:

WshShell.AppActivate(theCalculator.ProcessID);

Для того чтобы закрыть окно Калькулятора, в него посылаются нажатия клавиш <Alt>+<F4>:

WshShell.SendKeys("%{F4}");

После закрытия Калькулятора запускается Блокнот (notepad.exe) и в него записываются результаты работы Калькулятора (вставка из буфера вычисленной суммы производится с помощью нажатий <Ctrl>+<V>):

WshShell.Run("notepad");
WScript.Sleep(1000);
WshShell.AppActivate("notepad");
WshShell.SendKeys("l{+}2=");
WshShell.SendKeys("^v");
WshShell.SendKeys(" {(}с{)} Calculator");

В результате в Блокноте отображается текст, показанный на рис. 2.12.

Рис. 2.12. Результат работы сценария Run&ExecWinApp.js


Листинг 2.30. Запуск двух приложений и обмен данными между ними (JScript)

Тот же пример, реализованный в виде VBScript-сценария, приведен в листинге 2.31.

Листинг 2.31. Запуск двух приложений и обмен данными между ними (VBScript)

Запуск независимых консольных приложений и команд DOS

Для запуска независимых, т.е. работающих в отдельном адресном пространстве и использующих свою копию переменных среды, консольных приложений или внешних (представленных исполняемыми файлами на жестком диске) команд DOS используется метод Run объекта WshShell. При этом выполнение сценария можно приостановить до окончания работы запущенного приложения, а затем проанализировать код выхода этого приложения (для этого третий параметр метода Run должен равняться true). Соответствующие примеры сценариев на языках JScript и VBScript приведены в листингах 2.32 и 2.33 соответственно.

Листинг 2.32. Запуск независимого консольного приложения (JScript)
Листинr 2.33. Запуск независимого консольного приложения (VBSсript)

Для выполнения внутренней команды DOS нужно запустить командный интерпретатор (в Windows NT/2000/XP это файл cmd.exe, в Windows9х — command.com) и передать ему в качестве параметра нужную команду. Для того чтобы при вызове командного интерпретатора не заботиться о полном пути к cmd.exe, нужно использовать переменную среды COMSPEC.

!

Для получения значения переменной среды ее имя нужно окружить знаками "%" (например, %COMSPEC%).

В листингах 2.34 и 2.35 приведены сценарии на языках JScript и VBScript, в которых запускаются внутренние команды COPY /? (вызов встроенной справки для сору) и DIR %WINDIR% (вывод содержимого системного каталога Windows).

При этом окно, в котором выполняется команда COPY /?, не закрывается после завершения этой команды, т.к. при запуске командного интерпретатора был указан ключ /k, а информация, выводимая командой DIR %WINDIR%, перенаправляется в файл windir.txt, после чего командное окно закрывается, т.к. для командного интерпретатора в этом случае был указан ключ .

Листинг 2.34. Доступ к параметрам командной строки запущенного сценария (JScript)
Листинг 2.35. Доступ к параметрам командной строки запущенного сценария (VBScript)

Запуск дочерних консольных приложений и команд DOS, использование их входных и выходных потоков

Консольное приложение или команду DOS можно запустить из сценария как дочернюю задачу, т.е. с теми же переменными среды, что у процесса-родителя. При этом информация, выводимая дочерним процессом, на экран дублироваться не будет, однако из родительского сценария можно считывать информацию из выходного потока и посылать данные во входной поток дочерней задачи (это напоминает конвейеризацию команд DOS, при которой данные выходного потока одной команды поступают во входной поток другой команды, например DIR | MORE). Таким образом, из сценария можно запускать ту или иную утилиту командной строки и обрабатывать выводимые ей данные; иногда таким образом получить нужную информацию бывает проще и быстрее, чем при использовании объектной модели WSH или другого сервера автоматизации.

В качестве примера рассмотрим сценарий ExecConApp.js (листинг 2.36), который выводит на экран общее количество файлов в текущем каталоге и их имена (рис. 2.13).

Рис. 2.13. Результат выполнения сценария ExecConApp.js


Как нетрудно заметить, имена файлов выводятся на экран в том же виде, что и при использовании команды DIR /B (рис. 2.14).

Таким образом, для получения нужной информации необходимо запустить в качестве дочернего процесса команду 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]); //Выводим строки на экран
!

В дочернем консольном приложении вывод строк в выходной поток происходит в DOS-кодировке, поэтому при наличии символов кириллицы эти строки нужно преобразовывать в кодировку Windows (примеры соответствующих функций конвертации на языках JScript и VBScript приведены в листингах 2.14 и 2.15).

Листинг 2.36. Запуск дочернего консольного приложения (JScript)

Аналогичный сценарий на языке VBScript приведен в листинге 2.37.

Листинг 2.37. Запуск дочернего консольного приложения (VBScript)

Доступ к специальным папкам Windows ХР

При установке Windows всегда автоматически создаются несколько специальных папок (например, папка для рабочего стола (Desktop) или папка для меню Пуск (Start)), путь к которым впоследствии может быть тем или иным способом изменен. С помощью свойства SpecialFolders объекта WshShell можно создать объект WshSpecialFolders, который является коллекцией, содержащей пути ко всем специальным папкам, имеющимся в системе (список названий этих папок приведен в главе 1 при описании объекта WshSpecialFolders).

В листингах 2.38 и 2.39 приводятся сценарии на языках JScript и VBScript соответственно, которые формируют список всех имеющихся в системе специальных папок (рис. 2.15).

Рис. 2.15. Пути для всех специальных папок в Windows ХР


Листинг 2.38. Формирование списка всех специальных папок (JScript)
Листинr 2.39. Формирование списка всех специальных папок (VBScript)

Объект WshSpecialFolders также позволяет получить путь к конкретно заданной специальной папке. Например, в сценарии SpecFold2.js (листинг 2.40) на экран выводятся пути к папкам рабочего стола (Desktop), избранных ссылок (Favorites) и раздела Программы (Programs) меню Пуск (Run) — рис. 2.16.

Рис. 2.16. Пути для некоторых специальных папок


Листинг 2.40. Доступ к определенным специальным папкам (JScript)

Реализация того же сценария на языке VBScript приведена в листинге 2.41.

Листинг 2.41. Доступ к определенным специальным папкам (VBScript)

Создание ярлыков в специальных папках

Для того чтобы из сценария создать ярлык в специальной папке (рабочий стол, меню Пуск (Start) и т.п.) или изменить свойства уже существующего ярлыка, необходимо:

1. Используя коллекцию WshSpecialFolders, узнать путь к нужной специальной папке.

2. С помощью метода CreateShortcut объекта WshShell создать объект WshShortcut (WshUrlShortcut) для связи с ярлыком в этой папке.

3. Задать или изменить свойства ярлыка с помощью соответствующих методов объекта WshShortcut (WshUrlShortcut).

4. Сохранить ярлык с помощью метода Save объекта WshShortcut (WshUrlShortcut).

Объект WshShortcut предоставляет доступ к следующим свойствам ярлыков (рис. 2.17):

Объект (Target);

Рабочая папка (Start in);

Быстрый вызов (Shortcut key);

Окно (Run);

Комментарий (Comment).

Кроме этого, с помощью объекта WshShortcut можно сменить значок, который соответствует ярлыку.

Рис. 2.17. Свойства ярлыка в Windows ХР


Остальных свойств, имеющихся у ярлыков в Windows ХР, объект WshShortcut не поддерживает (например, нельзя установить или сбросить флажок, позволяющий запускать процесс в отдельном адресном пространстве или под другой учетной записью пользователя).

В качестве примера ниже приведен сценарий Shortcut.js (листинг 2.42), в котором создается ярлык "Мой ярлык.lnk" на Блокнот (notepad.exe), причем этот ярлык может быть сохранен либо в меню Программы (Programs) работающего пользователя, либо на его рабочем столе. Выбор специальной папки в сценарии производится с помощью диалогового окна, которое создается методом Popup объекта WshShell (рис. 2.18).

Рис. 2.18. Диалоговое окно для выбора специальной папки


Рис. 2.10. Свойства ярлыка "Мой ярлык.lnk"


Для создаваемого ярлыка выбирается значок из файла Shell32.dll, находящегося в подкаталоге System каталога Windows (в Windows 95/98 этот файл находится в подкаталоге System), назначается комбинация горячих клавиш <Ctrl>+<Alt>+<N> и устанавливается максимизированный тип окна (рис. 2.19).

Листинг 2.42. Доступ к определенным специальным папкам (JScript)

Реализация того же сценария на языке VBScript приведена в листинге 2.43.

Листинг 2.43. Доступ к определенным специальным папкам (VBScript)

Работа с системным реестром Windows

Во всех версиях Windows системный реестр — это база данных, в которой хранится информация о конфигурации компьютера и операционной системы. С точки зрения пользователя, реестр является иерархическим деревом разделов, подразделов и параметров. Работать с этим деревом можно с помощью стандартного редактора реестра regedit.exe (рис. 2.20).

Рис. 2.20. Редактор реестра regedit.exe


С помощью методов объекта WshShell из сценариев WSH можно:

• создавать новые разделы и параметры (метод RegWrite);

• изменять значения параметров и разделов (метод RegWrite);

• считывать значения параметров и разделов (метод RegRead);

• удалять параметры и разделы (метод RegDelete).

!

В Windows ХР для работы с системным реестром сценарий должен иметь разрешение на доступ к разделам реестра, которым обладает администратор.

В листинге 2.44 представлен сценарий Registry.js, который производит манипуляции внутри корневого раздела HKEY_CURRENT_USER, причем каждая операция выполняется только после утвердительного ответа на соответствующий запрос, формируемый в диалоговом окне.

Сначала в разделе HKEY_CURRENT_USER создается подраздел ExampleKey, в который затем записывается строковый параметр ExampleValue со значением "Value from WSH" (рис. 2.21).

Рис. 2.21. Элементы системного реестра, создаваемые сценарием Registry.js


После этого параметр ExampleValue и раздел ExampleKey последовательно удаляются из реестра.

Листинг 2.44. Работа с системным реестром (JScript)

Реализация того же сценария на языке VBScript приведена в листинге 2.45.

Листинr 2.45. Работа с системным реестром (VBScript)

Работа с ресурсами локальной сети

Стандартным объектом, позволяющим выполнять типовые операции с локальной сетью, является WshNetwork. С помощью этого объекта можно:

• узнать сетевое имя компьютера, имя текущего пользователя и название домена, в котором он зарегистрировался;

• получить список всех сетевых дисков и всех сетевых принтеров, подключенных к рабочей станции;

• подключить или отключить сетевой диск и принтер;

• установить сетевой принтер в качестве принтера, используемого по умолчанию.

!

Для решения более сложных задач, связанных с администрированием локальной сети, можно применять имеющиеся в Windows ХР технологии ADSI — Active Directory Service Interface и WMI — Windows Management Instrumentation. 

Определение имен рабочей станции, пользователя и домена

Для того чтобы из сценария узнать имя текущего пользователя, домена и компьютера в сети, можно использовать соответствующие свойства объекта WshNetwork: UserName, Domain и ComputerName. Примеры сценариев на языках JScript и VBScript, которые выводят на экран такую информацию, приведены в листингах 2.46 и 2.47.

Листинг 2.46. Вывод сетевых параметров станции (JScript)
Листинг 2.47. Вывод сетевых параметров станции и списков подключенных сетевых ресурсов (VBScript)

Получение списка подключенных сетевых дисков и принтеров

У объекта WshNetwork имеются методы EnumNetworkDrives и EnumPrinterConnections, с помощью которых можно создать коллекции, содержащие, соответственно, сведения о всех подключенных к локальной станции сетевых дисках и сетевых принтерах. Эти коллекции устроены следующим образом: первым элементом является буква диска или название порта, вторым — сетевое имя ресурса, с которым связан этот диск или принтер. Та же последовательность сохраняется для всех элементов коллекции.

В листингах 2.48 и 2.49 приведены сценарии на языках JScript и VBScript соответственно, в которых на экран выводятся диалоговые окна, содержащие информацию о сетевых дисках и сетевых принтерах, подключенных к рабочей станции (рис. 2.22).

Рис. 2.22. Выводимая сценарием ListNetworkResources.js информация о подключенных сетевых ресурсах


Листинг 2.48. Вывод списка подключенных сетевых ресурсов (JScript)
Листинг 2.49. Вывод списка подключенных сетевых ресурсов (VBScript)

Подключение и отключение сетевых дисков и принтеров

Имеющиеся в локальной сети общедоступные ресурсы (диски и принтеры) можно посредством сценария подключить к рабочей станции для совместного использования. Подключаемому сетевому диску при этом нужно поставить в соответствие незанятую букву локального диска (например, если в системе уже имеются диски С:, D: и Е: (локальные или сетевые), то сетевой диск можно подключить под буквой F: или K:, но не Е:). В случае подключения сетевого принтера можно либо напрямую соединиться с этим принтером (для печати из приложений Windows), либо поставить в соответствие удаленному принтеру локальный порт (для печати из старых приложений MS-DOS).

!

Сетевые диски и принтеры также можно подключить с помощью Проводника Windows или выполнив соответствующую команду NET USE.

В качестве примера рассмотрим JScript-сценарий MapResources.js (листинг 2.50), в котором производится подключение диска K: к сетевому ресурсу \\RS_NT_Server\d и установка связи локального порта LPT1 с сетевым принтером \\104_Stepankova\HP.

Сначала нужно создать экземпляры объектов WshNetwork и WshShell:

WshNetwork = WScript.CreateObject("WScript.Network");
WshShell = WScript.CreateObject("WScript.Shell");

Для того чтобы подключить сетевой диск к устройству K:, нужно быть уверенным, что с этой буквой уже не связан сетевой диск (иначе произойдет ошибка). Поэтому предварительно отключается сетевой диск с помощью метода RemoveNetworkDrive:

WshNetwork.RemoveNetworkDrive(Drive);

(переменной Drive заранее было присвоено значение "K:"). При выполнении этой команды может произойти ошибка времени выполнения (например, диск K: не существует или возникла ошибка при отключении связанного с ним сетевого ресурса), поэтому вызов метода RemoveNetworkDrive помещается внутрь блока try конструкции try…catch языка JScript, которая позволяет обрабатывать такие ошибки:

try {
 //Отключаем сетевой диск
 WshNetwork.RemoveNetworkDrive(Drive);
} catch (e) { //Обрабатываем возможные ошибки
if (е.number != 0) {
 //Выводим сообщение об ошибке
 IsError=true;
 Mess="Ошибка при отключении диска "+Drive + "\nКод ошибки: "+
  е.number+"\nОписание: " + е.description;
 WshShell.Popup(Mess, 0, "Отключение сетевого диска", vbCritical);
 }
}

Теперь в случае возникновения ошибки при работе метода RemoveNetworkDrive управление передастся внутрь блока catch, а в полях переменной-объекта е будет содержаться информация о произошедшей ошибке (е.number — числовой код ошибки, е.description — краткое описание ошибки); эта информация отображается в диалоговом окне (рис. 2.23).

Рис. 2.23. Информация об ошибке, произошедшей при отключении диска K:


Если же отключение диска K: прошло успешно, на экран выводится диалоговое окно с информацией об этом (рис. 2.24):

if (!IsError) { //Все в порядке
 Mess="Диск "+Drive+" отключен успешно";
 WshShell.Popup(Mess, 0, "Отключение сетевого диска", vbInformation);
}

Рис. 2.24. Информация об успешном отключении диска K:


Аналогичный блок try…catch используется и при подключении сетевого диска:

try {
 //Подключаем сетевой диск
 WshNetwork.MapNetworkDrive(Drive, NetPath);
} catch (e) {
 //Обрабатываем возможные ошибки
 if (e != 0) {
  //Выводим сообщение об ошибке
  IsError=true;
  Mess="Ошибка при подключении диска " + Drive + " к " + NetPath+
   "\nКод ошибки: "+е.number + "\nОписание: "+е.description;
   WshShell.Popup(Mess, 0, "Подключение сетевого диска", vbCritical);

Если, например, пользователь, который подключает сетевой диск, не имеет соответствующих прав доступа к сетевому ресурсу, то на экран выведется диалоговое окно, изображенное на рис. 2.25.

Рис. 2.25. Информация об ошибке, произошедшей при подключении диска K:


Освобождение локального порта (метод RemovePrinterConnection), подключение сетевого принтера к этому порту (метод AddPrinterConnection) и обработка ошибок времени выполнения, которые могут возникнуть при этих действиях, производится в сценарии аналогичным образом.

Листинг 2.50. Отключение и подключение сетевых ресурсов (JScript)

Реализация того же сценария на языке VBScript представлена в листинге 2.51. Главное отличие здесь состоит в способе обработки возможных ошибок времени выполнения. В VBScript для этой цели предназначен оператор On Error Resume Next — при возникновении ошибки после выполнения этого оператора сценарий не прервется, а просто перейдет к выполнению следующей строки кода. Проанализировать же возникшую ошибку можно с помощью специального объекта Err, в полях Number и Description которого будут соответственно содержаться код и описание ошибки.

Листинг 2.51. Отключение и подключение сетевых ресурсов (VBScript)

Запуск сценариев на удаленных машинах. Контроль за ходом выполнения таких сценариев

Начиная с версии 5.6 сценарии WSH можно запускать не только на локальной машине, но и на других компьютерах, имеющихся в сети (это может быть очень удобно для централизованного администрирования удаленных рабочих станций).

Такие WSH-сценарии называются удаленными сценариями (remote scripts). При этом файл со сценарием может находиться либо на локальной машине, либо на общедоступном сетевом ресурсе. На жесткий диск удаленной машины файл сценария копироваться не будет — вместо этого текст сценария по коммуникационному протоколу DCOM — Distributed СОМ (распределенный СОМ) передается непосредственно в память процесса, запускаемого на этой машине.

Естественно, такой механизм запуска сценариев является весьма мощным средством удаленного администрирования, однако он также может быть использован для быстрого и практически незаметного распространения по сети вирусов. Поэтому при использовании удаленных сценариев WSH предусмотрены довольно строгие меры безопасности.

Во-первых, и на локальной и на удаленной машинах должны быть установлены операционные системы Windows NT (SP 3)/Windows 2000/Windows ХР (системы Windows 95/98/ME не поддерживаются).

Во-вторых, пользователь, который запускает сценарий, должен входить в группу локальных администраторов на той машине, где должен выполняться сценарий.

В-третьих, удаленная машина должна быть предварительно настроена для выполнения удаленных сценариев (по умолчанию после первоначальной установки выполнение таких сценариев запрещено). Для этого необходимо записать 1 в следующий параметр системного реестра:

HKLM\Software\Microsoft\Windows Script Host\Settings\Remote (А)

(если этот параметр не существует, его нужно создать). Если значением этого параметра является 0, то это означает, что выполнение удаленных сценариев на машине запрещено.

Для того чтобы разрешить выполнение удаленных сценариев на уровне пользователя, необходимо создать параметр

HKCU\Software\Microsoft\Windows Script Host\Settings\Remote (Б)

и также записать в него 1. Если значением этого параметра является 0, то это означает, что выполнение удаленных сценариев для текущего пользователя запрещено.

Также при настройке режима выполнения удаленных сценариев нужно проверить значение параметра

HKLM\Software\Microsoft\Windows Script Host\Settings\IgnoreUserSettings (В)

Если значением этого параметра является 1, то параметр (Б) игнорируется и проверяется только значение параметра (А). Если же значением параметра (В) является 0, то WSH сначала проверяет параметр (Б) и только в случае его отсутствия принимается во внимание значение параметра (А).

Если удаленные сценарии нужно выполнять на машине с операционной системой Windows ХР, то на этой машине нужно перерегистрировать сервер wscript.exe с помощью следующей команды:

wscript.exe -regserver

Удаленные сценарии всегда запускаются с помощью сервера wscript.exe, причем в этих сценариях не поддерживается вывод на экран удаленного компьютера никаких элементов пользовательского интерфейса (не выводятся даже диалоговые окна с сообщениями о возникающих в ходе выполнения ошибках). Другими словами, в удаленных сценариях по умолчанию нельзя использовать методы WScript.Echo или WshShell.Popup (это может привести к непредсказуемым результатам).

Для примера рассмотрим сценарий RemoteShortcut.js (листинг 2.52), который создает ярлык в специальной папке AllUserDesktop (рабочий стол для всех пользователей). Предположим, что этот сценарий находится в корневом каталоге диска D:, а запустить сценарий необходимо на компьютере \\Stand.

Листинг 2.52. Сценарий для запуска на удаленной машине (JScript)

Для запуска сценария RemoteShortcut.js на удаленном компьютере \\Stand нужно создать другой сценарий RunRemoteScript.js (листинг 2.53). Здесь вначале создается объект WshController:

Controller = WScript.CreateObject("WshController");

Затем мы получаем ссылку на экземпляр объекта WshRemote на машине \\Stand, соответствующий сценарию с текстом, взятым из файла D:\RemoteScript.js:

RemScript = Controller.CreateScript("D:\\RemoteScript.js", "stand");

Запускается удаленный сценарий с помощью метода Execute:

RemScript.Execute();

После этого нужно дождаться окончания работы сценария на удаленной машине, что делается путем контроля в цикле while свойства Status объекта WshRemote (значение свойства status, равное 2, говорит о том, что выполнение удаленного сценария завершено):

while (RemScript.Status != 2)
 //Цикл выполняется до завершения удаленного сценария
 WScript.Sleep(100); //Приостанавливаем сценарий на 0,1 сек

Метод Sleep объекта WScript вызывается в цикле для того, чтобы освободить процессор во время ожидания завершения удаленного сценария (листинг 2.53).

Листинг 2.53. Запуск удаленного сценария (JScript)

В листинге 2.54 приведен аналог сценария RunRemoteScript.js на языке VBScript.

Листинг 2.54. Запуск удаленного сценария (VBScript)

Контролировать ход выполнения удаленных сценариев можно не только путем анализа свойства Status, но и с помощью обработки событий Start (запуск сценария), Error (ошибка при выполнении сценария) и End (завершение работы сценария) объекта WshRemote; соответствующие примеры сценариев на языках JScript и VBScript приведены в листингах 2.55 и 2.56.

Напомним, что для обработки событий объекта нужно в сценарии сначала создать экземпляр этого объекта, а затем соединиться с ним при помощи метода ConnectObject, указав нужный префикс для функций-обработчиков:

Controller = WScript.CreateObject("WshController");
RemScript = Controller.CreateScript("D:\\RemoteScript.js ", "stand");
WScript.ConnectObject(RemScript, "RemoteScript_");

Затем в тексте сценария описываются функции RemoteScript_Start, RemoteScript_Error и RemoteScript_End, управление в которые будет передаваться при наступлении соответствующих событий.

Листинг 2.55. Обработка событий объекта WshRemote (JScript)
Листинг 2.56. Обработка событий объекта WshRemote (VBScript)
!

При контроле за ходом выполнения удаленного сценария с помощью обработки событий объекта WshRemote затрачивается больше ресурсов компьютера по сравнению с простой проверкой свойства Status. Кроме этого, при обработке событий увеличивается сетевой трафик между локальной и удаленной машинами. 



 

Глава 2. Примеры использованиястандартных объектов WSH (JScript и VBScript)