IWebBrowser2
(ссылка: IWebBrowser2 Interface). Объект хранит в себе данные даже после завершения всех скриптов, практически как буфер обмена, и может служить как средство обмена данными и объектами между скриптами.
Примечательно, что объект не удаляется из системы по завершении скрипта, создавшего его. Фактически, этот объект является новым окном Проводника с параметром
Visible = false
. В русской локализованной версии Windows объект определяется как Проводник Windows
(проверялось на Windows 7 Ultimate x64), в нелокализованых версиях Windows - Microsoft Internet Explorer
(Windows XP Service Pack 3) или Windows Explorer
(Windows Vista Enterprise Service Pack 2):
var appWindow = GetObject("new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}"); WScript.Echo(appWindow);
Переменные примитивных типов хранятся достаточно долго и доступны все время, пока объект существует в системе. Сложные объекты (например,
Object
или Array
) доступны между скриптами только пока скрипты не выгружены из памяти. То есть окно Проводника хранит ссылки на объекты. По завершении скрипта, сохранившего ссылку, объект становится недоступен, а обращение к ссылке вызывает исключение в скрипте, обратившемся к данным по этой ссылке. В целом это можно рассматривать как некий инструмент для передачи данных между скриптами, хотя и не обладающий достаточной надежностью.
Исходный код GlobalContainer.js
с комментариями
/** * Конструктор объекта-обертки * Создает объект типа WebBrowser2 (невидимое окно Проводника) * * @param String Сигнатура для идентификации уникального окна * @return Object GlobalContainer */ function GlobalContainer(signature) { signature = signature || GlobalContainer.signature; this.appWindow = GlobalContainer.getInstance(signature); if ( ! this.appWindow ) { this.appWindow = GetObject('new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}'); this.appWindow.StatusText = signature; } }; /** * Константа, определяет сигнатуру по умолчанию */ GlobalContainer.signature = 'GlobalContainer'; /** * Ищет окно с заданной сигнатурой * * @param String Сигнатура для идентификации уникального окна * @return Object WebBrowser2 */ GlobalContainer.getInstance = function(signature) { signature = signature || GlobalContainer.signature; var appList = (new ActiveXObject('Shell.Application')).Windows(); var i = appList.Count; while ( i-- ) { var e; try { var app = appList.Item(i); if ( app.StatusText && app.StatusText.indexOf(signature) == 0 ) { return app; } } catch (e) { } } }; /** * Возвращает данные по ключу, сохраненные в окне. * Данные могут быть сохранены с помощью. * GlobalContainer::putProperty() * * @param String Ключ * @return Mixed */ GlobalContainer.prototype.getProperty = function(name) { // return this.appWindow.GetProperty(name); var e; try { return this.appWindow.GetProperty(name); } catch (e) { } }; /** * Сохраняет данные с заданным ключом. * Данные могут быть получены с помощью. * GlobalContainer::putProperty() * * @param String Ключ * @param Mixed Данные * @return void */ GlobalContainer.prototype.setProperty = function(name, value) { // return this.appWindow.PutProperty(name, value); var e; try { return this.appWindow.PutProperty(name, value); } catch (e) { } }; /** * Закрывает существующее окно Проводника * * @param void * @return void */ GlobalContainer.prototype.close = function() { // return this.appWindow.Quit(); var e; try { return this.appWindow.Quit(); } catch (e) { } };
Тестовые файлы
test.js
:
// Этот фрагмент кода выполняется при запуске с ключом /init if ( WScript.Arguments.Named.Exists('init') ) { var co = new GlobalContainer(); co.setProperty('that', this); var flag = false; while ( ! flag ) { WScript.Sleep(10); } WScript.Echo("Эта строка выполняется не всегда!!!"); co.close(); } if ( WScript.Arguments.Named.Exists('soft') ) { var co = new GlobalContainer(); var that = co.getProperty('that'); if ( ! that ) { WScript.Echo("Связь не обнаружена."); } else { WScript.Echo("Обнаружена связь с внешним процессом."); var e; try { WScript.Echo("Попытаемся мягко завершить внешний процесс."); that.flag = true; } catch (e) { WScript.Echo("Попытка мягко завершить неудачна. Возможно процесс уже удален."); } } WScript.Echo("Закроем связного."); co.close(); } if ( WScript.Arguments.Named.Exists('hard') ) { var co = new GlobalContainer(); var that = co.getProperty('that'); if ( ! that ) { WScript.Echo("Связь не обнаружена."); } else { WScript.Echo("Обнаружена связь с внешним процессом."); var e; try { WScript.Echo("Попытаемся жестко завершить внешний процесс."); that.WScript.Quit(); } catch (e) { WScript.Echo("Попытка жестко завершить неудачна. Возможно процесс уже удален."); } } WScript.Echo("Закроем связного."); co.close(); }
test.wsf
<?xml version="1.0" encoding="utf-8" ?> <package> <job id="wscmd"> <?job error="true" debug="false" ?> <script language="javascript" src="./GlobalContainer.js"></script> <script language="javascript" src="./test.js"></script> </job> </package>
Тест 1. "Мягкое" закрытие первичного процесса
1. в отдельном окне выполнить:cscript //nologo test.wsf /init2. в другом окне выполнить
cscript //nologo test.wsf /soft
Тест 2. "Жесткое" закрытие первичного процесса
3. в отдельном окне выполнитьcscript //nologo test.wsf /init4. в другом окне выполнить
cscript //nologo test.wsf /hard
No comments:
Post a Comment