1 (изменено: Xameleon, 2017-01-17 19:43:15)

Тема: WSH: обмен данными и объектами между скриптами — 2

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

Преимущества:
1) Можно обмениваться любыми типами данных (доступных скриптам) между процессами. В том числе и объектами.
2) Отсутствие надобности создавать лишние процессы.
3) Всё делается встроенными средствами Windows. Не нужны посторонние Activex.

Обмен данными осуществляется через экземпляр класса - GlobalContainer.
Для начала используется метод Open("name"), чтобы открыть уже готовый либо создать новый контейнер, в котором будут храниться данные.
Это позволит использовать независимые хранилища для разных приложений.
Для передачи и получения данных используются соответсвенно 2 метода PutProperty(name,value) и GetProperty(name).
Ниже приведён пример из 2-ух vbs скриптов. В каждом из которых присутствует класс.
Первым запускается 1.vbs. Вторым 2.vbs.

Во второй скрипт, в качестве примера, передаётся значение введённое пользователем + созданный в первом скрипте объект Scripting.FileSystemObject.

Отдаю на тестирование. Интересно - как будет работать у Вас.

1.vbs

Dim gCon, fso
Set gCon = New GlobalContainer
gCon.Open "storage"
gCon.PutProperty "test",InputBox("Введите значение для глобальной переменной ""test"".")
set fso = CreateObject("Scripting.FileSystemObject")
gCon.PutProperty "fso",fso

MsgBox "Значение переменных установлено. Запустите второй скрипт, не закрывая окна."

Class GlobalContainer
    Private wnd, owner
    Sub Open(name)
        For Each wnd in CreateObject("Shell.Application").Windows
            if Instr(1,wnd.GetProperty("container_name"),name) = 1 Then Exit Sub
        Next
        owner = True
        Set wnd = GetObject("new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}")
        wnd.PutProperty "container_name", name
    End Sub
    
    Sub PutProperty(name, value)    
        wnd.PutProperty name, value
    End Sub
    
    Function GetProperty(name)
        On Error Resume Next
        if IsObject(wnd.GetProperty(name)) Then
            Set GetProperty = wnd.GetProperty(name)
        Else
            GetProperty = wnd.GetProperty(name)
        End if
    End Function

    Private Sub Class_Terminate()
        On Error Resume Next
        if owner Then wnd.Quit()
    End Sub
End Class

2.vbs

Dim gCon
Set gCon = New GlobalContainer
gCon.Open "storage"
MsgBox "Значение переменной ""test"": " & gCon.GetProperty("test") ,vbInformation
MsgBox "Тип переменной ""fso"": " & TypeName(gCon.GetProperty("fso")),vbInformation

Class GlobalContainer
    Private wnd, owner
    Sub Open(name)
        For Each wnd in CreateObject("Shell.Application").Windows
            if Instr(1,wnd.GetProperty("container_name"),name) = 1 Then Exit Sub
        Next
        owner = True
        Set wnd = GetObject("new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}")
        wnd.PutProperty "container_name", name
    End Sub
    
    Sub PutProperty(name, value)    
        wnd.PutProperty name, value
    End Sub
    
    Function GetProperty(name)
        On Error Resume Next
        if IsObject(wnd.GetProperty(name)) Then
            Set GetProperty = wnd.GetProperty(name)
        Else
            GetProperty = wnd.GetProperty(name)
        End if
    End Function

    Private Sub Class_Terminate()
        On Error Resume Next
        if owner Then wnd.Quit()
    End Sub
End Class

23.09.2011: (!) Обнаружена и исправлена ошибка при выгрузке класса. Экземпляр окна оставался в памяти после выгрузки.

20.04.2013: (!) Метод поиска контейнера изменён. Теперь поиск осуществляется по устанавливаемому Property "container_name".

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

2

Re: WSH: обмен данными и объектами между скриптами — 2

Прошу в заголовке проставить скриптовый язык для тех, кто не в теме.

3

Re: WSH: обмен данными и объектами между скриптами — 2

Виноват. Давно на форум не заглядывал.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

4

Re: WSH: обмен данными и объектами между скриптами — 2

Интересный способ

5

Re: WSH: обмен данными и объектами между скриптами — 2

Сам не ожидал. ) Как ни странно - создаваемый объект {C08AFD90-F2A1-11D1-8455-00A0C91F3880} кроме всего прочего имеет действующий hWnd, что в принципе тоже можно попользовать. )

2 all & VSVLAD: Скрипт нормально пашет ? Сбоев нет ? Интересует на чём проверенно. Т.к предположительно на разных ОС может давать разный результат. Я пока проверил на XP и Windows 7 Ultimate x64.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

