1

Тема: WSH: трансляция объекта WScript

COM-сервер WshScript.wsc предоставляет возможность использования стандартного объекта WScript там, где он недоступен непосредственно (например, в HTA).

WshScript.wsc

<?xml version='1.0' encoding='windows-1251' standalone='yes'?>
<component id='WshScript'>
<registration progid='WshScript'/>
<public>
  <property name='Name' dispid='0'><get /></property>
  <property name='WScript'><get /></property>
  <method name='Add'/>
  <method name='Remove'/>
</public>

<resource id='LocalizedName'>Сценарий сервера сценариев Windows</resource>

<script language='JScript'><![CDATA[
var WshGlobal;
(function () {
  var
    WshShell=new ActiveXObject("WScript.Shell"),
    WshEnvironment=WshShell.Environment("Process");
  var
    window_name=String(Math.random());
    SavedEnvString=WshEnvironment("WshScript_window_name");
  WshEnvironment("WshScript_window_name")=window_name;
  WshShell.Run("WScript.exe \"%windir%\\System32\\WshScript1.js\"", 0, true);

  var ShellWindows=(new ActiveXObject("Shell.Application")).Windows();
  for (var i=ShellWindows.Count; --i>=0;) {
    var IE=ShellWindows.Item(i);
    try {
      var Script=IE.Document.Script;
      if (Script.name==window_name) {
        WshGlobal=Script.WshGlobal; IE.Quit();
        if (SavedEnvString)
          WshEnvironment("WshScript_window_name")=SavedEnvString;
        else
          WshEnvironment.Remove("WshScript_window_name");
        return;
      }
    } catch (Err) {}
  }
})();
/************************************/
function get_Name() {return getResource("LocalizedName");}
function get_WScript() {return WshGlobal.WScript;}
function Add(EventName, EventHandler) {WshGlobal[EventName]=EventHandler;}
function Remove(EventName) {delete WshGlobal[EventName];}
]]></script>
</component>

WshScript.js

// %windir%\System32\WshScript.js
// Испольуется WshScript.wsc для получения объекта WScript

(function () {
  var IE=new ActiveXObject("InternetExplorer.Application");
  IE.Navigate("about:blank"); while (IE.Busy) WScript.Sleep(50);
  var Script=IE.Document.Script;
  Script.WshGlobal=this;
  Script.name=
    (new ActiveXObject("WScript.Shell")).
      ExpandEnvironmentStrings("%WshScript_window_name%");
})();

for (;;) WScript.Sleep(0x7fffffff);

WshScript1.js

// %windir%\System32\WshScript1.js
// Испольуется WshScript.wsc для синхронизации с WshScript.js

var WshShell=new ActiveXObject("WScript.Shell");
WshShell.Run("CScript.exe \"%windir%\\System32\\WshScript.js\"", 0, false);
var window_name=WshShell.ExpandEnvironmentStrings("%WshScript_window_name%");

var ShellWindows=(new ActiveXObject("Shell.Application")).Windows();
for (;;) {
  for (var i=ShellWindows.Count; --i>=0;)
    try {
      if (ShellWindows.Item(i).Document.Script.name==window_name)
        WScript.Quit();
    } catch (Err) {}
  WScript.Sleep(50);
}

Файлы WshScript.wsc, WshScript.js и WshScript1.js размещаются в каталоге %windir%\System32\, при этом WshScript.wsc необходимо зарегистрировать в системе как COM-сервер.

COM-сервер WshScript.wsc предоставляет ряд свойств и методов:

- свойство WScript (только чтение) возвращает стандартный объект WScript;
- метод Add(EventName, EventHandler) добавляет обработчик события для объекта, созданного с помощью WScript.CreateObject();
- метод Remove(EventName) удаляет созданный ранее обработчик события.

Файл test.hta демонстрирует использование COM-сервера WshScript.wsc и транслируемого объекта WScript.

test.hta

<HTML>
<HEAD>
<META http-equiv='Content-Type' content='text/html; charset=windows-1251'>

<SCRIPT language='JavaScript' type='text/javascript'><!--
var WshScript=new ActiveXObject("WshScript"), WScript=WshScript.WScript;
alert(WScript.ScriptFullName);
WScript.Sleep(5000);
var WshShell=WScript.CreateObject("WScript.Shell");
var WshScriptExec=WshShell.Exec("cmd.exe");
WshScriptExec.StdIn.WriteLine("dir");
WshScriptExec.StdIn.WriteLine("exit");
alert(WshScriptExec.StdOut.ReadAll());

onunload=function () {WScript.Quit();};
// --></SCRIPT>

<SCRIPT language='VBScript' type='text/vbscript'><!--
Dim IE

Sub document_onclick()
  Set IE = WScript.CreateObject("InternetExplorer.Application", "IE_")
  IE.Visible = True
  WshScript.Add "IE_OnQuit", GetRef("IE_OnQuit")
End Sub

Sub IE_OnQuit()
  IE.Visible = False 'чтобы увидеть следующее сообщение,
                     'т.к. фокус окну HTA не передаётся
  alert "Окно Internet Explorer будет закрыто."
