Тема: 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".