6 (изменено: VSVLAD, 2011-03-09 22:07:36)

Re: WSH: обмен данными и объектами между скриптами — 2

Я как понял класс создаёт экземпляр WebBrowser, а внутри него имеются методы для записи и чтения свойств.
Проверял на: XP Professional SP3, IE8.0.6001 - всё Окей

--
Проверил поиском по реестру в поисках этого CLSID - и не нашлось. Магия

7 (изменено: Xameleon, 2011-03-09 22:09:00)

Re: WSH: обмен данными и объектами между скриптами — 2

Обнаружил интересную, но вполне логичную особенность. Объект хранит в себе данные, даже после завершения всех скриптов. Практически как буфер обмена. По крайней мере на Windows 7 Ultimate так происходит. Не заметил - есть ли этот эффект на XP.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

8 (изменено: Xameleon, 2011-03-09 22:13:16)

Re: WSH: обмен данными и объектами между скриптами — 2

VSVLAD пишет:

Я как понял класс создаёт экземпляр WebBrowser, а внутри него имеются методы для записи и чтения свойств.
Проверял на: XP Professional SP3, IE8.0.6001 - всё Окей

--
Проверил поиском по реестру в поисках этого CLSID - и не нашлось. Магия

Магия ) Она самая. Только что и я проверил. Действительно его нет в реестре. Видимо это чудо ))). Ну ладно. Не буду раскрывать всех фокусов . А то эффект пропадёт )).

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

9 (изменено: Евген, 2011-03-25 15:27:23)

Re: WSH: обмен данными и объектами между скриптами — 2

Судя по всему этот CLSID не прописанный в реестре ниукого, как-то очень похож на объект IE. Сегодня нагуглил перечисление глаголов этого объекта, вот код

Option Explicit
Class Class1
Dim objIE,Verb

Sub Class_Initialize
Set objIE=GetObject("new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}")
objIE.Navigate2 0
Do While objIE.Busy Or objIE.ReadyState<>4
  WScript.Sleep 100
Loop
For Each Verb In objIE.Document.Application.NameSpace(strPath).Self.Verbs
Wscript.Echo Verb.Name
Next 
objIE.Quit 
End Sub

Sub Class_Terminate
On Error Resume Next
objIE.Quit
End Sub
End Class

Dim x,strPath

strPath="c:\util"

Set x=New Class1
Времени не хватает... :-(

10

Re: WSH: обмен данными и объектами между скриптами — 2

Следующий код

var x = GetObject("new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}");
WScript.Echo(x);

отзывается так:

Microsoft Internet Explorer

( 2 * b ) || ! ( 2 * b )

11

Re: WSH: обмен данными и объектами между скриптами — 2

Я думаю этот CLSID принадлежит ActiveX компоненту WebBrowser, который также как ActiveX компонент Internet Explorer находятся в библиотеке shdocvw.dll, а начиная с IE 7 перенеслись в ieframe.dll

12 (изменено: Евген, 2011-03-10 11:50:12)

Re: WSH: обмен данными и объектами между скриптами — 2

Rumata пишет:

отзывается так:

Microsoft Internet Explorer

Windows 7 Ultimate x64
отзывается как

Проводник Windows

какой то аморфный объект...
нужна ясность...

Времени не хватает... :-(

13 (изменено: Xameleon, 2011-03-10 12:07:00)

Re: WSH: обмен данными и объектами между скриптами — 2

Товарищи, видимо пришло время раскрыть мои карты, раз Вы занялись таким подробным исследованием.

Этот объект я случайно обнаружил, "ковыряя" библиотеку shdocvw.dll через утилитку oleview (у кого нет - можете загрузить тут http://www.microsoft.com/downloads/en/d … laylang=en). Библиотеку shdocvw.dll, использует Internet Explorer для организации своей объектной модели. Собственно через неё мы и получаем возможности управления браузером. Ковырял я этот объект по причине поиска возможности из скрипта регистрировать окна в коллекции ShellWindows без создания посторонних процессов. Тест показал, что этот объект мне подходит.

Объект, который создаётся "волшебным способом" это один из Creatable (создаваемых) объектов этой библиотеки, именуемый ShellBrowserWindow. Почему его классида нет в реестре и как он при этом создаётся, если его нет - для меня тоже пока что остаётся загадкой. ) Информации на сайте мелкомягких о нём я не нашёл. Но можно поизучать его вручную.

Т.к он наследует интерфейс от WebBrowser2, то его методы можно посмотреть тут. (Либо через oleview. )

http://msdn.microsoft.com/en-us/library … s.85).aspx

[
  uuid(C08AFD90-F2A1-11D1-8455-00A0C91F3880),
  helpstring("Shell Browser Window."),
  hidden
]
coclass ShellBrowserWindow {
    [default] interface IWebBrowser2;
    interface IWebBrowserApp;
    [default, source] dispinterface DWebBrowserEvents2;
    [source] dispinterface DWebBrowserEvents;
};

Вот собственно всё, что пока известно мне. Но подозреваю, что могут всплыть и новые подробности и возможности.

P.S Копаю в сторону его hWnd. Уж очень интересно - где же он окошко создаёт.

Set ShellBrowserWindow = GetObject("new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}")
MsgBox ShellBrowserWindow.hwnd
ShellBrowserWindow.Visible = True

--
При попытке сделать его Visible - показывает окно обычного проводника. Занятно...

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

14

Re: WSH: обмен данными и объектами между скриптами — 2

Xameleon пишет:

... Отдаю на тестирование...

Проверено на Win 2003 R2/2008/7 Pro. Везде работает, притом одинаково.

15

Re: WSH: обмен данными и объектами между скриптами — 2

Dmitrii пишет:
Xameleon пишет:

... Отдаю на тестирование...

Проверено на Win 2003 R2/2008/7 Pro. Везде работает, притом одинаково.

Благодарю. Очень признателен.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

16

Re: WSH: обмен данными и объектами между скриптами — 2

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

Set ShellWindows = CreateObject("Shell.Application").Windows

Кажись, так, помнится…

Не пришло ещё время для Коллекции, а?!

17

Re: WSH: обмен данными и объектами между скриптами — 2

2 alexii:
1) Это да. Ну перезапуск - редкий случай. )
2) Для коллекции ? Думаю пока рано. Ещё JSman не сказал своё слово. ) Как он в JS перегонит, так наверное можно.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

