Во всех сценариях WSH, которые мы рассматривали ранее, создавались экземпляры внешних СОМ-объектов, являющихся серверами автоматизации, после чего мы не задумываясь использовали свойства и методы этих объектов. В основном СОМ-объекты создаются в виде откомпилированных модулей с помощью универсальных языков типа Visual С++ или Visual Basic, однако с помощью специальной технологии Windows Script Components можно зарегистрировать в системе СОМ-объект, написанный на языке JScript или VBScript, причем для этого не нужно проводить никакой компиляции исходного кода сценария! Таким образом, любой сценарий WSH можно "упаковать" в СОМ-объект (мы будем называть такие объекты компонентами-сценариями или объектами-сценариями) и использовать его в приложениях, написанных на любом языке, который позволяет подключать внешние объекты. Преимуществами компонентов-сценариев над обычными откомпилированными компонентами (как и вообще любой интерпретируемой программы над компилируемой) является простота разработки, внесения изменений и распространения объектов-сценариев, недостатками — более медленная скорость работы и возможность внесения несанкционированных изменений в исходный код компонентов.
В этой главе мы кратко опишем механизм работы объектов-сценариев и внутреннюю структуру файлов с описанием таких объектов. Также будет подробно разобран пример создания, регистрации и использования объекта-сценария, предназначенного для создания архивных копий файлов.
Сразу оговоримся, что мы будем рассматривать только объекты-сценарии, которые являются серверами автоматизации (т.е. предоставляют свои свойства и методы другим приложениям), не затрагивая вопросы разработки специальных объектов для использования внутри HTML- или ASP-страниц (Active Server Pages).
Механизм работы объектов-сценариев базируется на технологии ActiveX Scripting, основную роль здесь играет динамическая библиотека Scrobj.dll, которая является оболочкой компонентов-сценариев и отвечает за функционирование файла-сценария в качестве СОМ-объекта. С точки зрения технологии СОМ эта библиотека для объектов-сценариев действует как внутренний сервер (inprocess server). Другими словами, оболочка компонентов-сценариев Scrobj.dll отвечает за то, чтобы при вызове из внешнего приложения метода объекта-сценария или обращении к его свойству запускалась соответствующая функция, описанная в этом сценарии. Для этого на уровне операционной системы незаметно для самого объекта-сценария и для приложения, в котором создается экземпляр этого объекта, производятся следующие действия.
□ При регистрации объекта-сценария в разделе
HKEY_CLASSES_ROOT\CLSID
системного реестра создается новый подраздел, название которого совпадает с глобальным кодом (CLSID) регистрируемого объекта. В этом новом разделе создается подраздел InprocServer32
, значением по умолчанию которого является полный путь к библиотеке Scrobj.dll. Кроме InprocServer32
, создаются подразделы ProgID
(программный идентификатор объекта) и ScripletURL
(полный путь к файлу объекта-сценария).
□ Если создание экземпляра объекта из внешнего приложения происходит с помощью программного идентификатора (ProgID) объекта, то сначала определяется глобальный код (CLSID) этого объекта. Для этого в разделе реестра
HKEY_LOCAL_MACHINE\SOFTWARE\Classes
ищется подраздел с именем, которое совпадает с программным идентификатором объекта (этот подраздел создается при регистрации объекта-сценария), и в качестве глобального кода берется значение параметра CLSID
из этого подраздела.
□ По известному глобальному коду объекта происходит поиск раздела с нужным названием в
HKEY_CLASSES_ROOT\CLSID
, после чего определяется значение подраздела InprocServer32
(путь к библиотеке Scrobj.dll) и загружается оболочка компонентов-сценариев Scrobj.dll.
□ Библиотека Scrobj.dll загружает указанный в подразделе
ScripletURL
файл со сценарием и перенаправляет вызовы методов объекта в этот сценарий.
Таким образом, нам остается лишь научиться правильным образом создавать файлы с исходным кодом компонентов-сценариев и регистрировать эти файлы в системе в качестве СОМ-объектов.
Компоненты-сценарии, реализованные в технологии Windows Script Components, представляют из себя файлы с расширениями wsc (WSC-файлы), которые содержат специальную XML-разметку (объектная модель WSC XML), к описанию которой мы и перейдем.
Ранее в главе 3 отмечалось, что объектная модель, которая используется при создании многозадачных сценариев (WS-файлов), была в основном позаимствована из схемы WSC XML, поэтому многие элементы WSC-файлов окажутся вам знакомыми.
В листинге 10.1 приводится несколько упрощенная (некоторые необязательные атрибуты у XML-элементов опущены) схема, поясняющая иерархию и порядок появления элементов в WSC-файле.
Сценарии подключения и отключения
Строка или число
Код сценария
]]>
Другие компоненты
Несколько замечаний относительно количества вхождений различных XML-элементов из листинга 10.1 в WSC-файл:
□ элемент
может содержать один или несколько элементов
;
□ элемент
должен содержать один элемент
и один элемент
;
□ элемент
может содержать один или несколько элементов
,
или
.
Обязательными для создания компонента-сценария являются элементы
,
,
и
.
Опишем теперь элементы XML, использующиеся в WSC-файлах, более подробно.
В WSC-файлы можно вставлять комментарии двумя разными способами: с помощью элемента
или элемента
. Например:
или
Второй комментарий
Напомним, что эти элементы являются стандартными для разметки W3C XML 1.0 (см. главу 3). Для того чтобы использовать символы кириллицы в файлах компонентов-сценариев, нужно обязательно в элементе
указать атрибут encoding
со значением, соответствующим используемой кодировке, например:
Этот элемент необходим в тех WSC-файлах, в которых с помощью элементов
определено более одного компонента. В этом случае
является контейнером для элементов
.
Если же в WSC-файле описан только один компонент, то элемент
можно не использовать.
Внутри элемента
описывается один компонент-сценарий (СОМ-объект). Необязательный атрибут id
определяет идентификатор объекта (это может понадобиться в том случае, когда в одном WSC-файле находится несколько СОМ-объектов).
В элементе
приводится информация, которая необходима для регистрации в системе компонента-сценария в качестве СОМ-объекта.
Атрибуты
progid
и classid
задают соответственно программный идентификатор и глобальный код, с помощью которых компонент-сценарий может быть использован в других приложениях (например, progid="MyClass.MyObject"
и classid="{424ac2bc-5732-4dea-be17-0211af99cd79}"
). Из этих двух атрибутов обязательно должен быть указан хотя бы один (можно указать и оба). Если в элементе
приведен только атрибут progid
, то глобальный код (GUID) для описываемого объекта будет сгенерирован автоматически при регистрации объекта в системе. Рекомендуется, однако, явно указывать глобальный код объекта, т.к. в противном случае этот код может оказаться различным при регистрации объекта на разных машинах.
Глобальный код объекта может быть сгенерирован с помощью описанной ниже программы Windows Script Component Wizard.
С помощью атрибута
description
можно задать краткое описание объекта, которое будет занесено в системный реестр при регистрации объекта.
Атрибут
version
позволяет указать номер версии описываемого объекта. Этот номер позволяет запрашивать из приложения определенную версию СОМ-объекта (он должен быть указан через точку после программного идентификатора объекта, например "Myclass.MyObject.1"
).
С помощью элемента
внутри контейнера
можно указать две функции, одна из которых будет вызываться при регистрации объекта в системе (эта функция должна иметь имя Register()
), а другая — при удалении объекта из системы (эта функция должна иметь имя Unregister()
).
В элементе
описываются те свойства, методы и события объекта, которые после его регистрации будут доступны извне другим приложениям (клиентам автоматизации). Другими словами, этот элемент является контейнером для элементов
,
и
.
Элемент
объявляет свойство СОМ-объекта, которое будет доступно для клиентов автоматизации.
Атрибут
name
определяет имя этого свойства (в дальнейшем внутри элемента
должна быть объявлена глобальная переменная с тем же именем, с помощью которой можно будет изменять значение свойства). Объявляемое свойство может быть доступно либо только для чтения (внутри контейнера
указан только элемент
), либо только для записи (внутри
указан только элемент
), либо и для чтения и для записи (внутри
указаны как элемент
, так и элемент
).
Атрибут
internalName
в элементах
и
задает имена функций, которые будут использоваться для чтения и записи свойства соответственно (эти функции описываются внутри контейнера
). Если же атрибут internalName
не указан, то чтение (запись) свойства производится в функции с именем get_PropertyName(put_PropertуName)
, где PropertyName
— имя свойства (атрибут
).
Элемент
объявляет метод СОМ-объекта, который будет доступен для внешних клиентов автоматизации.
Атрибут
name
определяет имя этого метода. В дальнейшем, если не указан атрибут internalName
, внутри контейнера
должна быть описана функция или процедура с таким же именем
Задание атрибута
internalName
позволяет внутри контейнера
использовать для реализации метода функцию или процедуру с именем, отличным от значения аргумента name
.
Список параметров метода (если они имеются) задается внутри элемента
с помощью элементов
, каждый из которых должен содержать аргумент name
, определяющий имя параметра.
Элемент
объявляет событие, которое может возникать в СОМ-объекте и обрабатываться клиентами автоматизации.
Аргумент
name
, как обычно, определяет имя этого события. С помощью аргумента dispid
можно указать числовой идентификатор интерфейса события. Этот идентификатор компилируется в библиотеку типов объекта и используется в клиентском приложении для обработки нужного события.
Для того чтобы вызвать наступление события, внутри элемента
используется функция fireEvent()
с именем нужного события в качестве параметра.
Элементы
,
и
имеют тот же смысл, что и в модели WS XML (см. описание этих элементов в главе 3).
В элементе
приводится сценарий на языках JScript или VBScript, который определяет поведение создаваемого СОМ-объекта — здесь нужно задать глобальные переменные, соответствующие объявленным в элементах
свойствам объекта, описать функции или процедуры для объявленных с помощью элементов
методов объекта и т.д.
Перейдем теперь к рассмотрению конкретного примера, для которого мы подробно опишем создание компонента-сценария, регистрацию его в системе в качестве СОМ-объекта и использование этого объекта в JScript-сценарии.
Представим себе следующую ситуацию. Имеется несколько каталогов на жестком диске, в которых хранятся рабочие файлы разных пользователей. Необходимо каждый день с помощью программы-архиватора arj.exe делать архивы этих файлов в заданный каталог, при этом имя архивного файла должно соответствовать шаблону ппММДД.arj", где пп — уникальный для каждого пользователя префикс, ММ — текущий месяц, ДД — текущий день.
Мы создадим компонент-сценарий
DateArc.WSC
, с помощью свойств и методов которого можно будет выполнить поставленную задачу.
Начнем мы с того, что определимся, какие именно свойства и методы будет содержать создаваемый объект (табл. 10.1).
Таблица 10.1. Свойства и методы объекта DateArc.WSC
Название | Свойство/метод | Режим доступа | Описание |
---|---|---|---|
|
Свойство | Чтение/запись | Исходный каталог для архивирования |
|
Свойство | Чтение/запись | Каталог, в котором хранятся архивные файлы |
|
Свойство | Чтение/запись | Префикс файла-архива |
|
Свойство | Чтение/запись | Маска, по которой отбираются файлы для архивирования |
|
Свойство | Чтение | Текст сообщения об ошибке |
|
Метод | Метод, осуществляющий архивирование файлов |
Имея зарегистрированный в системе СОМ-объект с такими свойствами и методами, несложно написать сценарий (назовем его RunArj.js), в котором создавался бы экземпляр объекта
DateArc.WSC
и производилось с помощью метода FilesToArchiv()
архивирование файлов из исходного в целевой каталог (листинг 10.2).
DateArc.WSC
/********************************************************************/
/* Имя: RunArj.js */
/* Язык: JScript */
/* Описание: Архивирование файлов с помощью COM-объекта DateArc.WSC */
/********************************************************************/
//Объявляем переменные
var
DateArc, //Экземпляр объекта DateArc.WSC
Result; //Результат выполнения метода FilesToArchiv()
//Инициализируем константы для диалоговых окон
var vbCritical=16,vbInformation=64;
//Создаем объект WshShell
WshShell = WScript.CreateObject("WScript.Shell");
//Создаем объект DateArc.WSC
DateArc=WScript.CreateObject("DateArc.WSC");
DateArc.SFrom="D:\\1"; //Исходный каталог
DateArc.SArch="D:\\2"; //Каталог, в который будут архивироваться
//файлы
DateArc.SPref="aa"; //Префикс для файл-архива
DateArc.SMask="*.*"; //Маска, по которой будут отбираться файлы
//для архивирования
//Запускаем метод FilesToArchiv()
Result=DateArc.FilesToArchiv();
if (!Result)
//Если возникла ошибка, выводим соответствующее сообщение
WshShell.Popup(DateArc.SErrMess, 0, "Архивирование файлов", vbCritical);
else WshShell.Popup("Архивирование завершено успешно!", 0,
"Архивирование файлов", vbInformation);
/************* Конец *********************************************/
Из листинга 10.1 можно понять, что создание компонента-сценария связано с написанием большого количества вспомогательного кода (нужно заполнить элементы
,
,
и
, написать функции для чтения и записи каждого из свойств объекта и т.д). Поэтому мы воспользуемся специальным мастером для создания компонентов-сценариев Windows Script Component Wizard (эту программу можно свободно получить с сайта Microsoft http://msdn.microsoft.com/scripting).
Первым шагом после запуска мастера является заполнение полей диалогового окна, представленного на рис. 10.1. Здесь нужно ввести имя создаваемого компонента ("DateArc"), имя файла с его описанием ("DateArc"), программный идентификатор ("DateArc.WSC"), версию компонента ("1.00") и каталог, в котором будет создан WSC-файл ("C:\WSC").
Рис. 10.1. Общая информация о создаваемом компоненте-сценарии
На втором шаге работы мастера мы выберем, какой язык будет использоваться при написании сценария ("JScript"), и укажем, что при регистрации и работе объекта нужно выполнять проверку ошибок ("Error checking") (рис. 10.2).
Рис. 10.2. Определение характеристик компонента-сценария
Третий шаг работы мастера позволяет описать свойства создаваемого объекта. Здесь для каждого свойства мы указываем его имя (колонка "Name"), тип ("Read" — только чтение, "Write" — только запись, "Read/Write" — чтение и запись) и значение по умолчанию (колонка "Default") (рис. 10.3).
Рис. 10.3. Задание свойств компонента-сценария
На четвертом шаге описываются методы объекта. В нашем случае объект
DateArc.WSC
имеет единственный метод FilesToArchiv()
, вызываемый без параметров (рис. 10.4).
Рис. 10.4. Задание методов компонента-сценария
На пятом шаге нам предлагается указать, какие события могут возникать в объекте. Для нашего компонента-сценария мы не будем задавать никаких событий (рис. 10.5).
Рис. 10.5. Задание событий компонента-сценария
Шестой шаг является заключительным в работе мастера. Здесь нам выдается вся информация о создаваемом объекте (рис. 10.6). После нажатия кнопки Finish в каталоге C:\WSC будет создан файл DateArc.wsc, приведенный в листинге 10.3.
Рис. 10.6. Итоговая информация о создаваемом компоненте-сценарии
var description = new DateArc;
function DateArc() {
this.get_SFrom = get_SFrom;
this.put_SFrom = put_SFrom;
this.get_SArch = get_SArch;
this.put_SArch = put_SArch;
this.get_SPref = get_SPref;
this.put_SPref = put_SPref;
this.get_SMask = get_SMask;
this.put_SMask = put_SMask;
this.get_SErrMess = get_SErrMess;
this.FilesToArchiv = FilesToArchiv;
}
var SFrom;
var SArch;
var SPref;
var SMask;
var SErrMess;
function get_SFrom() {
return SFrom;
}
function put_SFrom(newValue) {
SFrom = newValue;
}
function get_SArch() {
return SArch;
}
function put_SArch(newValue) {
SArch = newValue;
}
function get_SPref() {
return SPref;
}
function put_SPref(newValue) {
SPref = newValue;
}
function get_SMask() {
return SMask;
}
function put_SMask(newValue) {
SMask = newValue;
}
function get_SErrMess(){
return SErrMess;
}
function FilesToArchiv() {
return "Temporary Value";
}
]]>
Как мы видим из листинга 10.3, при использовании в компоненте-сценарии языка JScript в результате работы мастера внутрь контейнера
помещаются:
□ глобальные переменные, которые соответствуют объявленным в элементах
свойствам;
□ заготовки функций с префиксами
get_
и put_
, которые осуществляют чтение и запись свойств объекта;
□ заготовки функций, которые соответствуют объявленным в элементах
методам.
Кроме этого, создается экземпляр внутреннего объекта, содержащего те же свойства и методы, что были описаны внутри элемента
(переменная description
). Имя этого внутреннего объекта совпадает с именем класса описываемого СОМ-объекта (в нашем случае это "DateArc
").
Создаваемый мастером внутренний объект нужен только в иллюстративных целях, т.к. здесь наглядно видно, какие именно свойства и методы будет предоставлять клиентам автоматизации компонент-сценарий. Если убрать из контейнера
описание внутреннего объекта, это никак не скажется на функционировании объекта-сценария.
Для получения нужного нам СОМ-объекта из сформированного с помощью Windows Script Component Wizard файла DateArc.wsc нужно выполнить несколько шагов.
Во-первых, для того, чтобы использовать внутри описания СОМ-объекта символы кириллицы, необходимо добавить в директиву
аргумент encoding="windows-1251"
(без этого в сценарии не удастся даже написать по-русски комментарии):
Во-вторых, в контейнер
мы вставим элемент
с двумя функциями Register()
и Unregister()
, которые будут выводить на экран диалоговые окна с соответствующей информацией при регистрации компонента-сценария и его отключении соответственно:
var WshShell;
//Инициализируем константы для диалоговых окон
var vbInformation=64;
function Register() {
//Создаем объект WshShell
WshShell = new ActiveXObject("WScript.Shell");
WshShell.Popup("Компонент зарегистрирован в системе",0,
"Компонент для архивирования файлов",vbInformation);
}
function Unregister() {
//Создаем объект WshShell
WshShell = new ActiveXObject("WScript.Shell");
WshShell.Popup("Компонент удален из системы", 0,
"Компонент для архивирования файлов",vbInformation);
}
]]>
Затем нам понадобятся две дополнительные функции. Первая из них
NowIs()
формирует строку формата ММДД, где ММ — текущий месяц, ДД — текущий день:
//Вспомогательная функция для символьного представления даты
function NowIs() {
var d, s="", s1="";
//Создаем объект Date (текущая дата)
d=new Date();
//Выделяем номер месяца
s+=(d.getMonth()+1);
//Если месяц представляется одним символом, добавляем слева "0"
if (s.length==1) s="0"+s;
//Выделяем в дате день
s1+=d.getDate();
//Если день представляется одним символом, добавляем слева "0"
if (s1.length==1) s1="0"+s1;
s+=s1;
//Возвращаем сформированную строку
return s;
}
Вторая функция
CheckPath()
будет проверять наличие исходного каталога и каталога для хранения архивных файлов. Для этого используется метод FolderExists()
объекта FileSystemObject
. Заметим, что сам объект FileSystemObject
нужно создавать не путем вызова метода CreateObject
объекта WScript
, а с помощью конструкции new ActiveXObject()
:
FSO=new ActiveXObject("Scripting.FileSystemObject");
т.к. в отличие от обычного сценария WSH в компоненте-сценарии нет встроенного объекта
WScript
. Если хотя бы один из каталогов не существует, функция CheckPath()
запишет соответствующее сообщение в свойство SErrMess
и вернет значение false
, в противном случае функция CheckPath()
возвращает значение true
.
//Проверка доступности каталогов
function CheckPath() {
var FSO;
//Создаем объект FileSystemObject
FSO=new ActiveXObject("Scripting.FileSystemObject");
//Проверяем доступность исходного каталога
if (!FSO.FolderExists(SFrom)) { //Исходный каталог не существует
//Формируем строку с информацией об ошибке
SErrMess="Не найден исходный каталог "+SFrom;
return false;
}
//Проверяем доступность каталога для архивирования
if (!FSO.FolderExists(SArch)) {
//Каталог для архивирования не существует
//Формируем строку с информацией об ошибке
SErrMess="Не найден каталог для хранения архивов "+SArch;
return false;
}
//Если оба каталога существуют, возвращаем true
return true;
}
Основной функцией, осуществляющей архивирование файлов, является
FilesToArchiv()
. В самом начале этой функции с помощью вызова CheckPath()
проверяется наличие рабочих каталогов. Если хотя бы один из каталогов не существует, то выполнение FilesToArchiv()
прерывается и возвращается значение false
:
if (!CheckPath()) return false;
Затем создаются экземпляры объектов
FileSystemObject
и WshShell
:
//Создаем объект FileSystemObject
FSO = new ActiveXObject("Scripting. FileSystemObject");
//Создаем объект WshShell
WshShell = new ActiveXObject("WScript.Shell");
Имя файла-архива формируется следующим образом:
//Формируем имя файла-архива
SFName=SPref+NowIs()+".arj";
Архиватор arj.exe мы будем запускать в отдельном командном окне, которое закроется после выполнения этой программы. Для этого мы сформируем командную строку
SComLine
, с помощью которой запускается вторичная копия командного процессора (путь к командному процессору хранится в переменной среды %COMSPEC%
, вторичная копия вызывается с помощью ключа /с
):
SComLine="%COMSPEC% /с ";
Синтаксис запуска arj.exe для создания архивного файла имеет следующий вид:
arj.exe a Archiv Files
где
— путь к файлу-архиву, Archiv
— имена добавляемых в архив файлов (здесь можно использовать шаблонные символы ? и *). Поэтому мы добавим нужные компоненты к командной строке Files
SComLine
:
SComLine+=" arj.exe a "+FSO.BuildPath(SArch, SFName) + " ";
SComLine+= FSO.BuildPath(SFrom, SMask);
Команды, записанные в
SComLine
, запускаются с помощью метода Run
объекта WshShell
; код возврата сохраняется в переменной RetCode
:
RetCode = WshShell.Run(SComLine, 1, true);
Равенство нулю переменной
RetCode
означает, что архивирование выполнено без ошибок — в этом случае функция FilesToArchiv()
возвращает true
. Если же при выполнении arj.exe возникла ошибка (переменная RetCode
не равна нулю), то ее код вносится в сообщение об ошибке (свойство SErrMess
):
//Анализируем код возврата для arj.exe
if (0==RetCode)
//Выполнение arj.exe завершилось без ошибок
return true;
else {
//Формируем строку с информацией об ошибке
SErrMess="Ошибка ARJ.EXE! Код "+RetCode;
return false;
}
Полностью содержимое файла DateArc.wsc приведено в листинге 10.4.
DateArc.WSC
(JScript)
version="1.00"
classid="{424ac2bc-5732-4dea-be17-0211af99cd79}">
var WshShell;
//Инициализируем константы для диалоговых окон
var vbInformation=64;
function Register() {
//Создаем объект WshShell
WshShell = new ActiveXObject("WScript.Shell");
WshShell.Popup("Компонент зарегистрирован в системе",0,
"Компонент для архивирования файлов",vbInformation);
}
function Unregister() {
//Создаем объект WshShell
WshShell = new ActiveXObject("WScript.Shell");
WshShell.Popup("Компонент удален из системы",0,
"Компонент для архивирования файлов",vbInformation);
}
]]>
var description = new DateArc;
//Конструктор объекта DateArc
function DateArc() {
//Объявляем свойства объекта DateArc
this.get_SFrom = get_SFrom;
this.put_SFrom = put_SFrom;
this.get_SArch = get_SArch;
this.put_SArch = put_SArch;
this.get_SPref = get_SPref;
this.put_SPref = put_SPref;
this.get_SMask = get_SMask;
this.put_SMask = put_SMask;
this.get_SErrMess = get_SErrMess;
//Объявляем метод FilesToArchiv
this.FilesToArchiv = FilesToArchiv;
}
var SFrom, //Исходный каталог для архивирования
SArch, //Каталог, в котором будет создаваться архив
SPref, //Префикс файла
SMask, //Маска, по которой отбираются файлы для
//архивирования
SErrMess; //Текст сообщения об ошибке
//Чтение и запись свойства SFrom
function get_SFrom() {
return SFrom;
}
function put_SFrom(newValue) {
SFrom = newValue;
}
//Чтение и запись свойства SArch
function get_SArch() {
return SArch;
}
function put_SArch(newValue) {
SArch = newValue;
}
//Чтение и запись свойства SPref
function get_SPref() {
return SPref;
}
function put_SPref(newValue) {
SPref = newValue;
}
//Чтение и запись свойства SMask
function get_SMask() {
return SMask;
}
function put_SMask(newValue) {
SMask = newValue;
}
//Чтение свойства SErrMess
function get_SErrMess() {
return SErrMess;
}
//Вспомогательная функция для символьного представления даты
function NowIs() {
var d, s="", s1="";
//Создаем объект Date (текущая дата)
d=new Date();
//Выделяем номер месяца
s+=(d.getMonth()+1);
//Если месяц представляется одним символом, добавляем слева "0"
if (s.length==1) s="0"+s;
//Выделяем в дате день
s1+=d.getDate();
//Если день представляется одним символом, добавляем слева "0"
if (s1.length==1) s1="0"+s1;
s+=s1;
//Возвращаем сформированную строку
return s;
}
//Проверка доступности каталогов
function CheckPath() {
var FSO;
//Создаем объект FileSystemObject
FSO=new ActiveXObject("Scripting.FileSystemObject");
//Проверяем доступность исходного каталога
if (!FSO.FolderExists(SFrom)) { //Исходный каталог не существует
//Формируем строку с информацией об ошибке
SErrMess="Не найден исходный каталог "+SFrom;
return false;
}
//Проверяем доступность каталога для архивирования
if (!FSO.FolderExists(SArch)) {
//Каталог для архивирования не существует
//Формируем строку с информацией об ошибке
SErrMess="Не найден каталог для хранения архивов "+SArch;
return false;
}
//Если оба каталога существуют, возвращаем true
return true;
}
//Архивирование файлов из исходного каталога
function FilesToArchiv() {
var WshShell,SComLine,RetCode,SFName,FSO;
//Если хотя бы один из каталогов не существует, возвращаем false
if (!CheckPath()) return false;
//Создаем объект FileSystemObject
FSO=new ActiveXObject("Scripting.FileSystemObject");
//Создаем объект WshShell
WshShell = new ActiveXObject("WScript.Shell");
//Формируем имя файла-архива
SFName=SPref+NowIs()+".arj";
//Формируем командную строку для запуска архиватора arj.exe
SComLine="%COMSPEC% /c arj.exe a ";
SComLine+=FSO.BuildPath(SArch,SFName)+" ";
SComLine+=FSO.BuildPath(SFrom,SMask);
//Запускаем архиватор arj.exe
RetCode = WshShell.Run(SComLine, 1, true);
//Анализируем код возврата для arj.exe
if (0==RetCode)
//Выполнение arj.exe завершилось без ошибок
return true;
else {
//Формируем строку с информацией об ошибке
SErrMess="Ошибка ARJ.EXE! Код "+RetCode;
return false;
}
}
]]>
После написания текста объекта-сценария нужно внести информацию о нем в системный реестр, т.е, зарегистрировать объект. Это можно сделать несколькими способами, самый простой из которых заключается в следующем. Нужно выделить в Проводнике Windows необходимый WSC-файл с компонентом-сценарием (в нашем случае это файл DateArc.wsc в каталоге C:\WSC), щелкнуть правой кнопкой мыши и в появившемся контекстном меню выбрать пункт Подключить (Register) (рис. 10.7).
Рис. 10.7. Контекстное меню, сопоставленное расширению WSC
После этого необходимая информация запишется в реестр и выполнится функция
Register()
, которая описана в файле DateArc.wsc внутри элемента
, в результате чего на экран будет выведено диалоговое окно, показанное на рис. 10.8.
Рис. 10.8. Информация о регистрации компонента-сценария DateArc.WSC
В системном реестре данные о регистрируемом объекте
DateArc.WSC
заносятся в две ветви: HKEY_LOCAL_MACHINE
и HKEY_CLASSES_ROOT
.
В разделе
HKEY_LOCAL_MACHINE\SOFTWARE\Classes
создается новый подраздел DateArc.WSC
со значением по умолчанию "DateArc
". В подразделе DateArc.WSC
в параметр CLSID
записывается глобальный код объекта DateArc.WSC
— "{424AC2BC-5732-4DEA-BE17-0211AF99CD79}" (рис. 10.9).
Рис. 10.9. Информация о зарегистрированном объекте DateArc.WSC в ветви
HKEY_LOCAL_MACHINE
В разделе
HKEY_CLASSES_ROOT\CLSID
создается новый подраздел, название которого совпадает с глобальным кодом объекта DateArc.WSC — "{424AC2BC-5732-4DEA-BE17-0211AF99CD79}". Значением по умолчанию для нового подраздела является "DateArc" (рис. 10.10).
Рис. 10.10. Информация о зарегистрированном объекте DateArc.WSC в ветви
HKEY_CLASSES_ROOT
В новом разделе создаются, в свою очередь, еще несколько подразделов, значения которых очень важны для функционирования компонента-сценария в качестве СОМ-объекта (см. разд. "Технология Windows Script Components"). Эти разделы для нашего примера описаны в табл. 10.2.
Таблица 10.2. Подразделы, создаваемые в разделе HKCR\CLSID \{424AC2BC-5732-4DEA-BE17-0211AF99CD79} при регистрации объекта DateArc.WSC
Название | Значение по умолчанию | Описание |
---|---|---|
|
"F:\WINDOWS\System32\scrobj.dll" | Полный путь к оболочке компонентов-сценариев scrobj.dll |
|
"DateArc.WSC.1.00" | Программный идентификатор объекта, включающий номер версии |
|
"file://C:\WSC\DateArc.wsc" | Полный путь к WSC-файлу |
|
"DateArc.WSC" | Программный идентификатор объекта без номера версии |
Отключается компонент-сценарий так же просто, как и регистрируется. Снова нужно выделить в Проводнике Windows WSC-файл, щелкнуть правой кнопкой мыши и в появившемся контекстном меню выбрать пункт Отключить (Unregister). При этом из системного реестра записи об этом объекте будут удалены, после чего выполнится функция
Unregister()
(рис. 10.11).
Рис. 10.11. Информация об отключении компонента-сценария DateArc.WSC
Различие между компонентами-сценариями, написанными на языках JScript и VBScript, проявляется только в секции
WSC-файлов. Во-первых, естественным образом меняется синтаксис описанных внутри контейнера
функций. Во-вторых, в WSC-файле, написанном с помощью VBScript, отсутствует описание внутреннего объекта, который генерируется программой Windows Script Component Wizard и имеет поля и методы, совпадающие с объявленными внутри элемента
(см. листинг 10.3).
Объяснение этому очень простое — в VBScript нельзя создавать свои внутренние объекты.
Полностью содержимое файла DateArcVB.wsc, который реализует СОМ-объект
DateArc.WSC
с помощью VBScript, приведено в листинге 10.5.
version="1.00" classid="{424ac2bc-5732-4dea-be17-0211af99cd79}">
Dim WshShell
Function Register()
'Создаем объект WshShell
Set WshShell = CreateObject("WScript.Shell")
WshShell.Popup "Компонент зарегистрирован в системе",0,_
"Компонент для архивирования файлов",vbInformation
End Function
Function Unregister()
'Создаем объект WshShell
Set WshShell = CreateObject("WScript.Shell")
WshShell.Popup "Компонент удален из системы",0,_
"Компонент для архивирования файлов",vbInformation
End Function
]]>
Dim SFrom 'Исходный каталог для архивирования
Dim SArch 'Каталог, в котором будет создаваться архив
Dim SPref 'Префикс файла
Dim SMask 'Маска, по которой отбираются файлы для
'архивирования
Dim SErrMess 'Текст сообщения об ошибке
'Чтение и запись свойства SFrom
Function get_SFrom()
get_SFrom = SFrom
End Function
Function put_SFrom(newValue)
SFrom = newValue
End Function
'Чтение и запись свойства SArch
Function get_SArch()
get_SArch = SArch
End Function
Function put_SArch(newValue)
SArch = newValue
End Function
'Чтение и запись свойства SPref
Function get_SPref()
get_SPref = SPref
End Function
Function put_SPref(newValue)
SPref = newValue
End Function
'Чтение и запись свойства SMask
Function get_SMask()
get_SMask = SMask
End Function
Function put_SMask(newValue)
SMask = newValue
End Function
'Чтение свойства SErrMess
Function get_SErrMess()
get_SErrMess = SErrMess
End Function
'Вспомогательная функция для символьного представления даты
Function NowIs()
Dim d,s,s1
s=""
s1=""
'Определяем текущую дату
d=Date()
'Выделяем номер месяца
s=s & Month(d)
'Если месяц представляется одним символом, добавляем слева "0"
If Len(s)=1 Then
s="0" & s
End If
'Выделяем в дате день
s1=s1 & Day(d)
'Если день представляется одним символом, добавляем слева "0"
If Len(s1)=1 Then
s1="0" & s1
End If
s=s & s1
'Возвращаем сформированную строку
NowIs=s
End Function
'Проверка доступности каталогов
Function CheckPath()
Dim FSO
'Создаем объект FileSystemObject
Set FSO=CreateObject("Scripting.FileSystemObject")
'Проверяем доступность исходного каталога
If Not FSO.FolderExists(SFrom) Then
'Исходный каталог не существует
'Формируем строку с информацией об ошибке
SErrMess="Не найден исходный каталог " & SFrom
CheckPath=false
End If
'Проверяем доступность каталога для архивирования
If Not FSO.FolderExists(SArch) Then
'Каталог для архивирования не существует
'Формируем строку с информацией об ошибке
SErrMess="Не найден каталог для хранения архивов " & SArch
CheckPath=false
End If
'Если оба каталога существуют, возвращаем true
CheckPath=true
End Function
'Архивирование файлов из исходного каталога
Function FilesToArchiv()
Dim WshShell,SComLine,RetCode,SFName,FSO
'Если хотя бы один из каталогов не существует, возвращаем false
If Not CheckPath() Then
FilesToArchiv=false
End If
'Создаем объект FileSystemObject
Set FSO=CreateObject("Scripting.FileSystemObject")
'Создаем объект WshShell
Set WshShell=CreateObject("WScript.Shell")
'Формируем имя файла-архива
SFName=SPref & NowIs() & ".arj"
'Формируем командную строку для запуска архиватора arj.exe
SComLine="%COMSPEC% /c arj.exe a "
SComLine=SComLine & FSO.BuildPath(SArch,SFName)+" "
SComLine=SComLine & FSO.BuildPath(SFrom,SMask)
'Запускаем архиватор arj.exe
RetCode = WshShell.Run(SComLine, 1, true)
'Анализируем код возврата для arj.exe
If 0=RetCode Then
'Выполнение arj.exe завершилось без ошибок
FilesToArchiv=true
Else
'Формируем строку с информацией об ошибке
SErrMess="Ошибка ARJ.EXE! Код " & RetCode
FilesToArchiv=false
End If
End Function
]]>