1

Тема: WSH & HTA: обмен данными между скрипт-процессами

Для обмена данными потребуется скрипт-сервер, в котором формируется сообщение, и скрипт-клиент, который это сообщение
принимает, основываясь на определенном "сигнале" который подает сервер - будь то создание мутекса, изменение файла или возникновение еще какого-нибудь события. Мутекс - это сигнальный объект, принадлежащий процессу. В системе может существовать только один мутекс. Передача данных здесь идет через буфер обмена.

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

Потребуется зарегистрированная библиотека LangMf.Dll v7.7.0.0.

Скрипт-сервер SERVER.HTA, создающий мутекс и копирующий данные в буфер:

<meta http-equiv=Content-Type content="text/html; charset=windows-1251">
<HTML>
<TITLE>Data Exchange Sample Server-Окно сервер</TITLE>
<HEAD>
<STYLE type=text/css>
BODY    {background-color: #84c2fb;}
INPUT    {font-family: Lucida Console; font-size: 14px; font-weight: 700}
</STYLE>
<HTA:APPLICATION
    ID="DDESRV"
    APPLICATIONNAME="ddeServ"    
/>
</HEAD>

<BODY SCROLL="NO">
<CENTER><INPUT TYPE='TEXT' ID='txt1' SIZE=30></CENTER>
<CENTER><INPUT TYPE='BUTTON' ID='btn1' VALUE='Отправить'></CENTER>
<SCRIPT>
/*Серверный скрипт для создания семафора-мутекса,существование
которого разрешает клиентскому скрипту считывание данных
из буфера обмена*/

//Потребуется зарегистрированная библиотека LangMf.Dll v7.7.0.0
    
window.moveTo    (0,0)
window.resizeTo    (500,250)

var LMFCode=new String
var LMF=new ActiveXObject('Atomix.LangMf')
    
LMFCode=
'<#Module=>                             \n'+
';---------------------------------------------------------------------    \n'+
'Sub Load(cmdstr)                        \n'+
'End Sub                            \n'+
';----------------------------------------------------------------------      \n'+    
'Function CreateMutex()                         \n'+
'Sys.ClipBoard.SetText txt1.value                \n'+
';Создание мутекса-семафора с заданным именем        \n'+
'hMutex=Sys.DynApi.CallFunction("KERNEL32.DLL","CreateMutexA", _\n'+
'                    0, _            \n'+
'                    False, _            \n'+
'                    "DDEHTA")        \n'+
';Разрешение на открытие мутекса клиентским скриптом        \n'+
';который примет данные из буфера обмена и уничтожит мутекс    \n'+
'Sys.DynApi.CallFunction "KERNEL32.DLL","ReleaseMutex",hMutex    \n'+
'End Function                            \n'+
';----------------------------------------------------------------------      \n'+
';Уничтожение мутекса при выходе из приложения        \n'+
'Function CloseHandle()                        \n'+
'    Sys.DynApi.CallFunction "KERNEL32.DLL","CloseHandle",hMutex    \n'+
'End Function                            \n'+
';----------------------------------------------------------------------      \n'+
'<#Module>'

LMFCode=LMFCode.replace(/(;)+/igm,"'")
LMF.AddObject(txt1,'txt1')
LMF.Command(LMFCode)
//------------------------------------------------------------------------
function btn1.onclick()
{
    LMF.FuncRun('CreateMutex',1)
}
//------------------------------------------------------------------------
function window.onbeforeunload()
{
    LMF.FuncRun('CloseHandle',1)
    LMF.Reset()
}
//------------------------------------------------------------------------
</SCRIPT>    
</BODY>
</HTML>

Скрипт-клиент CLIENT.HTA, отслеживающий появление мутекса и читающий данные буфера обмена:

<meta http-equiv=Content-Type content="text/html; charset=windows-1251">
<HTML>
<TITLE>Data Exchange Sample Clent-Окно клиент</TITLE>
<HEAD>
<STYLE type=text/css>
BODY    {background-color: #84c2fb;}
P    {font-family: Lucida Console; font-size: 18px; font-weight: 700}
</STYLE>
<HTA:APPLICATION
    ID="DDEClient"
    APPLICATIONNAME="ddeClient"    
/>
</HEAD>
<BODY SCROLL="NO">
<CENTER><P ID='clientText'></P></CENTER>
<SCRIPT>
/*Клиентский скрипт получающий данные от скрипта-сервера
через буфер обмена после обнаружения в системе мутекса*/
    
//Потребуется зарегистрированная библиотека LangMf.Dll v7.7.0.0
    
var timerCall
    
window.moveTo    (0,300)
window.resizeTo    (500,250)
    
//----------------------------------------------------------------------
var LMFCode=new String
var LMF=new ActiveXObject('Atomix.LangMf')
    
LMFCode=
'<#Module=>                            \n'+
'Const MUTEX_ALL_ACCESS    =&H1f0001            \n'+
'Public hMutex                            \n'+
';---------------------------------------------------------------------    \n'+
'Sub Load(cmdstr)                        \n'+
'End Sub                            \n'+
';----------------------------------------------------------------------      \n'+
'Function WaitMutexMf()                        \n'+
';Попытка открыть мутекс-семафор с заданным именем        \n'+
'WaitMutexMf=Sys.DynApi.CallFunction(    _                                  \n'+
'"KERNEL32.DLL","OpenMutexA", _                                        \n'+
'                MUTEX_ALL_ACCESS, _        \n'+
'                True, _                \n'+
'                "DDEHTA")            \n'+
';и сразу же уничтожить его                    \n'+
'Sys.DynApi.CallFunction "KERNEL32.DLL","CloseHandle",WaitMutexMf\n'+
'End Function                            \n'+
';----------------------------------------------------------------------      \n'+
'Function GetData()                        \n'+
'    GetData=Sys.ClipBoard.GetText()            \n'+
'End Function                            \n'+
';----------------------------------------------------------------------       \n'+
'<#Module>'

LMFCode=LMFCode.replace(/(;)+/igm,"'")
LMF.Command(LMFCode)
waitMutex()
    
//[Проверка на появление в системе мутекса с заданным именем]
//-----------------------------------------------------------------------
function waitMutex()
{
hMutex=LMF.FuncRun('WaitMutexMf',1)
    if (hMutex!=0)
    {
    Str=LMF.FuncRun('GetData',1)
    clientText.innerText=Str
    }
    timerCall=window.setTimeout('waitMutex()',500)
}
//------------------------------------------------------------------------
function window.onclose()
{
    window.clearTimeout(timerCall,100)
    LMF.Reset()
}
//------------------------------------------------------------------------
</SCRIPT>    
</BODY>
</HTML>

Надо запустить оба скрипта одновременно, ввести данные в поле ввода окна сервера и нажать "Отправить".
Проверялось на Win98/Me/XP.
Автор примера - Poltergeyst.

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

2

Re: WSH & HTA: обмен данными между скрипт-процессами

Другой способ аналогичного обмена данными.
Использование буферного файла. В данном случае процесс-клиент занимается отслеживанием факта записи данных в буферный файл со стороны сервера, читает данные и выводит в свое окно.
Потребуются библиотеки LangMf.Dll и AutoItX3.dll.
Скрипт-сервер SERVER.HTA записывает данные в файл:

<meta http-equiv=Content-Type content="text/html; charset=windows-1251">
<HTML>
<TITLE>Data Exchange Sample Server</TITLE>
<HEAD>
<STYLE type=text/css>
BODY    {background-color: #84c2fb;}
INPUT    {font-family: Lucida Console; font-size: 14px; font-weight: 700}
</STYLE>
<HTA:APPLICATION
    ID="DDESRV"
    APPLICATIONNAME="ddeServ"    
/>
</HEAD>

<BODY SCROLL="NO">
<CENTER><INPUT TYPE='TEXT' ID='txt1' SIZE=30></CENTER>
<CENTER><INPUT TYPE='BUTTON' ID='btn1' VALUE='Отправить'></CENTER>
<SCRIPT>
/*Серверный скрипт для записи данных в буферный файл.
Скрипт-клиент отслеживает событие изменения буферного файла
и читает его содержимое*/
    
var scrRun    =new ActiveXObject('Scripting.FileSystemObject')
var wShell    =new ActiveXObject('WScript.Shell')
buferfile    =wShell.CurrentDirectory+'\\ddefile.txt'
    
window.moveTo    (0,300)
window.resizeTo    (500,250)
    
//------------------------------------------------------------------------
function btn1.onclick()
{    
    var stream=scrRun.OpenTextFile(buferfile,2,true)
    stream.Write(txt1.value)
    stream.Close()
}

//------------------------------------------------------------------------
function window.onbeforeunload()
{
    var stream=scrRun.OpenTextFile(buferfile,2,true)
    stream.Write('closeClient')
    stream.Close()
}
//------------------------------------------------------------------------
</SCRIPT>    
</BODY>
</HTML>

Скрипт-клиент CLIENT.JS отслеживает факт записи в буферный файл:

//Клиентский скрипт ожидающий уведомления об изменении буферного файла
//Потребуется зарегистрированная библиотека LangMf.Dll v7.7.0.0
//Потребуется зарегистрированная библиотека AutoItX3.Dll v3.2.0.1
    
//----------------------------------------------------------------------------------
var LMFCode=new String
var LMF        =new ActiveXObject('Atomix.LangMf')
var AutoItX3    =new ActiveXObject('AutoItX3.Control')
var scrRun    =new ActiveXObject('Scripting.FileSystemObject')
var wShell    =new ActiveXObject('WScript.Shell')
curDir=wShell.CurrentDirectory
//----------------------------------------------------------------------------------

LMFCode=
'<#Module=>                                    \n'+
'Const FILE_NOTIFY_CHANGE_LAST_WRITE    =&H10                    \n'+
'Public curDir                            \n'+
'Public hFirst                            \n'+
';-----------------------------------------------------------------------------\n'+
'Sub Load(cmdstr)                        \n'+
'End Sub                            \n'+
';-----------------------------------------------------------------------------\n'+
'Function FirstNotification(curDir)                    \n'+
';Инициация начального объекта проверки файла на факт измемения\n'+
'hFirst    =Sys.DynApi.CallFunction( _                \n'+
'    "KERNEL32.DLL", _                        \n'+
'    "FindFirstChangeNotificationA", _                    \n'+
'        curDir, _                        \n'+
'        1, _                            \n'+
'        FILE_NOTIFY_CHANGE_LAST_WRITE)            \n'+
'End Function                                \n'+
';-----------------------------------------------------------------------------    \n'+
'Function WaitNotification()                        \n'+
';Активация объекта на ожидание изменений файла            \n'+
'    Sys.DynApi.CallFunction  _                    \n'+
'    "KERNEL32.DLL", _                        \n'+
'    "FindNextChangeNotification", _                    \n'+
'    hFirst                                \n'+
';Ожидание .На этой инструкции скрипт встает до появления новой записи\n'+
';в буферный файл со стороны скрипта сервера                \n'+
'    Sys.DynApi.CallFunction _                    \n'+
'        "KERNEL32.DLL", _                    \n'+
'        "WaitForSingleObject", _                    \n'+
'        hFirst,-1                            \n'+
'End Function                                \n'+
';-----------------------------------------------------------------------------    \n'+
'Function CloseNotification()                        \n'+
';Удаление начального объекта проверки файла на факт изменения    \n'+
'    hFirst        =Sys.DynApi.CallFunction( _            \n'+
'    "KERNEL32.DLL", _                        \n'+
'    "FindCloseChangeNotification", _                    \n'+
'    hFirst)                                \n'+
'End Function                                \n'+
';-----------------------------------------------------------------------------    \n'+
'<#Module>'
    LMFCode=LMFCode.replace(/(;)+/igm,"'")
LMF.Command(LMFCode)
LMF.FuncRun('FirstNotification',1,curDir)
//----------------------------------------------------------------------------------
AutoItX3.ToolTip('\nСкрипт клиент: нет сообщений от сервера\n',10,10)
wtNotifier()
//[Рекурсивный вызов ожидания изменений буферного файла]
//----------------------------------------------------------------------------------
function wtNotifier()
{
LMF.FuncRun('WaitNotification',1)
//После освобождения скрипта от ожидания объекта происходит чтение новых данных 
//буферного файла и их вывод в всплывающее окно
WScript.Sleep(300)
var stream=scrRun.OpenTextFile(wShell.CurrentDirectory+'\\ddefile.txt',1)
data=stream.ReadAll()
WScript.Sleep(100)
stream.Close()
    //---------------------------------------------------------------------------
    if (data=='closeClient')
    {
    LMF.FuncRun('CloseNotification',1);
    AutoItX3.ToolTip('');
    return
    }
    //---------------------------------------------------------------------------
AutoItX3.ToolTip('\nСкрипт клиент получил сообщение: '+data+'\n',10,10)
wtNotifier()
}
//----------------------------------------------------------------------------------

Надо запустить оба скрипта одновременно, предварительно разместив их в пустом каталоге, ввести данные в поле ввода окна сервера и нажать "Отправить".
Проверялось на Win98/Me/XP.
Автор примера - Poltergeyst.

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

3

Re: WSH & HTA: обмен данными между скрипт-процессами

В качестве синхронизатора процессов может также выступать разделяемая именованная область памяти, создаваемая одним процессом с помощью CreateFileMapping, и открываемая другим с помощью OpenFileMapping.
Для запуска примеров потребуется библиотека dynwrap.dll.
Скрипт RUN.VBS ожидает появления разделяемой области:

'---------------------------------------------------------------
'Скрипт ожидает создания разделяемой области
'памяти и закрывается при её появлении.
'---------------------------------------------------------------
'Lang. VBScript
'OC Win98/Millenium
'Используется библиотека dynwrap.dll
'---------------------------------------------------------------
'Константы CreateFileMapping/
Const PAGE_READONLY         =2
Const PAGE_READWRITE     =4
Const PAGE_WRITECOPY     =8
Const PAGE_EXECUTE         =16
Const PAGE_EXECUTE_READ     =32
Const SEC_IMAGE        =&H1000000

Public hShare
hShare=0

MsgBox "Скрипт RUN.VBS запущен",vbExclamation,"RUN.VBS"
'---------------------------------------------------------------
'Открытие разделяемой области памяти
Set OpenFileMappingAC=CreateObject("DynamicWrapper")
OpenFileMappingAC.Register _
"KERNEL32.DLL","OpenFileMappingA","i=lls","f=s","r=h"

'---------------------------------------------------------------
While hShare=0
hShare=OpenFileMappingAC.OpenFileMappingA( _
        PAGE_READWRITE, _
        1, _
        "scrmap")
WScript.Sleep(100)
Wend
'---------------------------------------------------------------
WScript.Sleep(200)
MsgBox "Скрипт RUN.VBS остановлен",vbExclamation,"RUN.VBS"
'---------------------------------------------------------------
'Закрытие дескриптора hMap
Set CloseHandleC=CreateObject("DynamicWrapper")
CloseHandleC.Register _
"KERNEL32.DLL","CloseHandle","i=h","f=s","r=l"
CloseHandleC.CloseHandle hShare 
'---------------------------------------------------------------
Set OpenFileMappingAC=Nothing
Set CloseHandleC=Nothing

Скрипт STOP.VBS создает именованную область и является "тормозом" предыдущего скрипта:

'---------------------------------------------------------------
'Скрипт создающий разделяемую область памяти с именем
'SCRMAP.Создание такой области станет сигналом
'для другого скрипта,который закроется при её появлении.
'---------------------------------------------------------------
'Lang. VBScript
'OC Win98/Millenium
'Используется библиотека dynwrap.dll
'---------------------------------------------------------------
'Константы CreateFileMapping/
Const PAGE_READONLY         =2
Const PAGE_READWRITE     =4
Const PAGE_WRITECOPY     =8
Const PAGE_EXECUTE         =16
Const PAGE_EXECUTE_READ     =32
Const SEC_IMAGE        =&H1000000
'---------------------------------------------------------------
Set CreateFileMappingAC=CreateObject("DynamicWrapper")
CreateFileMappingAC.Register _
"KERNEL32.DLL","CreateFileMappingA","i=hlllls","f=s","r=h"
'---------------------------------------------------------------
'Создание разделяемой области
hMap=CreateFileMappingAC.CreateFileMappingA( _
        -1, _
        0, _
        PAGE_READWRITE, _
        0, _
        4096, _
        "scrmap")    
If hMap=0 Then 
MsgBox "Невозможно создать разделяемую область памяти",vbExclamation,"Error"
WScript.Quit
End If
'---------------------------------------------------------------
MsgBox _
"Не закрывайте это сообщение,чтобы блокировать выполнение RUN.vbs", _
vbExclamation, _
"RUN.vbs"
'---------------------------------------------------------------
'Закрытие дескриптора hMap
Set CloseHandleC=CreateObject("DynamicWrapper")
CloseHandleC.Register _
"KERNEL32.DLL","CloseHandle","i=h","f=s","r=l"
CloseHandleC.CloseHandle hShare
'---------------------------------------------------------------
Set CreateFileMappingAC=Nothing
Set CloseHandleC=Nothing

Если RUN.VBS будет запущен первым, то запуск STOP.VBS остановит его выполнение. В ином случае, если оставить открытым сообщение скрипта STOP.vbs, то работа цикла в скрипте RUN.vbs станет невозможной, и он будет сразу же завершать свое выполнение.
Проверялось на Win98/Me/XP.
Автор примеров - Poltergeyst.

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

4

Re: WSH & HTA: обмен данными между скрипт-процессами

Именованная разделяемая область памяти способна работать не только в качестве сигнализатора, но и в качестве буфера чтения-записи со стороны разных скриптовых процессов.
Потребуются библиотеки LangMF.Dll и dynwrap.dll.
Скрипт-сервер MAPSVR.js создает разделяемую область памяти и заполняет её данными, введёнными через InputBox.

//------------------------------------------------------------------
//Скрипт-сервер,создает разделяемую область памяти
//и заполняет её данными
//------------------------------------------------------------------
//Lang.JScript
//Потребуются библиотеки [dynwrap.dll] и [LangMf.dll v7.7.0.0]
//ОС Win98/Millenium
//------------------------------------------------------------------
//Константы CreateFileMapping/
var PAGE_READONLY         =2
var PAGE_READWRITE         =4
var PAGE_WRITECOPY         =8
var PAGE_EXECUTE         =16
var PAGE_EXECUTE_READ     =32
var SEC_IMAGE            =eval('0x1000000')
//------------------------------------------------------------------
//Константы MapViewOfFile/
var FILE_MAP_WRITE=2
var FILE_MAP_ALL_ACCESS     = 0xf001f
var FILE_MAP_READ         =4
//------------------------------------------------------------------

//Вставка кода LangMf
LMFCode= 
'<#Module=shareServer>                     \n'+
';--------------------------------------------------------------\n'+
'Sub Load(cmdstr)                        \n'+
'End Sub                            \n'+
';--------------------------------------------------------------\n'+
'Function InputStrPtr()                        \n'+
'    strData=InputBox("Введите данные:","Скрипт-сервер")    \n'+
'    If strData="" Then                    \n'+
'        InputStrPtr=0                    \n'+
'        Exit Function                    \n'+
'    End If                            \n'+
'InputStrPtr=Sys.cStrPtr(strData & String(255-Len(strData),Chr(32)))\n'+
'End Function                            \n'+
';--------------------------------------------------------------\n'+
'Function WaitMessage()                        \n'+
'MsgBox "Не закрывая это сообщение,запустите скрипт-клиент.", _    \n'+
'    vbExclamation+vbSystemModal, _            \n'+
'    "Скрипт сервер"                    \n'+
'End Function                            \n'+
';--------------------------------------------------------------\n'+
'<#Module>'
    
    LMFCode=LMFCode.replace(/(;)+/igm,"'")
    var LMF    =new ActiveXObject("Atomix.LangMF")
    LMF.Command(LMFCode)

//[Выделение разделяемой именованной области памяти]
//------------------------------------------------------------------
    WScript.Sleep(100)
CreateFileMappingAC=new ActiveXObject("DynamicWrapper")
CreateFileMappingAC.Register(
    "KERNEL32.DLL","CreateFileMappingA","i=hlllls","f=s","r=h")

hMap=CreateFileMappingAC.CreateFileMappingA(    
            -1,
            0,
            PAGE_READWRITE,
            0,
            4096,
            "scriptmap")    

//[Мэппирование выделенной области]
//------------------------------------------------------------------
    WScript.Sleep(100)
MapViewOfFileC=new ActiveXObject("DynamicWrapper")
MapViewOfFileC.Register(
    "KERNEL32.DLL","MapViewOfFile","i=hllll","f=s","r=h")

hView=MapViewOfFileC.MapViewOfFile(
            hMap,
            FILE_MAP_WRITE,
            0,
            0,
            0)

//[Ввод строковых данных(не более 255 симв.)]
//[Получение соответствующего указателя]
//------------------------------------------------------------------
    WScript.Sleep(100)
    sPtr=LMF.FuncRun('InputStrPtr',1)
    WScript.Sleep(100)
    if (!sPtr){releaseMap();WScript.Quit(-1)}

//[Перемещение данных в разделяемую область памяти]
//------------------------------------------------------------------
var RtlMoveMemoryC=new ActiveXObject("DynamicWrapper")
RtlMoveMemoryC.Register(
    "KERNEL32.DLL","RtlMoveMemory","i=lll","f=s","r=l")

hRes=RtlMoveMemoryC.RtlMoveMemory(hView,sPtr,255)

//------------------------------------------------------------------
    WScript.Sleep(100)
    LMF.FuncRun('WaitMessage',1)
    WScript.Sleep(100)
    releaseMap()
//------------------------------------------------------------------
//[Освобождение дескрипторов]
//------------------------------------------------------------------
function releaseMap()
{
    UnmapViewOfFileC=new ActiveXObject("DynamicWrapper")
    UnmapViewOfFileC.Register(
        "KERNEL32.DLL","UnmapViewOfFile","i=h","f=s","r=l")

    UnmapViewOfFileC.UnmapViewOfFile(hView)
    //---------------------------------------------------------
    CloseHandleC=new ActiveXObject("DynamicWrapper")
    CloseHandleC.Register(
        "KERNEL32.DLL","CloseHandle","i=h","f=s","r=l")

    CloseHandleC.CloseHandle(hMap)
    LMF.Reset()
    WScript.Quit()
}
//------------------------------------------------------------------
//Poltergeyst

Скрипт-клиент MAPCLN.js открывает разделяемую область памяти и читает данные.

//------------------------------------------------------------------
//Скрипт-клиент,открывает разделяемую область памяти
//и читает данные.
//------------------------------------------------------------------
//Lang.JScript
//Потребуются библиотеки [dynwrap.dll] и [LangMf.dll v7.7.0.0]
//ОС Win98/Millenium
//------------------------------------------------------------------
//Константы CreateFileMapping/
var PAGE_READONLY         =2
var PAGE_READWRITE         =4
var PAGE_WRITECOPY         =8
var PAGE_EXECUTE         =16
var PAGE_EXECUTE_READ         =32
var SEC_IMAGE            =eval('0x1000000')
//------------------------------------------------------------------
//Константы MapViewOfFile/
var FILE_MAP_ALL_ACCESS     = 0xf001f
var FILE_MAP_READ         =4
var FILE_MAP_WRITE        =2
//------------------------------------------------------------------
var CP_ACP=0

//Вставка кода LangMf
LMFCode= 
'<#Module=shareClient>                    \n'+
'Public strStr                            \n'+
';--------------------------------------------------------------\n'+
'Sub Load(cmdstr)                        \n'+
'End Sub                            \n'+
';--------------------------------------------------------------\n'+
'Function GetStrPtr()                        \n'+
'    strStr=String(255,Chr(32))                \n'+
'    GetStrPtr=Sys.cStrPtr(strStr)                \n'+
'End Function                            \n'+
';--------------------------------------------------------------\n'+
'Function GetStr()                        \n'+
'strStr=Sys.RTrimS(strStr)                    \n'+
'    MsgBox "Принято сообщение: " & strStr, _        \n'+
'    vbInformation+vbSystemModal,"Скрипт клиент"        \n'+
'GetStr=strStr                            \n'+
'End Function                            \n'+
';--------------------------------------------------------------\n'+
'<#Module>'
    
    LMFCode=LMFCode.replace(/(;)+/igm,"'")
    var LMF    =new ActiveXObject("Atomix.LangMF")
    LMF.Command(LMFCode)

//[Открытие разделяемой области памяти]
//------------------------------------------------------------------
    WScript.Sleep(100)
CreateFileMappingAC=new ActiveXObject("DynamicWrapper")
CreateFileMappingAC.Register(
    "KERNEL32.DLL","CreateFileMappingA","i=hlllls","f=s","r=h")

hShare=CreateFileMappingAC.CreateFileMappingA(    
            -1,
            0,
            PAGE_READWRITE,
            0,
            4096,
            "scriptmap")    

//Если область уже создана скриптом сервером,то будет получен
//дескриптор этой,уже существующей области.
//[Мэппирование полученного участка памяти]
//------------------------------------------------------------------
    WScript.Sleep(100)
MapViewOfFileC=new ActiveXObject("DynamicWrapper")
MapViewOfFileC.Register(
    "KERNEL32.DLL","MapViewOfFile","i=hllll","f=s","r=h")

hShareView=MapViewOfFileC.MapViewOfFile(    
        hShare,
        FILE_MAP_ALL_ACCESS,
        0,
        0,
        0)

//[Получение указателя на строку-болванку]
//------------------------------------------------------------------
    WScript.Sleep(100)
    sPtr=LMF.FuncRun('GetStrPtr',1)
    WScript.Sleep(100)

//[Копирование содержимого мэппированного участка в строку-болванку]
//------------------------------------------------------------------
var memcpyC    =new ActiveXObject("DynamicWrapper") 
memcpyC.Register("msvcrt.dll","memcpy","f=c","i=lll","r=l")
    WScript.Sleep(100)
    pDest=LMF.FuncRun("GetStrPtr",1)
    res=memcpyC.memcpy(pDest,hShareView,255) 

//[Возврат данных]
//------------------------------------------------------------------
    WScript.Sleep(100)
    strData=LMF.FuncRun('GetStr',1)
    WScript.Sleep(100)
    LMF.Reset()
    WScript.Quit()
//------------------------------------------------------------------
//Poltergeyst

Сначала надо запустить скрипт-сервер, указать данные в поле ввода, и после появления сообщения о запуске скрипта-клиента, запустить
скрипт-клиент, который должен воспроизвести данные, оставленные сервером.
Проверялось на Win98/Me/XP.
Автор примеров - Poltergeyst, благодарность за разъяснения - YMP.

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

5

Re: WSH & HTA: обмен данными между скрипт-процессами

Обмен данными между скриптами можно реализовать через сокеты. Для работы примера понадобится зарегистрированный «mswinsck.ocx» (поставляется вместе с MS Office, VB6).

В примере показан обмен данными между двумя скриптами. Одним из них является сервер [Server.vbs], другой — клиент [Client.vbs]. Сначала запустите «сервер», затем — «клиента».

[Server.vbs]

Dim Winsock
Set Winsock = WScript.CreateObject("MSWinsock.Winsock")

Dim bClose
  bClose = True

Sub Winsock_ConnectionRequest(reqId)
  Winsock.Close()
  Winsock.Accept(reqId)
End Sub

Sub Winsock_DataArrival(bytTotal)
Dim Data
  Data = ""
  Winsock.GetData Data, 8, bytTotal
  WScript.Echo("[Сервер] Получено: "+Data)
  Winsock.SendData("Привет от сервера :) ")
End Sub

Sub Winsock_Error (number, desc, sCode, src, help, helpctx, cancelDisplay)
  WScript.Echo("[Сервер] Ошибка: "+desc)
  bClose = False
End Sub

Sub Winsock_Close
  'WScript.Echo("Соединение закрыто.")
  bClose=False
End Sub

  WScript.ConnectObject Winsock,"Winsock_"
   
  Winsock.LocalPort = 6789
  Winsock.Protocol = 0
  Winsock.Listen
   
  Do While (bClose) 
  WScript.Sleep(500)
  Loop

[Client.vbs]

   
Dim bConnected
Dim bSent
  bConnected=false
  bSent=false

Dim bDataReceived
  bDataReceived=false

Dim Winsock
Set Winsock=WScript.CreateObject("MSWinsock.Winsock")

Sub Winsock_Connect
  bConnected=true
End Sub

Sub Winsock_SendComplete
  bSent=true
End Sub

Sub Winsock_DataArrival(bytTotal)
Dim str
  Winsock.GetData str,8
  WScript.Echo "[Клиент] Получено: " & str
  bDataReceived=true
End Sub

  WScript.ConnectObject Winsock,"Winsock_"
  Winsock.Connect "127.0.0.1", 6789
  Do While Not (bConnected)
  WScript.Sleep 500
  Loop
   
  Winsock.SendData "Привет, сервер!"
   
  Do While Not(bDataReceived)
  WScript.Sleep 500
  Loop
  Winsock.Close

Полную документацию по Winsock Control можно найти тут.