18

Re: WSH: обмен данными и объектами между скриптами — 2

Кстати в js не работает. Но дождемся независимой экспертизы (-:

( 2 * b ) || ! ( 2 * b )

19 (изменено: JSman, 2011-03-11 00:14:50)

Re: WSH: обмен данными и объектами между скриптами — 2

Здравствуйте! Представляю черновую версию на JScript.

function GlobalObject(Name)
{    
    if(!Name)Name="GlobalObject";
    if (this.Window = this.FindWindow(Name))null;else
    {
        this.Window = GetObject("new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}");
        this.Window.StatusText = Name;
    }
}

GlobalObject.prototype = 
{
    FindWindow : function (Name)
    {
        var  ShellWindows=(new ActiveXObject("Shell.Application")).Windows();
        for (var i=ShellWindows.Count; --i>=0;)
        if (ShellWindows.Item(i).StatusText && ShellWindows.Item(i).StatusText.indexOf(Name)!=-1) 
        return ShellWindows.Item(i);
    },
    
    GetProperty: function (Name)
    {
        return this.Window.GetProperty(Name);
    },
    
    SetProperty: function (Name, Value)
    {
        this.Window.PutProperty(Name, Value);
    }

}

Примеры связи двух процессов

Файл номер 1.

var g = new GlobalObject();
g.SetProperty("Host", this);
while (1) WScript.Sleep(10);

Файл номер 2.

var g = new GlobalObject(), host;
if (host = g.GetProperty("Host")) 
{WScript.Echo("Связь установлена. Теперь закроем чужой процесс.");host.WScript.Quit();} else WScript.Echo("Связь не установлена")

Запускаем сначала первый файл, потом второй.

20

Re: WSH: обмен данными и объектами между скриптами — 2

Rumata пишет:

Кстати в js не работает. Но дождемся независимой экспертизы (-:

У JSman-а не может не работать. )))

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

21

Re: WSH: обмен данными и объектами между скриптами — 2

Будете дополнять эту тему: WSH & HTA: обмен данными между скрипт-процессами или новую заведёте?

22

Re: WSH: обмен данными и объектами между скриптами — 2

Xameleon пишет:
Rumata пишет:

Кстати в js не работает. Но дождемся независимой экспертизы (-:

У JSman-а не может не работать. )))

Опечатался. [i] вместо .Item(i)

( 2 * b ) || ! ( 2 * b )

23

Re: WSH: обмен данными и объектами между скриптами — 2

Поправил немного свой код. Добавил открытие контейнера для хранения переменных под определённым именем. OpenContainer
2 alexii: Ммм. Наверное лучше допишем и в коллекцию перенесём. )

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

24

Re: WSH: обмен данными и объектами между скриптами — 2

Предлагаю отдельную тему завести коллеге Xameleon

25

Re: WSH: обмен данными и объектами между скриптами — 2

Можно, например, завести такую: «WSH: обмен данными и объектами между скриптами — 2». Немного будет отличаться заголовок, но это не страшно: кросс-посты я потом добавлю.