End Sub
' --></SCRIPT>
</HEAD>

<BODY>
<P>При щелчке мышью по странице будет открыто окно Internet&nbsp;Explorer,
при закрытии которого будет выведено сообщение
«Окно Internet Explorer будет закрыто.».</P>

<P><SMALL>Повторный щелчок до закрытия Internet&nbsp;Explorer
может привести к ошибке.</SMALL></P>
</BODY></HTML>

При запуске этого hta происходит следующее:

- выводится полный путь к файлу WshScript.js (объект WScript которого транслируется);
- делается пауза на 5 секунд средствами объекта WScript;
- демонстрируется работа с консольными приложениями, запускаемыми с помощью WshShell.Exec() (без появления "чёрного окна", т.к. WshScript.js выполняется в невидимом окне): запускается команда dir и выводится результат её работы;
- отображается окно hta; щелчок в окне приводит к созданию окна Internet Explorer с обработкой его события "OnQuit": при закрытии этого окна hta выдаст сообщение;
- при закрытии окна hta вызывается WScript.Quit(), чтобы завершить процесс CScript.exe; это действие является обязательным, иначе процесс останется в памяти.

Теперь о принципах работы. При создании объекта COM-сервера "WshScript" происходит следующее:

- создаётся переменная среды WshScript_window_name, в которую записывается случайная строка; эта строка впоследствии используется как имя служебного невидимого окна Internet Explorer, которое необходимо для работы;
- запускается скрипт WshScript1.js с ожиданием его завершения;
- скрипт WshScript1.js асинхронно запускает скрипт WshScript.js и ожидает появления окна Internet Explorer с именем WshScript_window_name; когда такое окно появляется, скрипт WshScript1.js завершает свою работу;
- скрипт WshScript.js запускает Internet Explorer, создавая скрытое окно с именем WshScript_window_name; скрипт передаёт свойству "Script" объекта "Document" окна Internet Explorer свой глобальный контекст ("this"), из которого потом можно будет вытащить объект WScript; этот скрипт никогда не завершит работу, пока не будет вызван метод Quit() его объекта WScript (организуется бесконечный цикл);
- когда работа скрипта WshScript1.js завершена, управление передаётся обратно в COM-сервер, а в системе уже есть скрытое окно Internet Explorer с именем WshScript_window_name;
- в системе разыскивается окно Internet Explorer с именем WshScript_window_name, и из свойства "Script" его объекта "Document" извлекается глобальный контекст скрипта WshScript.js; свойство "WScript" этого контекста и будет искомым объектом WScript, который предоставляется COM-сервером как своё публичное свойство "WScript"; окно Internet Explorer закрывается.

Автор идеи - wisgest.

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

2 (изменено: Poltergeyst, 2019-11-05 02:41:51)

Re: WSH: трансляция объекта WScript

Без гарантий, используете на свой страх и риск.

Пример трансляции объекта WScript в область Internet Explorer, через передачу значения заданного произвольного свойства объекта Document, создаваемого скриптом-сервером.

Предназначен для отслеживания события WMI (запуск процесса) в области Internet Explorer с применением возможностей транслированного объекта WScript.

Скрипт состоит из двух частей:

1] Сервер WSH [trns_vbs.js], который создает объект Internet Explorer, выполняет навигацию на документ-клиент и передает ему свою общую область(this) путем присвоения значения заданному произвольному свойству документа. Скрипт-сервер удерживается циклом, что позволяет в любой момент обратится к его объектам.

2] Документ-клиент [trns_vbs.htm], инициируемый скриптом-сервером, получает общую область скрипта-сервера из значения своего произвольного свойства изначально заданного сервером. Затем из полученной области "вынимается" объект WScript. Таким образом происходит трансляция.

При использовании транслированного метода WScript.CreateObject в пространстве Internet Explorer, предусматривающего обработку событий, обработка событий однако сохраняется в области скрипта-сервера, что требует дополнительной связки обработчиков событий из области Internet Explorer с областью скрипта-сервера. Для этого из области Internet Explorer вызывается специальная функция области скрипта-сервера, в которую передаются имя события и указатель на обработчик.

Для начала работы запустите сервер [trns_vbs.js]. После закрытия окна Internet Explorer работа сервера автоматически завершается.

Платформа: Internet Explorer
OC WinME/XP

Post's attachments

wscr2ie.zip 5.95 kb, 3 downloads since 2019-11-05 

You don't have the permssions to download the attachments of this post.

3 (изменено: Poltergeyst, 2019-11-05 02:42:26)

Re: WSH: трансляция объекта WScript

Совершенно аналогичное решение для языка LangMF. На этот раз объект WScript транслируется в область LangMF через объект многопотоковых скриптов 'Atomix.NewLangMF'.

Потребуется установленный LangMF 9
ОС WinXP/7

Post's attachments

wscr2mf.zip 4.6 kb, 3 downloads since 2019-11-05 

You don't have the permssions to download the attachments of this post.