В этой главе мы на примерах подробно рассмотрим, как с помощью стандартных объектов WSH 5.6, описание которых приведено в главе 1, можно решать некоторые практические задачи, связанные, в частности, с выводом и вводом текстовой информации, запуском других приложений (как на локальной, так и на удаленной машине), созданием ярлыков в различных папках, работой с системным реестром и локальной сетью. Практически все сценарии приведены как на языке JScript, так и на VBScript, и снабжены подробными комментариями.
Сформированные в сценарии строки текста можно выводить в стандартный выходной поток (в консольном режиме) или в графическое диалоговое окно несколькими способами:
□ с помощью метода
Echo
объекта WScript
;
□ с помощью методов
Write
и WriteLine
объекта WScript.StdOut
;
□ с помощью функции
MsgBox
языка VBScript;
□ с помощью метода
Popup
объекта WshShell
.
Примеры использования метода
WScript.Echo
в сценариях, написанных на языках JScript и VBScript, представлены соответственно в листингах 2.1 и 2.2.
Для корректного отображения с помощью метода Echo символов кириллицы, эти символы должны быть представлены в Windows-кодировке (CP 1251).
WScript.Echo
(JScript)/*******************************************************************/
/* Имя: Echo1.js */
/* Язык: JScript */
/* Описание: Пример использования метода WScript.Echo */
/*******************************************************************/
//Печатаем строку текста (кириллица)
WScript.Echo("Использование метода Echo (Win-кодировка)");
//Печатаем строку текста и результат вычислений
WScript.Echo("Например, 1+2=",1+2);
/************* Конец *********************************************/
'*******************************************************************
' Имя: Echo1.vbs
' Язык: VBScript
' Описание: Пример использования метода WScript.Echo
'*******************************************************************
' Печатаем строку текста (кириллица)
WScript.Echo "Использование метода Echo (Win-кодировка)"
' Печатаем строку текста и результат вычислений
WScript.Echo "Например, 1+2=",1+2
'************* Конец *********************************************
Если сценарий 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. Диалоговое окно с несколькими строками текста
/*******************************************************************/
/* Имя: Echo2.js */
/* Язык: JScript */
/* Описание: Вывод сразу нескольких строк (WScript.Echo) */
/*******************************************************************/
var s; //Объявляем переменную
s="Пример\nвывода\nнескольких\nстрок"; //Формируем строки
WScript.Echo(s); //Печатаем строки
/************* Конец *********************************************/
'*******************************************************************
' Имя: Echo2.vbs
' Язык: VBScript
' Описание: Вывод сразу нескольких строк (WScript.Echo)
'*******************************************************************
Option Explicit
Dim s ' Объявляем переменную
' Формируем строки
s="Пример"&vbCrLf&"вывода"&vbCrLf&"нескольких"&vbCrLf&"строк"
WScript.Echo s ' Печатаем строки
'************* Конец *********************************************
Для вывода строк в сценариях, выполняющихся в консольном режиме, можно использовать стандартный выходной поток
WScript.StdOut
(листинги 2.5 и 2.6). Напомним, что запускать сценарий, обращающийся к потоку StdOut
, можно только в консольном режиме с помощью cscript.exe. Если же попробовать выполнить, например, сценарий StdOut1.js с помощью wscript.exe, то произойдет ошибка (рис. 2.4).
Рис. 2.4. Ошибка, возникающая при обращении к
StdOut
в графическом режиме
/*******************************************************************/
/* Имя: StdOut1.js */
/* Язык: JScript */
/* Описание: Пример использования методов StdOut.Write и */
/* StdOut.WriteLine */
/*******************************************************************/
var n; //Объявляем переменную
n=1+2;
//Печать без перевода строки
WScript.StdOut.Write("Использование метода ");
//Выводим строку с текущей позиции курсора
WScript.StdOut.WriteLine("StdOut.WriteLine");
//Печатаем строку и значение переменной
WScript.StdOut.WriteLine("Например, 1+2="+n);
/************* Конец *********************************************/
'*******************************************************************
' Имя: StdOut1.vbs
' Язык: VBScript
' Описание: Пример использования методов StdOut.Write и StdOut.WriteLine
'*******************************************************************
Option Explicit
Dim n ' Объявляем переменную
n=1+2
' Печать без перевода строки
WScript.StdOut.Write "Использование метода "
' Выводим строку с текущей позиции курсора
WScript.StdOut.WriteLine "StdOut.WriteLine"
В Windows ХР символы кириллицы, посылаемые из сценария в стандартный выходной поток, должны быть представлены в Windows-кодировке (CP 1251). В предыдущих версиях Windows для корректного отображения на экране символы кириллицы при использовании потока
WScript.StdOut
должны быть в DOS-кодировке (OEM 866).
Как и при использовании метода
WScript.Echo
, в качестве параметра метода WriteLine
можно указывать строки, содержащие символы перевода строки (листинги 2.7 и 2.8).
StdOut
сразу нескольких строк (JScript)/*******************************************************************/
/* Имя: StdOu2.js */
/* Язык: JScript */
/* Описание: Вывод сразу нескольких строк (StdOut.WriteLine) */
/*******************************************************************/
var s; //Объявляем переменную
s="Пример\nвывода\nнескольких\nстрок"; //Формируем строки
WScript.StdOut.WriteLine(s); //Выводим строки
/************* Конец *********************************************/
StdOut
сразу нескольких строк (VBScript)'*******************************************************************
' Имя: StdOut2.vbs
' Язык: VBScript
' Описание: Вывод сразу нескольких строк (StdOut.WriteLine)
'*******************************************************************
Option Explicit
Dim s ' Объявляем переменную
' Формируем строки
s="Пример"&vbCrLf&"вывода"&vbCrLf&"нескольких"&vbCrLf&"строк"
WScript.StdOut.WriteLine s ' Выводим строки
'************* Конец *********************************************
Для создания более компактного текста сценария можно сразу сохранить ссылку на стандартный выходной поток
WScript.StdOut
в отдельную переменную и затем при вызове методов Write
и WriteLine
использовать эту переменную (листинги 2.9 и 2.10).
StdOut
в переменной (JScript)/*******************************************************************/
/* Имя: StdOut3.js */
/* Язык: JScript */
/* Описание: Пример использования метода StdOut.WriteLine */
/*******************************************************************/
var n,StdOut; //Объявляем переменные
n=1+2;
StdOut=WScript.StdOut; //Сохраняем ссылку на StdOut в переменной
//Выводим строки в StdOut
StdOut.WriteLine("Пример использования метода StdOut.WriteLine() ...");
StdOut.WriteLine("1+2="+n);
/************* Конец *********************************************/
'*******************************************************************
' Имя: StdOut3.vbs
' Язык: JScript
' Описание: Пример использования метода StdOut.WriteLine
'*******************************************************************
Option Explicit
Dim n,StdOut ' Объявляем переменные
n=1+2
Set StdOut=WScript.StdOut ' Сохраняем ссылку на StdOut в переменной
' Выводим строки в StdOut
StdOut.WriteLine "Это пример использования метода StdOut.WriteLine() ..."
StdOut.WriteLine "1+2=" & n
'************* Конец *********************************************
В языке VBScript существует специальная функция
MsgBox
, с помощью которой можно выводить информацию в диалоговое окно с несколькими кнопками; также в этом окне можно задавать заголовок и значок (рис. 2.5).
Рис. 2.5. Диалоговое окно, созданное с помощью функции
MsgBox
Пример сценария, создающего такое диалоговое окно, приведен в листинге 2.11.
В языке JScript аналога функции
MsgBox
нет.
'*******************************************************************
' Имя: MsgBox.vbs
' Язык: VBScript
' Описание: Пример использования функции MsgBox
'*******************************************************************
Dim Res,Text,Title ' Объявляем переменные
Text="Пример вывода строк в диалоговое" & vbCrLf & " окно VBScript"
Title="Заголовок"
' Выводим диалоговое окно на экран
Res=MsgBox(Text,vbOkCancel+vbInformation+vbDefaultButton2,Title)
' Определяем, какая из кнопок была нажата в диалоговом окне
If Res=vbOk Then
MsgBox "Нажата кнопка OK"
Else
MsgBox "Нажата кнопка Отмена"
End If
'************* Конец *********************************************
Подробное описание функции
MsgBox
приведено в приложении 1. Здесь же мы отметим только то, что значением функции MsgBox
является константа, соответствующая нажатой в диалоговом окне кнопки (в нашем примере такими константами являются vbOk
и vbCancel
). Таким образом, MsgBox
может использоваться в сценариях для организации выбора пользователем одного из возможных вариантов, однако это не совсем удобно, т.к. надписи на кнопках нельзя задавать произвольным образом (можно указать только OK, Отмена, Стоп, Повтор, Пропустить, Да и Нет).
С помощью метода
Popup
(подробное описание метода приведено в главе 1) можно создавать такие же диалоговые окна, как и при помощи функции MsgBox
, причем этот метод можно использовать как в VBScript-, так и в JScript-сценариях (листинги 2.12 и 2.13).
Popup
(JScript)/*******************************************************************/
/* Имя: Popup.js */
/* Язык: JScript */
/* Описание: Пример использования метода WshShell.Popup */
/*******************************************************************/
var WshShell,Res,Text,Title; //Объявляем переменные
//Инициализируем константы для диалоговых окон
var vbOkCancel=1,vbOk=1;
//Создаем объект WshShell
WshShell = WScript.CreateObject("WScript.Shell");
Text="Пример вывода строк в диалоговое\nокно WScript";
Title="Заголовок"
//Выводим диалоговое окно на экран
Res=WshShell.Popup(Text,0,Title,vbOkCancel);
// Определяем, какая из кнопок была нажата в диалоговом окне
if (Res==vbOk) WshShell.Popup("Нажата кнопка OK");
else WshShell.Popup("Нажата кнопка Отмена");
/************* Конец *********************************************/
Popup
(VBScript)'*******************************************************************
' Имя: Popup.vbs
' Язык: VBcript
' Описание: Пример использования метода WshShell.Popup
'*******************************************************************
Option Explicit
Dim WshShell,Res,Text,Title ' Объявляем переменные
' Создаем объект WshShell
Set WshShell = WScript.CreateObject("WScript.Shell")
Text="Пример вывода строк в диалоговое" & vbCrLf & "окно WScript"
Title="Заголовок"
' Выводим диалоговое окно на экран
Res=WshShell.Popup(Text,0,Title,vbOkCancel)
' Определяем, какая из кнопок была нажата в диалоговом окне
If (Res=vbOk) Then
WshShell.Popup "Нажата кнопка OK"
Else
WshShell.Popup "Нажата кнопка Отмена"
End If
'************* Конец *********************************************
Главным отличием метода
Popup
от функции MsgBox
является наличие параметра nSecToWait
, задающего время (в секундах), по истечении которого диалоговое окно будет автоматически закрыто. Если этот параметр равен нулю, как в приведенных выше примерах, то окно будет закрыто только после нажатия какой-либо кнопки в нем.
Для организации в сценариях диалога с пользователем необходимо уметь принимать вводимые с клавиатуры строки текста. В консольном и графическом режимах ввод информации осуществляется по-разному: при запуске сценария с помощью cscript.exe мы имеем доступ к стандартному входному потоку
StdOut
, при использовании wscript.exe можно применять функцию InputBox
языка VBScript.
Самый простой способ ввести строку в консольном режиме предоставляет метод
WScript.StdIn.ReadLine
, при использовании этого метода ввод завершается нажатием клавиши Отметим, что при использовании стандартного входного потока
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
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-кодировке, соответствующего этой букве.
StdIn.ReadLine
(JScript)/*******************************************************************/
/* Имя: StdIn1.js */
/* Язык: JScript */
/* Описание: Пример использования метода StdIn.ReadLine */
/*******************************************************************/
var s,RusDict; //Объявляем переменные
//Функция для создания объекта Dictionary с парами "ключ-значение", где
//"ключ"-буква в 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("п", "я");
}
//Функция для перевода строки из DOS- в Windows-кодировку
function DosToWin(s) {
var i,ss; //Объявляем переменные
//Проверяем, создан ли объект RusDict
if (typeof(RusDict)=="undefined")
//Если объект RusDict не создан, создаем его
MakeRusDict();
ss="";
for (i=0;i
if (RusDict.Exists(s.charAt(i))) //Проверяем наличие символа в словаре
//Преобразуем i-й символ в Windows-кодировку
ss+=RusDict.Item(s.charAt(i));
else ss+=s.charAt(i);
}
return ss;
}
/************* Начало *********************************************/
//Печатаем приглашение для ввода
WScript.StdOut.Write("Введите одну строку: ");
s = WScript.StdIn.ReadLine(); //Вводим строку с клавиатуры
WScript.StdOut.WriteBlankLines(1); //Печатаем пустую строку
WScript.StdOut.Write("Было введено: ");
//Преобразовываем введенную строку в Windows-кодировку
//и выводим ее на экран
WScript.StdOut.WriteLine(DosToWin(s));
/************* Конец *********************************************/
'*******************************************************************
' Имя: StdIn1.vbs
' Язык: VBScript
' Описание: Пример использования метода StdIn.WriteLine
'*******************************************************************
' Функция для перевода строки из DOS- в Windows-кодировку
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
'************* Начало *********************************************
Dim s
' Печатаем приглашение для ввода
WScript.StdOut.Write "Введите одну строку: "
s = WScript.StdIn.ReadLine ' Вводим строку с клавиатуры
WScript.StdOut.WriteBlankLines 1 ' Печатаем пустую строку
WScript.StdOut.Write "Было введено: "
' Преобразовываем введенную строку в Windows-кодировку
' и выводим ее на экран
WScript.StdOut.WriteLine DosToWin(s)
'************* Конец *********************************************
Используя метод
WScript.StdIn.ReadAll
, можно ввести сразу несколько строк подряд, ввод при этом прекращается после нажатия клавиш split
объекта string
, а в VBScript — одноименная внутренняя функция Split
(листинги 2.16 и 2.17).
StdIn.ReadAll
(JScript)/*******************************************************************/
/* Имя: StdIn2.js */
/* Язык: JScript */
/* Описание: Пример использования метода StdIn.ReadAll */
/*******************************************************************/
var RusDict;
//Функция для создания объекта Dictionary с парами "ключ-значение", где
//"ключ"-буква в 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("п", "я");
}
//Функция для перевода строки из DOS- в Windows-кодировку
function DosToWin(s) {
var i,ss; //Объявляем переменные
//Проверяем, создан ли объект RusDict
if (typeof(RusDict)=="undefined")
//Если объект RusDict не создан, создаем его
MakeRusDict();
ss="";
for (i=0;i
if (RusDict.Exists(s.charAt(i))) //Проверяем наличие символа в словаре
//Преобразуем i-й символ в Windows-кодировку
ss+=RusDict.Item(s.charAt(i));
else ss+=s.charAt(i);
}
return ss;
}
/************* Начало *********************************************/
var s,ArrS,i; //Объявляем переменные
//Печатаем приглашение для ввода
WScript.StdOut.WriteLine("Вводите строки:");
s = WScript.StdIn.ReadAll(); //Вводим строки с клавиатуры
WScript.StdOut.WriteBlankLines(3); //Печатаем пустые строки
ArrS=s.split("\n"); //Формируем массив из введенных строк
WScript.StdOut.WriteLine("Всего ведено строк: "+ArrS.length);
for (i=1;i<=ArrS.length;i++)
//Преобразовываем введенные строки в Windows-кодировку
//и выводим их на экран
WScript.StdOut.WriteLine(i+": "+DosToWin(ArrS[i-1]));
/************* Конец *********************************************/
StdIn.ReadAll
(VBScript)'*******************************************************************
' Имя: StdIn2.vbs
' Язык: VBScript
' Описание: Пример использования метода StdIn.ReadAll
'*******************************************************************
Option Explicit
' Функция для перевода строки из DOS- в Windows-кодировку
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
'************* Начало *********************************************
Dim s,ArrS,i,ColStr ' Объявляем переменные
' Печатаем приглашение для ввода
WScript.StdOut.WriteLine "Вводите строки:"
s = WScript.StdIn.ReadAll ' Вводим строки с клавиатуры
WScript.StdOut.WriteBlankLines 3 ' Печатаем пустые строки
ArrS=Split(s,vbCrLf) ' Формируем массив из введенных строк
ColStr=UBound(ArrS)+1
' Печатаем введенные строки
WScript.StdOut.WriteLine "Всего ведено строк: " & ColStr
For i=1 To ColStr
' Преобразовываем введенные строки в Windows-кодировку
' и выводим их на экран
WScript.StdOut.WriteLine i & ": " & DosToWin(ArrS(i-1))
Next
'************* Конец *********************************************/
В сценариях VBScript в графическом режиме информацию можно вводить с помощью диалогового окна, создаваемого внутренней функцией
InputBox
(рис. 2.6).
Рис. 2.6. Диалоговое окно со строкой ввода
Пример сценария, использующего функцию
InputBox
, представлен в листинге 2.18 (подробное описание параметров функции InputBox см. в приложении 1).
'*******************************************************************
' Имя: InpBox.vbs
' Язык: VBScript
' Описание: Пример использования функции InputBox
'*******************************************************************
Option Explicit
Dim s,s1 ' Объявляем переменные
s1="Пример" & vbCrLf & "диалогового окна" & vbCrLf & "для ввода строки"
' Выводим диалоговое окно со строкой ввода на экран
s=InputBox(s1,"Диалоговое окно VBScript")
' Выводим диалоговое окно с введенной строкой
MsgBox "Было введено: " & s
'************* Конец *********************************************/
К сожалению, ни в языке JScript, ни в объектной модели WSH нет функции или метода, позволяющих напрямую создавать диалоговые окна со строкой ввода. Однако при помощи файлов сценариев с XML-разметкой, описанных в главе 3, функции языка VBScript (
InputBox
в частности) можно использовать внутри JScript-сценария (соответствующий пример приведен в листинге 3.11).
На практике часто бывает необходимо знать определенные атрибуты 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 в графическом режиме
/*******************************************************************/
/* Имя: PropScript.js */
/* Язык: JScript */
/* Описание: Вывод свойств запущенного сценария */
/*******************************************************************/
//Проверка режима, в котором запущен сценарий
function IsCScript() {
return ("c"== WScript.FullName.toLowerCase().charAt(WScript.FullName.length - 11));
}
//Возвращает каталог, содержащий запущенный сценарий
function GetScriptDir() {
var ScriptDir;
ScriptDir = WScript.ScriptFullName;
ScriptDir = ScriptDir.substring(0, ScriptDir.lastIndexOf("\\"));
return ScriptDir;
}
/******************* Начало **********************************/
var WshShell,s; //Объявляем переменные
//Создаем объект WshShell
WshShell=WScript.CreateObject("WScript.Shell");
s=" Свойства запущенного сценария:\n\n";
//Проверяем, в каком режиме был запущен сценарий
if (IsCScript()) s+="Запущен в консольном режиме\n";
else s+="Запущен в графическом режиме\n";
//Определяем остальные параметры
s+="Путь к серверу: "+WScript.FullName+"\n";
s+="Каталог сервера: "+WScript.Path+"\n";
s+="Версия WSH: "+WScript.Version+"\n\n";
s+="Текущий каталог: "+ WshShell.CurrentDirectory+"\n";
s+="Путь к сценарию: "+WScript.ScriptFullName+"\n";
s+="Каталог сценария: "+GetScriptDir()+"\n";
s+="Имя сценария: "+WScript.ScriptName+"\n";
WScript.Echo(s); //Выводим сформированные строки
/************* Конец *********************************************/
'*******************************************************************
' Имя: PropScript.vbs
' Язык: VBScript
' Описание: Вывод свойств запущенного сценария
'*******************************************************************
Option Explicit
' Проверка режима, в котором запущен сценарий
Function IsCScript()
IsCScript=("c"=Mid(LCase(WScript.FullName),Len(WScript.FullName)-10,1))
End Function
' Возвращает каталог, содержащий запущенный сценарий
Function GetScriptDir()
Dim ScriptDir
ScriptDir = WScript.ScriptFullName
ScriptDir = Left(ScriptDir, InstrRev(ScriptDir,"\")-1)
GetScriptDir=ScriptDir
End Function
'******************* Начало **********************************/
Dim WshShell,s ' Объявляем переменные
' Создаем объект WshShell
Set WshShell=WScript.CreateObject("WScript.Shell")
s=" Свойства запущенного сценария:" & vbCrLf & vbCrLf
' Проверяем, в каком режиме был запущен сценарий
If IsCScript() Then
s=s & "Запущен в консольном режиме" & vbCrLf
Else
s=s & "Запущен в графическом режиме" & vbCrLf
End If
' Определяем остальные параметры
s=s & "Путь к серверу: " & WScript.FullName & vbCrLf
s=s & "Каталог сервера: " & WScript.Path & vbCrLf
s=s & "Версия WSH: " & WScript.Version & vbCrLf & vbCrLf
s=s & "Текущий каталог: "+ WshShell.CurrentDirectory & vbCrLf
s=s & "Путь к сценарию: " & WScript.ScriptFullName & vbCrLf
s=s & "Каталог сценария: " & GetScriptDir() & vbCrLf
s=s & "Имя сценария: " & WScript.ScriptName & vbCrLf
WScript.Echo s ' Выводим сформированные строки
'************* Конец *********************************************
Используя аргументы командной строки, в сценарии можно передавать различную информацию, скажем, те или иные переключатели или имена пользователей и рабочих станций. При задании аргумента можно указать либо только его значение, либо имя вместе со значением в следующем формате: "Имя_аргумента:Значение".
Как в имени аргумента, так и в его значении могут использоваться символы кириллицы.
Например, выполнив в командном окне строку
cscript Example.js /Имя:"Андрей Попов" /Возраст:30
или
cscript Example.js /Возраст:30 /Имя:"Андрей Попов"
мы передадим в сценарий Example.js два параметра: "Имя" со значением "Андрей Попов" и "Возраст" со значением "30". Значения этих параметров можно было передать и как безымянные параметры:
cscript Example.js "Андрей Попов" 30
Однако в последнем случае при задании безымянных аргументов будет важен порядок их указания в командной строке.
В WSH для обработки параметров командной строки служат следующие объекты-коллекции:
□
WshArguments
(содержит все параметры, как именные, так и безымянные);
□
WshNamed
(содержит только именные параметры);
□
WshUnnamed
(содержит только безымянные параметры).
Описание аргументов командной строки в сценариях можно задавать с помощью XML-элементов
,
и
(см. главу 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
/********************************************************************/
/* Имя: Args.js */
/* Язык: JScript */
/* Описание: Работа с аргументами запущенного сценария */
/********************************************************************/
var
i,objArgs,s,objNamedArgs,objUnnamedArgs; //Объявляем переменные
objArgs = WScript.Arguments; //Создаем объект WshArguments
//Определяем общее количество аргументов
s="Всего аргументов: "+objArgs.Count()+"\n";
for (i=0; i<=objArgs.Count()-1; i++)
s+=objArgs(i)+"\n"; //Формируем строки со значениями аргументов
objUnnamedArgs=objArgs.Unnamed; //Создаем объект WshUnnamed
//Определяем количество безымянных аргументов
s+="\nБезымянных аргументов: "+objUnnamedArgs.length+"\n";
for (i=0; i<=objUnnamedArgs.length-1; i++)
//Формируем строки со значениями безымянных аргументов
s+=objUnnamedArgs(i)+"\n";
objNamedArgs=objArgs.Named; //Создаем объект WshNamed
//Определяем количество именных аргументов
s+="\nИменных аргументов: "+objNamedArgs.length+"\n";
//Проверяем, существует ли аргумент /Имя:
if (objNamedArgs.Exists("Имя")) s+=objNamedArgs("Имя")+"\n";
//Проверяем, существует ли аргумент /Comp:
if (objNamedArgs.Exists("Comp")) s+=objNamedArgs("Comp")+"\n";
WScript.Echo(s); //Выводим сформированные строки
/************* Конец *********************************************/
'********************************************************************
' Имя: Args.vbs
' Язык: VBScript
' Описание: Работа с аргументами запущенного сценария
'********************************************************************
Option Explicit
Dim i,Arg,objArgs,s,objNamedArgs,objUnnamedArgs ' Объявляем переменные
Set objArgs = WScript.Arguments ' Создаем объект WshArguments
' Определяем общее количество аргументов
s="Всего аргументов: " & objArgs.Count() & vbCrLf
For Each Arg In objArgs
s=s & Arg & vbCrLf ' Формируем строки со значениями аргументов
Next
Set objUnnamedArgs=objArgs.Unnamed ' Создаем объект WshUnnamed
' Определяем количество безымянных аргументов
s=s & vbCrLf & "Безымянных аргументов: " & objUnnamedArgs.length & vbCrLf
For Each Arg In objUnnamedArgs
' Формируем строки со значениями безымянных аргументов
s=s & Arg & vbCrLf
Next
Set objNamedArgs=objArgs.Named ' Создаем объект WshNamed
' Определяем количество именных аргументов
s=s & vbCrLf & "Именных аргументов: " & objNamedArgs.Length & vbCrLf
' Проверяем, существует ли аргумент /Имя:
If objNamedArgs.Exists("Имя") Then
s=s & objNamedArgs("Имя") & vbCrLf
End If
' Проверяем, существует ли аргумент /Comp:
If objNamedArgs.Exists("Comp") Then
s=s & objNamedArgs("Comp") & vbCrLf
End If
WScript.Echo s ' Выводим сформированные строки
'************* Конец *********************************************
Любое приложение при завершении своей работы может возвращать операционной системе целое число — код выхода (обычно ненулевое значение этого кода указывает на то, что выполнение программы прервалось в силу той или иной ошибки).
Сама операционная система Windows не проверяет код завершения приложений.
В WSH код выхода из сценария задается с помощью параметра метода
Quit
объекта WScript
. В листингах 2.23 и 2.24 приведены сценарии, в которых код завершения выбирается в зависимости от того, какая кнопка нажата в диалоговом окне (рис. 2.9): кнопке OK соответствует код 1, кнопке Отмена — код 0.
Рис. 2.9. Диалоговое окно, создаваемое в сценарии Quit.js
/*******************************************************************/
/* Имя: Quit.js */
/* Язык: JScript */
/* Описание: Выход из сценария с заданным кодом завершения */
/*******************************************************************/
var WshShell,Res,Text,Title; //Объявляем переменные
var vbOkCancel=1,vbOk=1; //Инициализируем константы для диалоговых окон
//Создаем объект WshShell
WshShell = WScript.CreateObject("WScript.Shell");
Text="Выберите кнопку для завершения сценария";
Title="Диалоговое окно";
//Выводим диалоговое окно на экран
Res=WshShell.Popup(Text,0,Title,vbOkCancel);
if (Res==vbOk) WScript.Quit(1);
else WScript.Quit(0);
/************* Конец *********************************************/
'*******************************************************************
' Имя: Quit.vbs
' Язык: VBScript
' Описание: Выход из сценария с заданным кодом завершения
'*******************************************************************
Option Explicit
Dim WshShell,Res,Text,Title ' Объявляем переменные
' Создаем объект WshShell
Set WshShell = WScript.CreateObject("WScript.Shell")
Text="Выберите кнопку для завершения сценария"
Title="Диалоговое окно"
' Выводим диалоговое окно на экран
Res=WshShell.Popup(Text,0,Title,vbOkCancel)
If Res=1 Then
WScript.Quit 1
Else
WScript.Quit 0
End If
'************* Конец *********************************************
Если сценарий запускался с помощью командного файла, то код выхода можно проанализировать с помощью оператора
IF ERRORLEVEL
.
Пример подобного ВАТ-файла приведен в листинге 2.25. Здесь сценарий Quit.js запускается с помощью команды
START
с ключом /WAIT
, указывающим на то, что выполнение ВАТ-файла должно быть приостановлено до окончания работы Quit.js. После этого, если код завершения pавен 1 (в диалоговом окне сценария была нажата кнопка OK), происходит переход к метке :Ok
и выдача с помощью команды ECHO
соответствующего сообщения на экран.
Для корректного отображения на экране символов кириллицы в BAT-файлах должна использоваться DOS-кодировка.
Если же код завершения сценария Quit.js был равен 0 (в диалоговом окне была нажата кнопка Отмена), то управление перейдет к строке
ECHO Для выхода из Quit.js была нажата кнопка Отмена
@ЕСНО OFF
REM **************************************************************
REM Имя: check.bat
REM Язык: BAT-файл
REM Кодировка: DOS
REM Описание: Определение кода завершения для сценария Quit.js
REM **************************************************************
@ЕСНO OFF
ECHO Запускаем сценарий Quit.js...
START /W Quit.js
REM Определяем код завершения для сценария Quit.js
IF ERRORLEVEL 1 GOTO :Ok
ECHO Для выхода из Quit.js была нажата кнопка Отмена
GOTO :end
:Ok
ECHO Для выхода из Quit.js была нажата кнопка Ok
:end
Для того чтобы из сценария получить доступ к свойствам или методам внешнего сервера автоматизации, вначале надо "создать" соответствующий объект, т.е. загрузить в память экземпляр нужного СОМ-объекта и сохранить в переменной ссылку на этот объект. Напомним, что объект в сценарии может создаваться несколькими способами:
□ с помощью метода
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
/*******************************************************************/
/* Имя: PrintInWord.js */
/* Язык: JScript */
/* Описание: Использование из сценария внешнего объекта */
/* автоматизации (Microsoft Word) */
/*******************************************************************/
var WA,WD,Sel; //Объявляем переменные
//Создаем объект--приложение Microsoft Word
WA=WScript.CreateObject("Word.Application");
//Можно было использовать конструкцию
//WA=new ActiveXObject("Word.Application");
WD=WA.Documents.Add(); //Создаем новый документ (объект Document)
WA.Visible=true; //Делаем Word видимым
Sel=WA.Selection; //Создаем объект Selection
Sel.Font.Size=14; //Устанавливаем размер шрифта
Sel.ParagraphFormat.Alignment=1; //Выравнивание по центру
Sel.Font.Bold=true; //Устанавливаем полужирный шрифт
Sel.TypeText("Привет!\n"); //Печатаем строку текста
Sel.Font.Bold=false; //Отменяем полужирный шрифт
Sel.ParagraphFormat.Alignment=0; //Выравнивание по левому краю
//Печатаем строку текста
Sel.TypeText("Эти строки напечатаны с помощью WSH.");
WD.PrintOut(); //Выводим документ на принтер
/************* Конец *********************************************/
'*******************************************************************
' Имя: PrintInWord.vbs
' Язык: VBScript
' Описание: Использование из сценария внешнего объекта
' автоматизации (Microsoft Word)
'*******************************************************************
Option Explicit
Dim WA,WD,Sel ' Объявляем переменные
'Создаем объект--приложение Microsoft Word
Set WA=WScript.CreateObject("Word.Application")
' Можно было использовать конструкцию
' Set WA=CreateObject("Word.Application")
Set WD=WA.Documents.Add 'Создаем новый документ (объект Document)
WA.Visible=true ' Делаем Word видимым
Set Sel=WA.Selection 'Создаем объект Selection
Sel.Font.Size=14 'Устанавливаем размер шрифта
Sel.ParagraphFormat.Alignment=1 'Выравнивание по центру
Sel.Font.Bold=true 'Устанавливаем полужирный шрифт
Sel.TypeText "Привет!" & vbCrLf 'Печатаем строку текста
Sel.Font.Bold=false 'Отменяем полужирный шрифт
Sel.ParagraphFormat.Alignment=0 'Выравнивание по левому краю
'Печатаем строку текста
Sel.TypeText "Эти строки напечатаны с помощью WSH."
WD.PrintOut 'Выводим документ на принтер
'************* Конец *********************************************
Внешние программы и команды можно запускать из сценариев различными способами.
Запустить из сценария 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+")");
}
/*******************************************************************/
/* Имя: ExecWinApp.js */
/* Язык: JScript */
/* Описание: Запуск и закрытие приложения (объект WshScriptExec) */
/*******************************************************************/
var WshShell,theNotepad,Res,Text,Title; //Объявляем переменные
//Инициализируем константы для диалоговых окон
var vbYesNo=4,vbQuestion=32,vbYes=6,vbNo=7;
//Создаем объект WshShell
WshShell = WScript.CreateObject("WScript.Shell");
WScript.Echo("Запускаем Блокнот");
//Запускаем приложение (создаем объект WshScriptExec)
theNotepad = WshShell.Exec("notepad");
WScript.Sleep(1000); //Приостанавливаем выполнение сценария
Text="Блокнот запущен (Status="+theNotepad.Status+")\nЗакрыть Блокнот?";
Title="";
//Выводим диалоговое окно на экран
Res=WshShell.Popup(Text,0,Title,vbQuestion+vbYesNo);
//Определяем, какая кнопка нажата в диалоговом окне
if (Res==vbYes) {
theNotepad.Terminate(); //Прерываем работу Блокнота
//Приостанавливаем выполнение сценария для того, чтобы Блокнот
//успел закрыться
WScript.Sleep(100);
WScript.Echo("Блокнот закрыт (Status="+theNotepad.Status+")");
}
/************* Конец *********************************************/
Тот же самый пример на языке VBScript приведен в листинге 2.29.
'*******************************************************************
' Имя: ExecWinApp.vbs
' Язык: VBScript
' Описание: Запуск и закрытие приложение (объект WshScriptExec)
'*******************************************************************
Option Explicit
Dim WshShell,theNotepad,Res,Text,Title ' Объявляем переменные
' Создаем объект WshShell
Set WshShell = WScript.CreateObject("WScript.Shell")
WScript.Echo "Запускаем Блокнот"
' Запускаем приложение (создаем объект WshScriptExec)
Set theNotepad = WshShell.Exec("notepad")
WScript.Sleep 500 ' Приостанавливаем выполнение сценария
Text="Блокнот запущен (Status=" & theNotepad.Status & ")" & vbCrLf _
& "Закрыть Блокнот?"
Title=""
' Выводим диалоговое окно на экран
Res=WshShell.Popup(Text,0,Title,vbQuestion+vbYesNo)
' Определяем, какая кнопка нажата в диалоговом окне
If Res=vbYes Then
theNotepad.Terminate ' Прерываем работу Блокнота
' Приостанавливаем выполнение сценария для того, чтобы Блокнот
' успел закрыться
WScript.Sleep 100
WScript.Echo "Блокнот закрыт (Status=" & theNotepad.Status & ")"
End If
'************* Конец *********************************************/
Производить переключение между окнами нескольких запущенных приложений позволяет метод
AppActivate
объекта WshScript
. В качестве аргумента этого метода нужно указывать либо заголовок активизируемого окна, либо программный идентификатор (PID) процесса, который запущен в этом окне. Предпочтительным является использование PID, который можно получить с помощью свойства ProcessID
объекта WshScriptExec
, соответствующего активизируемому приложению. Недостатки применения в методе AppActivate
заголовка окна:
□ при написании сценария необходимо знать точное название заголовка;
□ само приложение может изменить текст в заголовке окна;
□ в случае нескольких окон с одинаковыми заголовками
AppActivate
всегда будет активизировать один и тот же экземпляр, доступ к другим окнам получить не удастся.
Активизировав то или иное окно, в котором выполняется приложение Windows, можно из сценария сымитировать нажатия клавиш в этом окне. Для этого используется метод
SendKeys
объекта WshShell
(подробное описание этого метода приведено в главе 1).
Для нормальной работы метода
SendKeys
необходимо, чтобы языком по умолчанию в операционной системе был назначен английский язык.
Рассмотрим пример сценария Run&ExecWinApp.js (листинг 2.30), в котором запускается Калькулятор (calc.exe), и в его окно с помощью
SendKeys
последовательно посылаются нажатия клавиш <1>, <+>, <2> и theCalculator = WshShell.Exec("calc");
WScript.Sleep(1000);
WshShell.AppActivate(theCalculator.ProcessID);
WshShell.SendKeys("1{+}");
WshShell.SendKeys("2");
WshShell.SendKeys("~"); //Клавиша
Затем выполнение сценария приостанавливается на 1 секунду, чтобы результат вычислений был виден на экране:
WScript.Sleep(1000);
после чего результат вычислений (символ "3") копируется в буфер с помощью "нажатия" клавиш
WshShell.SendKeys ("^c");
После этого на экран выводится сообщение о том, что Калькулятор будет закрыт:
WScript.Echo("Закрываем калькулятор");
в результате чего окно Калькулятора теряет фокус. Для того чтобы вновь активизировать это окно, используется метод AppActivate, параметром которого служит PID Калькулятора:
WshShell.AppActivate(theCalculator.ProcessID);
Для того чтобы закрыть окно Калькулятора, в него посылаются нажатия клавиш
WshShell.SendKeys("%{F4}");
После закрытия Калькулятора запускается Блокнот (notepad.exe) и в него записываются результаты работы Калькулятора (вставка из буфера вычисленной суммы производится с помощью нажатий
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
/*******************************************************************/
/* Имя: Run&ExecWinApp.js */
/* Язык: JScript */
/* Описание: Запуск двух приложений и обмен данными между ними */
/*******************************************************************/
var WshShell, theCalculator; //Объявляем переменные
//Создаем объект WshShell
WshShell = WScript.CreateObject("WScript.Shell");
WScript.Echo("Запускаем калькулятор и\n считаем 1+2");
//Создаем объект WshScript (запускаем Калькулятор)
theCalculator = WshShell.Exec("calc");
//Приостанавливаем выполнение сценария, для того, чтобы
//окно Калькулятора успело появиться на экране
WScript.Sleep(1000);
//Активизируем окно Калькулятора
WshShell.AppActivate(theCalculator.ProcessID);
//Посылаем нажатия клавиш в окно Калькулятора
WshShell.SendKeys("1{+}");
WshShell.SendKeys("2");
WshShell.SendKeys("~"); //Клавиша
WScript.Sleep(1000);
//Копируем результат вычисления в буфер Windows (+C)
WshShell.SendKeys("^c");
//Выводим сообщение (активное окно меняется)
WScript.Echo("Закрываем калькулятор");
//Активизируем окно Калькулятора
WshShell.AppActivate(theCalculator.ProcessID);
//Закрываем окно Калькулятора (+)
WshShell.SendKeys("%{F4}");
WScript.Echo("Запускаем Блокнот и копируем туда результат");
WshShell.Run("notepad"); //Запускаем Блокнот
//Приостанавливаем выполнение сценария, для того, чтобы
//окно Блокнота успело появиться на экране
WScript.Sleep(1000);
WshShell.AppActivate("notepad"); //Активизируем окно Блокнота
//Посылаем нажатия клавиш в окно Блокнота
WshShell.SendKeys("1{+}2=");
//Вставляем содержимое буфера Windows (+V)
WshShell.SendKeys("^v");
//Выводим в окно Блокнота оставшуюся информацию
WshShell.SendKeys(" {(}c{)} Calculator");
/************* Конец *********************************************/
Тот же пример, реализованный в виде VBScript-сценария, приведен в листинге 2.31.
'*******************************************************************
' Имя: Run&ExecWinApp.vbs
' Язык: VBScript
' Описание: Запуск двух приложений и обмен данными между ними
'*******************************************************************
Option Explicit
Dim WshShell, theCalculator ' Объявляем переменные
' Создаем объект WshShell
Set WshShell = WScript.CreateObject("WScript.Shell")
WScript.Echo("Запускаем калькулятор и" & vbCrLf & "считаем 1+2")
' Создаем объект WshScript (запускаем Калькулятор)
Set theCalculator = WshShell.Exec("calc")
' Приостанавливаем выполнение сценария, для того, чтобы
' окно Калькулятора успело появиться на экране
WScript.Sleep 500
' Активизируем окно Калькулятора
WshShell.AppActivate theCalculator.ProcessID
' Посылаем нажатия клавиш в окно Калькулятора
WshShell.SendKeys "1{+}"
WshShell.SendKeys "2"
WshShell.SendKeys "~" ' Клавиша
WScript.Sleep 500
' Копируем результат вычисления в буфер Windows (+C)
WshShell.SendKeys "^c"
' Выводим сообщение (активное окно меняется)
WScript.Echo "Закрываем калькулятор"
' Активизируем окно Калькулятора
WshShell.AppActivate theCalculator.ProcessID
' Закрываем окно Калькулятора (+)
WshShell.SendKeys "%{F4}"
WScript.Echo "Запускаем Блокнот и копируем туда результат"
WshShell.Run "notepad" ' Запускаем Блокнот
' Приостанавливаем выполнение сценария, для того, чтобы
' окно Блокнота успело появиться на экране
WScript.Sleep 1000
WshShell.AppActivate "notepad" ' Активизируем окно Блокнота
' Посылаем нажатия клавиш в окно Блокнота
WshShell.SendKeys "1{+}2="
' Вставляем содержимое буфера Windows (+V)
WshShell.SendKeys "^v"
' Выводим в окно Блокнота оставшуюся информацию
WshShell.SendKeys " {(}c{)} Calculator"
'************* Конец *********************************************
Для запуска независимых, т.е. работающих в отдельном адресном пространстве и использующих свою копию переменных среды, консольных приложений или внешних (представленных исполняемыми файлами на жестком диске) команд DOS используется метод
Run
объекта WshShell
. При этом выполнение сценария можно приостановить до окончания работы запущенного приложения, а затем проанализировать код выхода этого приложения (для этого третий параметр метода Run
должен равняться true
). Соответствующие примеры сценариев на языках JScript и VBScript приведены в листингах 2.32 и 2.33 соответственно.
/*******************************************************************/
/* Имя: RunConApp.js */
/* Язык: JScript */
/* Описание: Запуск независимого консольного приложения и */
/* определение его кода выхода */
/*******************************************************************/
var WshShell, Code; //Объявляем переменные
//Создаем объект WshShell
WshShell = WScript.CreateObject("WScript.Shell");
//Запускаем утилиту xcopy с ключом "/?" и ожидаем окончания ее работы
Code=WshShell.Run("xcopy /?",1,true);
//Печатаем полученный код возврата
WScript.Echo("Код возврата: ", Code);
/************* Конец *********************************************/
'*******************************************************************
' Имя: RunConApp.vbs
' Язык: VBScript
' Описание: Запуск независимого консольного приложения и
' определение его кода выхода
'*******************************************************************
Option Explicit
Dim WshShell, Code ' Объявляем переменные
' Создаем объект WshShell
Set WshShell = WScript.CreateObject("WScript.Shell")
' Запускаем утилиту xcopy с ключом "/?" и ожидаем окончания ее работы
Code=WshShell.Run("xcopy /?",1,true)
' Печатаем полученный код возврата
WScript.Echo "Код возврата: ", Code
'************* Конец *********************************************/
Для выполнения внутренней команды 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, после чего командное окно закрывается, т.к. для командного интерпретатора в этом случае был указан ключ /с
.
/*******************************************************************/
/* Имя: RunDOSCom.js */
/* Язык: JScript */
/* Описание: Выполнение внутренних команд DOS */
/*******************************************************************/
var WshShell, Code; //Объявляем переменные
//Создаем объект WshShell
WshShell = WScript.CreateObject("WScript.Shell");
//Запускаем внутреннюю команду COPY
WshShell.Run("%COMSPEC% /k copy /?",1);
//Запускаем внутреннюю команду DIR
WshShell.Run("%COMSPEC% /c dir %WINDIR% > windir.txt",1);
/************* Конец *********************************************/
'*******************************************************************
' Имя: 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, при которой данные выходного потока одной команды поступают во входной поток другой команды, например
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).
/*******************************************************************/
/* Имя: ExecConApp.js */
/* Язык: JScript */
/* Описание: Запуск дочернего консольного приложения */
/*******************************************************************/
//Объявляем переменные
var ObjExec,WshShell,s,IsBreak,ArrS,ColStr,ColFiles,i;
//Создаем объект WshShell
WshShell = WScript.CreateObject("WScript.Shell");
//Запускаем команду DIR
ObjExec=WshShell.Exec("%COMSPEC% /c dir /b");
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 сек
}
ArrS=s.split("\n"); //Формируем массив строк
ColFiles=ArrS.length-1; // Количество файлов в текущем каталоге
WScript.StdOut.WriteLine("Всего файлов в текущем каталоге: "+ColFiles);
for (i=0;i<=ColFiles-1;i++)
WScript.StdOut.WriteLine(ArrS[i]); //Выводим строки на экран
/************* Конец *********************************************/
Аналогичный сценарий на языке VBScript приведен в листинге 2.37.
'*******************************************************************
' Имя: ExecConApp.vbs
' Язык: VbScript
' Описание: Запуск дочернего консольного приложения
'*******************************************************************
Option Explicit
' Объявляем переменные
Dim ObjExec,WshShell,s,IsBreak,ArrS,ColStr,ColFiles,i
' Создаем объект WshShell
Set WshShell = WScript.CreateObject("WScript.Shell")
' Запускаем команду DIR
Set ObjExec=WshShell.Exec("%COMSPEC% /c dir /b")
s=""
IsBreak=False
Do While True ' Бесконечный цикл
' Проверяем, достигнут ли конец выходного потока команды DIR
If (Not ObjExec.StdOut.AtEndOfStream) Then
' Считываем полностью выходной поток команды DIR
s=s+ObjExec.StdOut.ReadAll
End If
If IsBreak Then
Exit Do ' Выходим из цикла
End If
' Проверяем, не завершилось ли выполнение DIR
If ObjExec.Status=1 Then
IsBreak=True
Else
WScript.Sleep 100 ' Приостанавливаем сценарий на 0,1 сек
End If
Loop
ArrS=Split(s,vbCrLf) ' Формируем массив строк
ColFiles=UBound(ArrS) ' Количество файлов в текущем каталоге
WScript.StdOut.WriteLine "Всего файлов в текущем каталоге: " & ColFiles
For i=0 To ColFiles-1
WScript.StdOut.WriteLine ArrS(i) ' Выводим строки на экран
Next
'************* Конец *********************************************
При установке Windows всегда автоматически создаются несколько специальных папок (например, папка для рабочего стола (Desktop) или папка для меню Пуск (Start)), путь к которым впоследствии может быть тем или иным способом изменен. С помощью свойства
SpecialFolders
объекта WshShell
можно создать объект WshSpecialFolders
, который является коллекцией, содержащей пути ко всем специальным папкам, имеющимся в системе (список названий этих папок приведен в главе 1 при описании объекта WshSpecialFolders
).
В листингах 2.38 и 2.39 приводятся сценарии на языках JScript и VBScript соответственно, которые формируют список всех имеющихся в системе специальных папок (рис. 2.15).
Рис. 2.15. Пути для всех специальных папок в Windows ХР
/******************************************************************/
/* Имя: SpecFold1.js */
/* Язык: JScript */
/* Описание: Вывод названий всех специальных папок Windows */
/******************************************************************/
var WshShell, WshFldrs, i, s; //Объявляем переменные
//Создаем объект WshShell
WshShell = WScript.CreateObject("Wscript.Shell");
//Создаем объект WshSpecialFolders
WshFldrs = WshShell.SpecialFolders;
s="Список всех специальных папок:\n\n";
//Перебираем все элементы коллекции WshFldrs
for (i=0;i<= WshFldrs.Count()-1;i++) {
//Формируем строки с путями к специальным папкам
s+=WshFldrs(i)+"\n";
}
WScript.Echo(s);
/************* Конец *********************************************/
'*****************************************************************
' Имя: SpecFold1.vbs
' Язык: VBScript
' Описание: Вывод названий всех специальных папок Windows
'*****************************************************************
Option Explicit
Dim WshShell, WshFldrs, SpecFldr, s ' Объявляем переменные
' Создаем объект WshShell
Set WshShell = WScript.CreateObject("Wscript.Shell")
' Создаем объект WshSpecialFolders
Set WshFldrs = WshShell.SpecialFolders
s="Список всех специальных папок:" & vbCrLf & vbCrLf
' Перебираем все элементы коллекции WshFldrs
For Each SpecFldr In WshFldrs
' Формируем строки с путями к специальным папкам
s=s & SpecFldr & vbCrLf
Next
WScript.Echo s
'************* Конец *********************************************/
Объект
WshSpecialFolders
также позволяет получить путь к конкретно заданной специальной папке. Например, в сценарии SpecFold2.js (листинг 2.40) на экран выводятся пути к папкам рабочего стола (Desktop), избранных ссылок (Favorites) и раздела Программы (Programs) меню Пуск (Run) — рис. 2.16.
Рис. 2.16. Пути для некоторых специальных папок
/******************************************************************/
/* Имя: SpecFold2.js */
/* Язык: JScript */
/* Описание: Вывод названий заданных специальных папок Windows */
/******************************************************************/
var WshShell, WshFldrs, s; //Объявляем переменные
//Создаем объект WshShell
WshShell = WScript.CreateObject("Wscript.Shell");
//Создаем объект WshSpecialFolders
WshFldrs = WshShell.SpecialFolders;
//Формируем строки с путями к конкретным специальным папкам
s="Некоторые специальные папки:\n\n";
s+="Desktop:\t"+WshFldrs("Desktop")+"\n";
s+="Favorites:\t"+WshFldrs("Favorites")+"\n";
s+="Programs:\t"+WshFldrs("Programs");
WScript.Echo(s); //Выводим сформированные строки на экран
/************* Конец *********************************************/
Реализация того же сценария на языке VBScript приведена в листинге 2.41.
'******************************************************************
' Имя: SpecFold2.vbs
' Язык: VBScript
' Описание: Вывод названий заданных специальных папок Windows
'******************************************************************
Option Explicit
Dim WshShell, WshFldrs, s ' Объявляем переменные
' Создаем объект WshShell
Set WshShell = WScript.CreateObject("Wscript.Shell")
' Создаем объект WshSpecialFolders
Set WshFldrs = WshShell.SpecialFolders
' Формируем строки с путями к конкретным специальным папкам
s="Некоторые специальные папки:" & vbCrLf & vbCrLf
s=s+"Desktop:"+WshFldrs("Desktop") & vbCrLf
s=s+"Favorites:"+WshFldrs("Favorites") & vbCrLf
s=s+"Programs:"+WshFldrs("Programs")
WScript.Echo s ' Выводим сформированные строки на экран
'************* Конец *********************************************/
Для того чтобы из сценария создать ярлык в специальной папке (рабочий стол, меню Пуск (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), назначается комбинация горячих клавиш
/*****************************************************************/
/* Имя: Shortcut.js */
/* Язык: JScript */
/* Описание: Создание ярлыков в специальных папках */
/*****************************************************************/
//Объявляем переменные
var WshShell,MyShortcut,PathTarg,PathIcon,Res,PathShortcut;
//Инициализируем константы для диалоговых окон
var vbYesNo=4,vbQuestion=32,vbYes=6;
//Создаем объект WshShell
WshShell = WScript.CreateObject("WScript.Shell");
//Выводим запрос для выбора папки, в которой будет создан ярлык
Res=WshShell.Popup("Где создать ярлык?\nДа - на рабочем столе\nНет - в меню Программы",0,
"Работа с ярлыками",vbQuestion+vbYesNo);
if (Res==vbYes) //Нажата кнопка Да
//Определяем путь к рабочему столу
PathShortcut = WshShell.SpecialFolders("Desktop");
else
//Определяем путь к меню Программы
PathShortcut = WshShell.SpecialFolders("Programs");
//Создаем объект-ярлык
MyShortcut = WshShell.CreateShortcut(PathShortcut+"\\Мой ярлык.lnk");
//Устанавливаем путь к файлу
PathTarg=WshShell.ExpandEnvironmentStrings("%windir%\\notepad.exe");
MyShortcut.TargetPath = PathTarg;
//Назначаем комбинацию горячих клавиш
MyShortcut.Hotkey = "CTRL+ALT+N";
//Выбираем иконку из файла SHELL32.dll
PathIcon=
WshShell.ExpandEnvironmentStrings("%windir%\\system32\\SHELL32.dll");
MyShortcut.IconLocation = PathIcon+", 1";
MyShortcut.WindowStyle=3; //Устанавливаем тип окна (максимизировано)
MyShortcut.Save(); //Сохраняем ярлык
WScript.Echo("Ярлык создан|");
/************* Конец *********************************************/
Реализация того же сценария на языке VBScript приведена в листинге 2.43.
Листинг 2.43. Доступ к определенным специальным папкам (VBScript)
'*****************************************************************
' Имя: Shortcut.vbs
' Язык: JScript
' Описание: Создание ярлыков в специальных папках
'*****************************************************************
Option Explicit
' Объявляем переменные
Dim WshShell,MyShortcut,PathTarg,PathIcon,Res,PathShortcut
' Создаем объект WshShell
Set WshShell = WScript.CreateObject("WScript.Shell")
' Выводим запрос для выбора папки, в которой будет создан ярлык
Res=WshShell.Popup("Где создать ярлык?" & vbCrLf & "Да - на рабочем столе" & vbCrLf & _
"Нет - в меню Программы",0,"Работа с ярлыками",vbQuestion+vbYesNo)
If Res=vbYes Then ' Нажата кнопка Да
' Определяем путь к рабочему столу
PathShortcut = WshShell.SpecialFolders("Desktop")
Else
' Определяем путь к меню Программы
PathShortcut = WshShell.SpecialFolders("Programs")
End If
' Создаем объект-ярлык
Set MyShortcut = WshShell.CreateShortcut(PathShortcut+"\Мой ярлык.lnk")
' Устанавливаем путь к файлу
PathTarg=WshShell.ExpandEnvironmentStrings("%windir%\\notepad.exe")
MyShortcut.TargetPath = PathTarg
' Назначаем комбинацию горячих клавиш
MyShortcut.Hotkey = "CTRL+ALT+N"
' Выбираем иконку из файла SHELL32.dll
PathIcon = _
WshShell.ExpandEnvironmentStrings("%windir%\system32\SHELL32.dll")
MyShortcut.IconLocation = PathIcon & ", 1"
MyShortcut.WindowStyle=3 ' Устанавливаем тип окна (максимизировано)
MyShortcut.Save ' Сохраняем ярлык
WScript.Echo "Ярлык создан|"
'************* Конец *********************************************
Во всех версиях 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
последовательно удаляются из реестра.
/********************************************************************/
/* Имя: Registry.js */
/* Язык: JScript */
/* Описание: Работа с системным реестром */
/********************************************************************/
//Объявляем переменные
var WshShell,Root,Key,Res,SValue,ValueName,SRegValue;
//Инициализируем константы для диалоговых окон
var vbYesNo=4,vbQuestion=32,vbInformation=64,vbYes=6,vbOkOnly=0;
Root="HKEY_CURRENT_USER"; //Корневой ключ
Key="\\ExampleKey\\"; //Новый ключ
ValueName="ExampleValue"; //Имя нового параметра
SValue="Value from WSH"; //Значение нового параметра
//Создаем объект WshShell
WshShell=WScript.CreateObject("WScript.Shell");
//Запрос на создание нового ключа
Res=WshShell.Popup("Создать ключ\n"+Root+Key+"?",0,
"Работа с реестром",vbQuestion+vbYesNo);
if (Res==vbYes) { //Нажата кнопка Да
//Записываем новый ключ
WshShell.RegWrite(Root+Key,"");
WshShell.Popup("Ключ\n"+Root+Key+" создан!",0,
"Работа с реестром",vbInformation+vbOkOnly);
}
//Запрос на запись нового параметра
Res=WshShell.Popup("Записать параметр\n"+Root+Key+ValueName+"?",0,
"Работа с реестром",vbQuestion+vbYesNo);
if (Res==vbYes) { //Нажата кнопка Да
//Записываем новый строковый параметр
WshShell.RegWrite(Root+Key+ValueName,SValue,"REG_SZ");
WshShell.Popup("Параметр\n"+Root+Key+ValueName+" записан!",0,
"Работа с реестром",vbInformation+vbOkOnly);
//Считываем значение созданного параметра
SRegValue=WshShell.RegRead(Root+Key+ValueName);
//Выводим на экран полученное значение
WshShell.Popup(Root+Key+ValueName+"="+SRegValue,0,
"Работа с реестром",vbInformation+vbOkOnly);
}
//Запрос на удаление параметра
Res=WshShell.Popup("Удалить параметр\n"+Root+Key+ValueName+"?",0,
"Работа с реестром",vbQuestion+vbYesNo);
if (Res==vbYes) { //Нажата кнопка Да
//Удаляем параметр
WshShell.RegDelete(Root+Key+ValueName);
WshShell.Popup("Параметр\n"+Root+Key+ValueName+" удален!",0,
"Работа с реестром",vbInformation+vbOkOnly);
}
//Запрос на удаление раздела
Res=WshShell.Popup("Удалить раздел\n"+Root+Key+"?",0,
"Работа с реестром",vbQuestion+vbYesNo);
if (Res==vbYes) { //Нажата кнопка Да
//Удаляем раздел
WshShell.RegDelete(Root+Key);
WshShell.Popup("Раздел\n"+Root+Key+" удален!",0,
"Работа с реестром",vbInformation+vbOkOnly);
}
/************* Конец *********************************************/
Реализация того же сценария на языке VBScript приведена в листинге 2.45.
'********************************************************************
' Имя: Registry.vbs
' Язык: VBScript
' Описание: Работа с системным реестром
'********************************************************************
Option Explicit
'Объявляем переменные
Dim WshShell,Root,Key,Res,SValue,ValueName,SRegValue
Root="HKEY_CURRENT_USER" 'Корневой ключ
Key="\ExampleKey\" 'Новый ключ
ValueName="ExampleValue" 'Имя нового параметра
SValue="Value from WSH" 'Значение нового параметра
'Создаем объект WshShell
Set WshShell=WScript.CreateObject("WScript.Shell")
'Запрос на создание нового ключа
Res=WshShell.Popup("Создать ключ" & vbCrLf & Root & Key & "?",0,_
"Работа с реестром",vbQuestion+vbYesNo)
If Res=vbYes Then 'Нажата кнопка Да
'Записываем новый ключ
WshShell.RegWrite Root & Key, ""
WshShell.Popup "Ключ" & vbCrLf & Root & Key & " создан!",0,_
"Работа с реестром",vbInformation+vbOkOnly
End If
'Запрос на запись нового параметра
Res=WshShell.Popup("Записать параметр" & vbCrLf & Root & Key & _
ValueName & "?",0,"Работа с реестром",vbQuestion+vbYesNo)
If Res=vbYes Then 'Нажата кнопка Да
'Записываем новый строковый параметр
WshShell.RegWrite Root & Key & ValueName,SValue,"REG_SZ"
WshShell.Popup "Параметр" & vbCrLf & Root & Key & _
ValueName & " записан!",0,"Работа с реестром",vbInformation+vbOkOnly
'Считываем значение созданного параметра
SRegValue=WshShell.RegRead(Root & Key & ValueName)
'Выводим на экран полученное значение
WshShell.Popup Root & Key & ValueName & "=" & SRegValue,0,_
"Работа с реестром",vbInformation+vbOkOnly
End If
'Запрос на удаление параметра
Res=WshShell.Popup("Удалить параметр" & vbCrLf & Root & Key & _
ValueName & "?",0,"Работа с реестром",vbQuestion+vbYesNo)
If Res=vbYes Then 'Нажата кнопка Да
'Удаляем параметр
WshShell.RegDelete Root & Key & ValueName
WshShell.Popup "Параметр" & vbCrLf & Root & Key & _
ValueName & " удален!",0,"Работа с реестром",vbInformation+vbOkOnly
End If
'Запрос на удаление раздела
Res=WshShell.Popup("Удалить раздел" & vbCrLf & Root & Key & _
"?",0,"Работа с реестром",vbQuestion+vbYesNo)
If Res=vbYes Then 'Нажата кнопка Да
'Удаляем раздел
WshShell.RegDelete Root & Key
WshShell.Popup "Раздел" & vbCrLf & Root & Key & " удален!",0,_
"Работа с реестром",vbInformation+vbOkOnly
End If
'************* Конец *********************************************
Стандартным объектом, позволяющим выполнять типовые операции с локальной сетью, является
WshNetwork
. С помощью этого объекта можно:
□ узнать сетевое имя компьютера, имя текущего пользователя и название домена, в котором он зарегистрировался;
□ получить список всех сетевых дисков и всех сетевых принтеров, подключенных к рабочей станции;
□ подключить или отключить сетевой диск и принтер;
□ установить сетевой принтер в качестве принтера, используемого по умолчанию.
Для решения более сложных задач, связанных с администрированием локальной сети, можно применять имеющиеся в Windows ХР технологии ADSI — Active Directory Service Interface и WMI — Windows Management Instrumentation.
Для того чтобы из сценария узнать имя текущего пользователя, домена и компьютера в сети, можно использовать соответствующие свойства объекта
WshNetwork
: UserName
, Domain
и ComputerName
. Примеры сценариев на языках JScript и VBScript, которые выводят на экран такую информацию, приведены в листингах 2.46 и 2.47.
/********************************************************************/
/* Имя: NetworkParam.js */
/* Язык: JScript */
/* Описание: Вывод сетевых параметров станции */
/********************************************************************/
var WshNetwork,s; //Объявляем переменные
//Создаем объект WshNetwork
WshNetwork = WScript.CreateObject("WScript.Network");
s="Сетевые параметры станции:\n\n";
//Выводим на экран свойства ComputerName, UserName и UserDomain
s+="Имя машины: "+WshNetwork.ComputerName+"\n";
s+="Имя пользователя: "+WshNetwork.UserName+"\n";
s+="Домен: "+WshNetwork.UserDomain;
WScript.Echo(s);
/************* Конец *********************************************/
'********************************************************************
' Имя: NetworkParam.vbs
' Язык: VBScript
' Описание: Вывод сетевых параметров станции
'********************************************************************
Option Explicit
Dim WshNetwork,s,NetwDrives,i,NetwPrinters ' Объявляем переменные
' Создаем объект WshNetwork
Set WshNetwork = WScript.CreateObject("WScript.Network")
s="Сетевые параметры станции:" & vbCrLf & vbCrLf
' Выводим на экран свойства ComputerName, UserName и UserDomain
s=s & "Имя машины: " & WshNetwork.ComputerName & vbCrLf
s= s & "Имя пользователя: " & WshNetwork.UserName & vbCrLf
s= s & "Домен: " & WshNetwork.UserDomain
WScript.Echo s
'************* Конец *********************************************
У объекта
WshNetwork
имеются методы EnumNetworkDrives
и EnumPrinterConnections
, с помощью которых можно создать коллекции, содержащие, соответственно, сведения о всех подключенных к локальной станции сетевых дисках и сетевых принтерах. Эти коллекции устроены следующим образом: первым элементом является буква диска или название порта, вторым — сетевое имя ресурса, с которым связан этот диск или принтер. Та же последовательность сохраняется для всех элементов коллекции.
В листингах 2.48 и 2.49 приведены сценарии на языках JScript и VBScript соответственно, в которых на экран выводятся диалоговые окна, содержащие информацию о сетевых дисках и сетевых принтерах, подключенных к рабочей станции (рис. 2.22).
Рис. 2.22. Выводимая сценарием ListNetworkResources.js информация о подключенных сетевых ресурсах
/********************************************************************/
/* Имя: ListNetworkResources.js */
/* Язык: JScript */
/* Описание: Вывод подключенных сетевых ресурсов (диски и принтеры) */
/********************************************************************/
var WshNetwork,s,NetwDrives,i,NetwPrinters; //Объявляем переменные
//Создаем объект WshNetwork
WshNetwork = WScript.CreateObject("WScript.Network");
/***** Вывод списка всех подключенных сетевых дисков ******/
s="Подключенные сетевые диски:\n\n";
//Создаем коллекцию с данными о подключенных дисках
NetwDrives = WshNetwork.EnumNetworkDrives();
i=0;
while (i<=NetwDrives.Count()-2) { //Перебираем элементы коллекции
//В первом элементе коллекции содержится буква диска,
//во втором - сетевое имя ресурса и т.д.
s+=NetwDrives(i)+" "+NetwDrives(i+1)+"\n";
i=i+2;
}
WScript.Echo(s); //Выводим сформированные строки на экран
/****** Вывод списка всех подключенных сетевых принтеров ******/
s="Подключенные сетевые принтеры:\n\n";
//Создаем коллекцию с данными о подключенных принтерах
NetwPrinters = WshNetwork.EnumPrinterConnections();
i=0;
while (i<=NetwPrinters.Count()-2) { //Перебираем элементы коллекции
//В первом элементе коллекции содержится названия локальных портов,
//во втором - сетевое имя принтера и т.д.
s+=NetwPrinters(i)+" "+NetwPrinters(i+1)+"\n";
i=i+2;
}
WScript.Echo(s); //Выводим сформированные строки на экран
/************* Конец *********************************************/
'********************************************************************
' Имя: ListNetworkResources.vbs
' Язык: JScript
' Описание: Вывод подключенных сетевых ресурсов (диски и принтеры)
'********************************************************************
Option Explicit
Dim WshNetwork,s,NetwDrives,i,NetwPrinters ' Объявляем переменные
' Создаем объект WshNetwork
Set WshNetwork = WScript.CreateObject("WScript.Network")
'******** Вывод списка всех подключенных сетевых дисков *********
s="Подключенные сетевые диски:" & vbCrLf & vbCrLf
' Создаем коллекцию с данными о подключенных дисках
Set NetwDrives = WshNetwork.EnumNetworkDrives()
i=0
While i<=NetwDrives.Count()-2 ' Перебираем элементы коллекции
' В первом элементе коллекции содержится буква диска,
' во втором - сетевое имя ресурса и т.д.
s=s & NetwDrives.Item(i) & " " & NetwDrives.Item(i+1) & vbCrLf
i=i+2
Wend
WScript.Echo s ' Выводим сформированные строки на экран
'******** Вывод списка всех подключенных сетевых принтеров *******
s="Подключенные сетевые принтеры:" & vbCrLf & vbCrLf
' Создаем коллекцию с данными о подключенных принтерах
Set NetwPrinters = WshNetwork.EnumPrinterConnections()
i=0
While i<=NetwPrinters.Count()-2 ' Перебираем элементы коллекции
' В первом элементе коллекции содержится названия локальных портов,
' во втором - сетевое имя принтера и т.д.
s=s & NetwPrinters.Item(i) & " " & NetwPrinters.Item(i+1) & vbCrLf
i=i+2
Wend
WScript.Echo s 'Выводим сформированные строки на экран
'************* Конец *********************************************
Имеющиеся в локальной сети общедоступные ресурсы (диски и принтеры) можно посредством сценария подключить к рабочей станции для совместного использования. Подключаемому сетевому диску при этом нужно поставить в соответствие незанятую букву локального диска (например, если в системе уже имеются диски С:, 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
) и обработка ошибок времени выполнения, которые могут возникнуть при этих действиях, производится в сценарии аналогичным образом.
/********************************************************************/
/* Имя: MapResources.js */
/* Язык: JScript */
/* Описание: Отключение и подключение сетевых дисков и принтеров */
/********************************************************************/
//Объявляем переменные
var WshNetwork,WshShell,Drive,NetPath,Port,NetPrinter,Mess,IsError;
//Инициализируем константы для диалоговых окон
var vbCritical=16,vbInformation=64;
Drive="K:"; //Буква диска
//NetPath="\\\\RS_NT_Server\\d"; //Сетевой путь для подключения диска
NetPath="\\\\RS_NT_Server\\d"; //Сетевой путь для подключения диска
Port="LPT1"; //Название локального порта
//Сетевой путь для подключения принтера
NetPrinter="\\\\104_Stepankova\\HP";
//Создаем объект WshNetwork
WshNetwork = WScript.CreateObject("WScript.Network");
//Создаем объект WshShell
WshShell = WScript.CreateObject("WScript.Shell");
/************* Отключение сетевого диска ***********************/
IsError=false;
try {
//Отключаем сетевой диск
WshNetwork.RemoveNetworkDrive(Drive);
} catch (e) { //Обрабатываем возможные ошибки
if (e != 0) {
//Выводим сообщение об ошибке
IsError=true;
Mess="Ошибка при отключении диска "+Drive+"\nКод ошибки: "+
e.number+"\nОписание: "+e.description;
WshShell.Popup(Mess,0,"Отключение сетевого диска",vbCritical);
}
}
if (!IsError) {
//Все в порядке
Mess="Диск "+Drive+" отключен успешно";
WshShell.Popup(Mess,0,"Отключение сетевого диска",vbInformation);
}
/************* Подключение сетевого диска ***********************/
IsError=false;
try {
//Подключаем сетевой диск
WshNetwork.MapNetworkDrive(Drive,NetPath);
} catch (e) { //Обрабатываем возможные ошибки
if (e != 0) {
//Выводим сообщение об ошибке
IsError=true;
Mess="Ошибка при подключении диска " + Drive + " к " + NetPath+
"\nКод ошибки: "+e.number+"\nОписание: "+e.description;
WshShell.Popup(Mess,0,"Подключение сетевого диска",vbCritical);
}
}
if (!IsError) {
//Все в порядке
Mess="Диск "+Drive+" успешно подключен к "+NetPath;
WshShell.Popup(Mess,0,"Подключение сетевого диска",vbInformation);
}
/************* Освобождение локального порта ***********************/
IsError=false;
try {
//Разрываем связь с сетевым принтером
WshNetwork.RemovePrinterConnection(Port);
} catch (e) {
if (e != 0) { //Обрабатываем возможные ошибки
//Выводим сообщение об ошибке
IsError=true;
Mess="Ошибка при отключении порта "+Port+"\nКод ошибки: "+
e.number+"\nОписание: "+e.description;
WshShell.Popup(Mess,0,"Отключение локального порта от сетевого ресурса",vbCritical);
}
}
if (!IsError) {
//Все в порядке
Mess="Порт "+Port+" отключен успешно";
WshShell.Popup(Mess,0,"Отключение локального порта от сетевого ресурса",vbInformation);
}
/***** Подключение локального порта к сетевому принтеру *********/
IsError=false;
try {
//Подключаем сетевой принтер к локальному порту
WshNetwork.AddPrinterConnection(Port,NetPrinter);
} catch (e) { //Обрабатываем возможные ошибки
if (e != 0) {
//Выводим сообщение об ошибке
IsError=true;
Mess="Ошибка при переназначении порта "+Port+ " на "+NetPrinter+
"\nКод ошибки: "+e.number+"\nОписание: "+e.description;
WshShell.Popup(Mess,0,"Подключение локального порта к сетевому ресурсу",vbCritical);
}
}
if (!IsError) {
//Все в порядке
Mess="Порт "+Port+" успешно подключен к "+NetPrinter;
WshShell.Popup(Mess,0,"Подключение локального порта к сетевому ресурсу",vbInformation);
}
/************* Конец *********************************************/
Реализация того же сценария на языке VBScript представлена в листинге 2.51. Главное отличие здесь состоит в способе обработки возможных ошибок времени выполнения. В VBScript для этой цели предназначен оператор
On Error Resume Next
— при возникновении ошибки после выполнения этого оператора сценарий не прервется, а просто перейдет к выполнению следующей строки кода. Проанализировать же возникшую ошибку можно с помощью специального объекта Err
, в полях Number
и Description
которого будут соответственно содержаться код и описание ошибки.
'********************************************************************
' Имя: MapResources.vbs
' Язык: VBScript
' Описание: Отключение и подключение сетевых дисков и принтеров
'********************************************************************
Option Explicit
' Объявляем переменные
Dim WshNetwork,Drive,NetPath,Port,NetPrinter
Drive="K:" ' Буква диска
NetPath="\\RS_NT_Server\d" ' Сетевой путь для подключения диска
Port="LPT1" ' Название локального порта
' Сетевой путь для подключения принтера
NetPrinter="\\104_Stepankova\HP"
' Создаем объект WshNetwork
Set WshNetwork = WScript.CreateObject("WScript.Network")
' Создаем объект WshShell
Set WshShell = WScript.CreateObject("WScript.Shell")
On Error Resume Next ' Включаем обработку ошибок времени выполнения
'************* Отключение сетевого диска ***********************
' Отключаем сетевой диск
WshNetwork.RemoveNetworkDrive Drive
If Err.Number<>0 Then
Mess="Ошибка при отключении диска " & Drive & vbCrLf & _
"Код ошибки: " & e.number & vbCrLf &+ _
"Описание: " & e.description
WshShell.Popup Mess,0,"Отключение сетевого диска",vbCritical
Else
' Все в порядке
Mess="Диск " & Drive & " отключен успешно"
WshShell.Popup Mess,0,"Отключение сетевого диска",vbInformation
End If
'************* Подключение сетевого диска ***********************
' Подключаем сетевой диск
WshNetwork.MapNetworkDrive Drive,NetPath
If Err.Number<>0 Then
Mess="Ошибка при подключении диска " & Drive & " к " & NetPath &_
"Код ошибки: " & e.number & "Описание: " & e.description
WshShell.Popup Mess,0,"Подключение сетевого диска",vbCritical
Else
' Все в порядке
Mess="Диск " & Drive & " успешно подключен к " & NetPath
WshShell.Popup Mess,0,"Подключение сетевого диска",vbInformation
End If
'************* Освобождение локального порта ***********************
' Разрываем связь с сетевым принтером
WshNetwork.RemovePrinterConnection Port
If Err.Number<>0 Then
Mess="Ошибка при отключении порта " & Port & "Код ошибки: " &_
e.number & "Описание: " & e.description
WshShell.Popup Mess,0,"Отключение порта от сетевого ресурса",vbCritical
Else
' Все в порядке
Mess="Порт " & Port & " отключен успешно"
WshShell.Popup Mess,0,"Отключение порта от сетевого ресурса",_
vbInformation
End If
'***** Подключение локального порта к сетевому принтеру *********
' Подключаем сетевой принтер к локальному порту
WshNetwork.AddPrinterConnection Port,NetPrinter
If Err.Number<>0 Then
Mess="Ошибка при переназначении порта " & Port & " на " & NetPrinter &_
"Код ошибки: " & e.number & "Описание: " & e.description
WshShell.Popup Mess,0,"Подключение порта к сетевому ресурсу",vbCritical
Else
' Все в порядке
Mess="Порт " & Port & " успешно подключен к " & NetPrinter
WshShell.Popup Mess,0,"Подключение порта к сетевому ресурсу",
vbInformation
End If
'************* Конец *********************************************
Начиная с версии 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.
/*****************************************************************/
/* Имя: RemoteShortcut.js */
/* Описание: Создание ярлыка на рабочем столе */
/*****************************************************************/
var WshShell,MyShortcut,PathTarg,PathShortcut;
//Создаем объект WshShell
WshShell = WScript.CreateObject("WScript.Shell");
//Определяем путь к папке "AllUsersDesktop" (рабочий стол
//всех пользователей)
PathShortcut = WshShell.SpecialFolders("AllUsersDesktop");
//Создаем объект-ярлык
MyShortcut = WshShell.CreateShortcut(PathShortcut+ "\\From Remote WSH.lnk");
//Устанавливаем путь к файлу
PathTarg=WshShell.ExpandEnvironmentStrings("%windir%\\notepad.exe");
MyShortcut.TargetPath = PathTarg;
MyShortcut.Save(); //Сохраняем ярлык
/************* Конец *********************************************/
Для запуска сценария 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).
/********************************************************************/
/* Имя: RunRemoteScript.js */
/* Язык: JScript */
/* Описание: Запуск удаленного сценария */
/********************************************************************/
var Controller, RemScript; //Объявляем переменные
//Создаем объект WshController
Controller = WScript.CreateObject("WshController");
//Создаем сценарий на удаленной машине (объект WshRemote)
RemScript = Controller.CreateScript("D:\\RemoteScript.js", "stand");
RemScript.Execute(); //Запускаем удаленный сценарий
WScript.Echo("Удаленный сценарий запущен");
while (RemScript.Status != 2)
//Цикл выполняется до завершения удаленного сценария
WScript.Sleep(100); //Приостанавливаем сценарий на 0,1 сек
WScript.Echo("Выполнение удаленного сценария завершено");
/************* Конец *********************************************/
В листинге 2.54 приведен аналог сценария RunRemoteScript.js на языке VBScript.
'********************************************************************
' Имя: RunRemoteScript.vbs
' Язык: VBScript
' Описание: Запуск удаленного сценария
'********************************************************************
Option Explicit
Dim Controller, RemScript ' Объявляем переменные
' Создаем объект WshController
Set Controller = WScript.CreateObject("WshController")
' Создаем сценарий на удаленной машине (объект WshRemote)
Set RemScript = Controller.CreateScript("D:\\RemoteScript.js", "stand")
RemScript.Execute ' Запускаем удаленный сценарий
WScript.Echo "Удаленный сценарий запущен"
While RemScript.Status <> 2
' Цикл выполняется до завершения удаленного сценария
WScript.Sleep 100 ' Приостанавливаем сценарий на 0,1 сек
Wend
WScript.Echo "Выполнение удаленного сценария завершено"
'************* Конец *********************************************
Контролировать ход выполнения удаленных сценариев можно не только путем анализа свойства
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
, управление в которые будет передаваться при наступлении соответствующих событий.
WshRemote
(JScript)/**********************************************************************/
/* Имя: RemoteEvents.js */
/* Язык: JScript */
/* Описание: Обработка событий, возникающих при выполнении удаленного */
/* сценария */
/**********************************************************************/
var Controller,RemScript,IsQuit; //Объявляем переменные
//Создаем объект WshController
Controller = WScript.CreateObject("WshController");
//Создаем сценарий на удаленной машине (объект WshRemote)
RemScript = Controller.CreateScript("D:\\RemoteScript.js ", "stand");
//Устанавливаем соединение с объектом WshRemote
WScript.ConnectObject(RemScript, "RemoteScript_");
RemScript.Execute(); //Запускаем удаленный сценарий
IsQuit = false;
while (!IsQuit) WScript.Sleep(100); //Приостанавливаем сценарий на 0,1 сек
WScript.Quit(); //Выходим из сценария
/*************** Функции-обработчики событий ***********************/
function RemoteScript_End() { //Событие End
WScript.Echo("Выполнение удаленного сценария завершено");
IsQuit = true;
}
function RemoteScript_Error() { //Событие Error
//Выводим на экран описание возникшей ошибки
WScript.Echo("Ошибка при выполнении удаленного сценария: " +
RemScript.Error.Description);
IsQuit = true;
}
function RemoteScript_Start() { //Событие Start
WScript.Echo("Удаленный сценарий запущен");
}
/************* Конец *********************************************/
'********************************************************************
' Имя: RemoteEvents.vbs
' Язык: VBScript
' Описание: Обработка событий, возникающих при выполнении удаленного
' сценария
'********************************************************************
Option Explicit
Dim Controller,RemScript,IsQuit ' Объявляем переменные
' Создаем объект WshController
Set Controller = CreateObject("WshController")
' Создаем сценарий на удаленной машине (объект WshRemote)
Set RemScript = Controller.CreateScript("D:\RemoteScript.js ", "stand")
' Устанавливаем соединение с объектом WshRemote
WScript.ConnectObject RemScript, "RemoteScript_"
RemScript.Execute ' Запускаем удаленный сценарий
IsQuit = False
While Not IsQuit
WScript.Sleep 100 ' Приостанавливаем сценарий на 0,1 сек
Wend
WScript.Quit ' Выходим из сценария
'*************** Функции-обработчики событий ***********************
Function RemoteScript_End() ' Событие End
WScript.Echo "Выполнение удаленного сценария завершено"
IsQuit = True
End Function
Function RemoteScript_Error() ' Событие Error
' Выводим на экран описание возникшей ошибки
WScript.Echo "Ошибка при выполнении удаленного сценария: " & _
RemScript.Error.Description
IsQuit = True
End Function
Function RemoteScript_Start() ' Событие Start
WScript.Echo "Удаленный сценарий запущен"
End Function
'************* Конец *********************************************
При контроле за ходом выполнения удаленного сценария с помощью обработки событий объекта
WshRemote
затрачивается больше ресурсов компьютера по сравнению с простой проверкой свойства Status
. Кроме этого, при обработке событий увеличивается сетевой трафик между локальной и удаленной машинами.