Re: WSH: обмен данными и объектами между скриптами — 2
omegastripes
оберните ADODB.Recordset в функции, их вызывайте удаленно.
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Серый форум → Общение → Windows Script Host, HTA (VBScript, JScript) → WSH: обмен данными и объектами между скриптами — 2
omegastripes
оберните ADODB.Recordset в функции, их вызывайте удаленно.
Крутая вещь. При попытке доступа к объекту уже завершенного процесса происходит ошибка "Компьютер удаленного сервера не существует..". Если это работает по удаленке, вообще жесть!:)
Что-то давно я не постил ничего на форуме. Случилось так, что мне опять потребовался код обмена данными между процессами. Открыл эту тему на форуме и понял, что есть что поменять и доработать. В текущей реализации не было:
1) встроенной возможности работать с событиями при изменении данных в хранилище
2) нормального метода проверки существования получателя
3) нормального контроля за созданными окнами (в случае аварийного закрытия скрипта в памяти оставались инстансы окон)
Решил переделать и доработать.
Изменения:
1) Переименовал объект в Shell.Connector. Это название показалось мне более логичным в виду внесённых изменений.
2) Собрал функционал в компонент WSC для удобства использования в разных языках JS / VBS и т.п. Изменил принцип работы.
Методы:
postMessage(connectorId,data) - Отправка сообщения коннектору получателю
connectorId <in> [String] - Идентификатор коннектора получателя
data <in> [String] - Данные для передачи
connect(connectorId) - Метод для проверки доступности указанного коннектора
connectorId <in> [String] - Идентификатор проверяемого коннектора
Свойства:
id <out> [String] - Идентификатор текущего коннектора
onmessage <in> [Object] - Задаёт ссылку на объект обратного вызова (функцию).
Во время срабатывания события в функцию/метод обратного вызова передаёт 2 параметра (connectorId, data)
3) Идентификатор коннектора генерируется как уникальный GUID и задаётся внутри самого объекта
4) Вместо использования отдельных инстансов Shell Browser Window используется только один для всех коннекторов. Благодаря этому при падении скрипта / закрытии процесса в памяти не остаётся инстансов открытых окон кроме одного, обеспечивающего работу коннекторов.
UPD: 28.01.2021 - Оптимизировал код. Убрал лишние вызовы и функции.
UPD: 10.02.2021 - Исправил код преобразования передаваемых данных.
UPD: 20.02.2021 - Залил код на GitHub ссылка
UPD: 20.02.2021 - Залил код на GitHub ссылка
Спасибо огромное!
Есть необходимость сохранять в window свои данные, аналогично этому:
window.putProperty(window.hWnd,'Shell.Connector');
т.е. иметь возможность сохранять свои данные для всех "коннекторов".
Соответственно, можно ли в putProperty передавать произвольные параметры?
yyk, в принципе, да. Но я потихоньку ушёл от этой идеи. Так как тогда нужно контролировать актуальность ссылок на объекты. Поэтому перешёл на передачу данных через сериализованный JSON. А теперь и вовсе перебрался на использование NTFS стримов.
Примерчик тут
В JScript не соображаю, пробую запустить этот код.
На строке:
this.appWindow = GlobalContainer.getInstance(signature);
Объект не поддерживает это свойство или метод
Запускаю файлом JS в виндовс 10 64бит.
ап: Пардон туплю, всё работает. Код для примера надо запускать после основного кода.
fkhlamingo, думаю вам проще будет разобраться в готовом примере, который я выложил на GitHub - ссылка.
ап: Пардон туплю, всё работает. Код для примера надо запускать после основного кода.
Разобрался.
думаю вам проще будет разобраться в готовом примере, который я выложил на GitHub
Спасибо за ответ, подскажите в каком файле смотреть.
Кстати в другой теме обсуждаем с вами Shell.Application, так вот этот код у меня добавляет окно в коллекцию. На досуге ещё потестирую, но надеюсь решить свой вопрос этим методом.
На GitHub я выложил несколько примеров:
1) Сам доработанный коннектор (с поддержкой события прихода данных) и примеры - https://github.com/diqipib/Shell.Connector
2) Применение коннектора в Worker-ах - https://github.com/diqipib/WSH-Worker
Xameleon
Большое вам спасибо, очень помогли!
с поддержкой события прихода данных
Опередили мой вопрос, буду разбираться.
хочу поднять ветку, альтернативным вариантом.
При этом этот вариант более универсален. Т.е. не только для "передачи", но и для применении например vbscript функции API. Как бы из vbscript можно будет и диски посекторно форматировать.
Метод такой.
Берём установочный диск VB6. Устанавливаем. Апгрейтим до SP3, но можно и без него.
После этого, забираем из директории такие , все файлы от VB6.
И кладём их в отд. каталог, типа "portable".
После этого откр блокнот и пишем туда строки.
файл 1.reg
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Licenses]
@="Licensing: Copying the keys may be a violation of established copyrights."
[HKEY_CLASSES_ROOT\Licenses\096EFC40-6ABF-11cf-850C-08002B30345D]
@="knsgigmnmngnmnigthmgpninrmumhgkgrlrk"
[HKEY_CLASSES_ROOT\Licenses\12B142A4-BD51-11d1-8C08-0000F8754DA1]
@="aadhgafabafajhchnbchehfambfbbachmfmb"
[HKEY_CLASSES_ROOT\Licenses\190B7910-992A-11cf-8AFA-00AA00C00905]
@="gclclcejjcmjdcccoikjlcecoioijjcjnhng"
[HKEY_CLASSES_ROOT\Licenses\1F3D5522-3F42-11d1-B2FA-00A0C908FB55]
@="gcfjdjecpchcncdjpdejijgcrdoijjfcieod"
[HKEY_CLASSES_ROOT\Licenses\4D553650-6ABE-11cf-8ADB-00AA00C00905]
@="gfjmrfkfifkmkfffrlmmgmhmnlulkmfmqkqj"
[HKEY_CLASSES_ROOT\Licenses\4F86BADF-9F77-11d1-B1B7-0000F8753F5D]
@="iplpwpnippopupiivjrioppisjsjlpiiokuj"
[HKEY_CLASSES_ROOT\Licenses\57CBF9E0-6AA7-11cf-8ADB-00AA00C00905]
@="aahakhchghkhfhaamghhbhbhkbpgfhahlfle"
[HKEY_CLASSES_ROOT\Licenses\6000720D-F342-11D1-AF65-00A0C90DCA10]
@="kefeflhlhlgenelerfleheietfmflelljeqf"
[HKEY_CLASSES_ROOT\Licenses\72E67120-5959-11cf-91F6-C2863C385E30]
@="ibcbbbebqbdbciebmcobmbhifcmciibblgmf"
[HKEY_CLASSES_ROOT\Licenses\74872840-703A-11d1-A3AF-00A0C90F26FA]
@="mninuglgknogtgjnthmnggjgsmrmgniglish"
[HKEY_CLASSES_ROOT\Licenses\74872841-703A-11d1-A3AF-00A0C90F26FA]
@="klglsejeilmereglrfkleeheqkpkelgejgqf"
[HKEY_CLASSES_ROOT\Licenses\9DF1A470-BA8E-11D0-849C-00A0C90DC8A9]
@="cchcqjejhcgcqcfjpdfcdjkckiqikchcojpd"
[HKEY_CLASSES_ROOT\Licenses\9E799BF1-8817-11cf-958F-0020AFC28C3B]
@="uqpqnqkjujkjjjjqwktjrjkjtkupsjnjtoun"
[HKEY_CLASSES_ROOT\Licenses\A133F000-CCB0-11d0-A316-00AA00688B10]
@="cibbcimbpihbbbbbnhdbeidiocmcbbdbgdoc"
[HKEY_CLASSES_ROOT\Licenses\C4145310-469C-11d1-B182-00A0C922E820]
@="konhqhioohihphkouimonhqhvnwiqhhhnjti"
[HKEY_CLASSES_ROOT\Licenses\CDE57A55-8B86-11D0-b3C6-00A0C90AEA82]
@="ekpkhddkjkekpdjkqemkfkldoeoefkfdjfqe"
[HKEY_CLASSES_ROOT\Licenses\D015B071-D2ED-11d0-A31A-00AA00688B10]
@="gjdcfjpcmjicjcdcoihcechjlioiccechepd"
[HKEY_CLASSES_ROOT\Licenses\DC4D7920-6AC8-11cf-8ADB-00AA00C00905]
@="iokouhloohrojhhhtnooiokomiwnmohosmsl"
[HKEY_CLASSES_ROOT\Licenses\ED4B87C4-9F76-11d1-8BF7-0000F8754DA1]
@="knlggnmntgggrninthpgmnngrhqhnnjnslsh"
[HKEY_CLASSES_ROOT\Licenses\F4FC596D-DFFE-11CF-9551-00AA00A3DC45]
@="mbmabptebkjcdlgtjmskjwtsdhjbmkmwtrak"
И сохраняем его как 1.reg.
Теперь главное. Этот рег файл для регистрации лицензий на все OCX которые есть у VB6. Вообще на девственной машине этой ветки и в помине нет. её пишет при установки VB6. Без этой лицензии ни один у вас COM его объект не запустится и сама VB6 естественно тоже.
Папка та "portable", занимает 11 мегов. Там вроде 2-3 файла как мне показалось позже лишние.
Это не суть.
1- регистрим файлом reg.
2- в директории "portable" запускаем файл VB6.EXE, с ПРАВАМИ АДМИНА. иначе никак. Будет ругаться. С правами, потому что ОН у себя где то метит путь к подчёркнутой мной (см скрин) библиотеки OLB. И всё. после этого можете запускать его как угодно. Он даже не поперхнётся и будет вам компилить даже всё привсё.
Теперь по теме.
Этот VB6 имеет в себе возможность делать классы и декларировать API функции.
При этом , т.к. он работает с ними в онлайн - рунтайм-е, то вы запуская его в vbscrit-е можете в онлайне менять любые API. А т.к. у vba6.dll есть хитрая функция
'------------- превращение строки в код
Private Declare Function EbExecuteLine Lib "vba6.dll" (ByVal StringToExec As Long, ByVal Any1 As Long, ByVal Any2 As Long, ByVal CheckOnly As Long) As Long
то с помощью её, вы можете запускать в онлайне прям из блокнота (например из HTA формы), любую какую вам нужно штуку. например, я запускал там "open file...." Т.е. изготавливал и читал файл на диске. Есть одно НО с этой функцией.
1- она выполняется только в памяти, и поэтому отделена от саvой COM библиотеки класса (потом поясню). Т.е. всё что там эта строка сделает она , не может получить от внутренней страницы кода загруженного класса в VB6 ничего. Хотя.. можно конечно подумать.
2-в VB6 принято при объявлении переменно её обозначать тип. В этой строке это нельзя делать. Т.е. там объявляются все переменные как в VBS скрипте, без типа.
3- условие. Это никаких переносов строк. Т.е. если писать длинный код в блокноте, как обычный код по строкам, то в конце каждой строки лучше ставить
"VbNewLine"
потом ч помощью функции подмены
"VbNewLine"
на
":"
получаем "индийский код", в одну линию и отсылаем её в COM VB6. VB6 при удачном исполнении кода отдаёт (API) цифру "-1", если плохо то "0". Отдаёт она в Vbscript (кто её давал код).
..
1-Короче, этот метод точно имеет многопоточность и не независимые потоки. Вы можете запустить из VBS сколько угодно этих классов.
2- он не нуждается в изучении других языков.
3- может запускать в онлайне любые API вина...
Теперь про класс.
в блокноте пишем.
Это будет файл класса.
Net_Call.cls
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
Persistable = 0 'NotPersistable
DataBindingBehavior = 0 'vbNone
DataSourceBehavior = 0 'vbNone
MTSTransactionMode = 0 'NotAnMTSObject
END
Attribute VB_Name = "Net_Call"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
'------- от сюда начинается ваш код
'-----------------------------
'-----------------------------
'-----------------------------
Option Explicit
'Option Strict Off
Private Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Long
Private Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'Private Declare Function GetTempPath Lib "kernel32" Alias "GetTempPathA" (ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long
'------------- превращение строки в код
Private Declare Function EbExecuteLine Lib "vba6.dll" (ByVal StringToExec As Long, ByVal Any1 As Long, ByVal Any2 As Long, ByVal CheckOnly As Long) As Long
'------ внешние функции API
Public Function ReadINIKey(Section As String, KeyName As String, ByVal FileName As String) As String
Dim retval As String
retval = String(255, Chr(0))
ReadINIKey = Left(retval, GetPrivateProfileString(Section, KeyName, "", retval, Len(retval), FileName))
End Function
Public Function WriteInIKey(Section As String, KeyName As String, ByVal KeyValue As String, ByVal FileName As String) As String
Dim AA_ As Long
AA_ = WritePrivateProfileString(Section, KeyName, KeyValue, FileName)
WriteInIKey = CStr(AA_)
End Function
Public Function Call_code(ByVal Code As String) As String
Dim a_1 As Long
ab = 67
a_1 = EbExecuteLine(StrPtr(Code), 0&, 0&, False) = 0
Call_code = CStr(a_1)
End Function
'-------- срабатывает при закрытии
Private Sub Class_Terminate()
End Sub
============
В этом классе я уже задиклорировал помимо строковой функции ещё и другие API (ini файл и темп директорию).
это файл проекта для VB6. Он будет загружать и запускать в VB6.exe класс (файл класса который выше), который при рунтайме вы будите в vbscrit-е его объявлять. Как будто он уже скомилирован в DLL.
файл Net_Call_API.vbp он основной на запуск. Он тащит за собой все файлы проекта.
Type=OleDll
Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#C:\Windows\SysWOW64\stdole2.tlb#OLE Automation
Class=Net_Call; Net_Call.cls
Startup="(None)"
HelpFile=""
Title="Net_Call_API"
Command32=""
Name="Net_Call_API"
HelpContextID="0"
CompatibleMode="0"
MajorVer=1
MinorVer=0
RevisionVer=0
AutoIncrementVer=1
ServerSupportFiles=0
VersionCompanyName="FREE_"
CompilationType=0
OptimizationType=0
FavorPentiumPro(tm)=0
CodeViewDebugInfo=0
NoAliasing=0
BoundsCheck=0
OverflowCheck=0
FlPointCheck=0
FDIVCheck=0
UnroundedFP=0
StartMode=1
Unattended=0
Retained=0
ThreadPerObject=0
MaxNumberOfThreads=1
DebugStartupOption=0
И ещё один довесок к проекту.
файл Net_Call_API.vbw нужен к файлу проекту.
Net_Call = 104, 104, 1165, 670,
Всё они в текстовой форме. И сохранять их надо в ANSI кодировки, что бы кркроказябры не появились в VB6. При этом в Vb6 можете сами писать и дописывать что хотитев них. А можно и в блокноте.
Теперь пишем VBS скрипт.
файл VB6_gen.vbs
Call IncludeFile("Class_sleep1.vbs")
Sub IncludeFile(fname)
executeGlobal CreateObject("Scripting.FileSystemObject").openTextFile(fname).readAll()
end sub
Private dblVB_ID
'Некоторые возможные значения типа_окна:
Const vbHide =0 '(0) — окно скрыто, фокус переходит к скрытому окну.
Const vbNormalFocus =1 '(1) — окно получает фокус и восстанавливает своё исходное положение и размер.
Const vbMinimizedFocus =2'(2) — окно отображается в виде значка и получает фокус.
Const vbMaximizedFocus =3'(3) — окно разворачивается во весь экран и получает фокус.
Const vbNormalNoFocus =4'(4) — восстанавливается последнее положение и размер окна, активное окно остаётся & _ & активным.
Const vbMinimizedNoFocus =6'(6) — окно отображается в виде значка, активное окно остаётся активным.
dim oShell
dim stroka_
dim sleep_
set sleep_ = new sleep1 '-- класс ожидания
Dim VB, fso
dim path_
Set oShell = WScript.CreateObject("WScript.Shell")
set fso=createobject("scripting.filesystemobject")
path_=fso.GetAbsolutePathName(".")
'--- пути у вас будут другие. Я для примера написал на диск С:
stroka_="""диск:\путь_где _лежит\VB6.EXE""" & " /run " & """диск:\путь_где_лежит_файл_проекта\Net_Call_API.vbp""" '- строка, запуска vb6 с выполением проекта.
'запуска vb6
dblVB_ID = oShell.run (stroka_, 6, false) '--True нельзя ставить
oShell.AppActivate dblVB_ID '- фокус на окно
'''oShell.SendKeys "{ENTER}" '- нажать ентер если надо
'''oShell.SendKeys "{ESC}" '- нажать экскейпт если надо
oShell.SendKeys "% n" '- минимизировать окно, иначе оно висит и маячит
sleep_.tm (1) '- ждать 1 сек пока окно закроется.
Call main 'переход к main процедуре
' |
' \|/
sub main()
Set VB = CreateObject("Net_Call_API.Net_Call")
path_= fso.GetAbsolutePathName(".") & "\test.ini" ' - назначаем путь где будет ini у нас
dim code_
' - посылка строки с командой в VB6
code_="a=10:msgbox a:a=a+1:msgbox a"
code_=replace(code_, vbNewline, ":")
msgbox VB.WriteInIKey ("section1", "KeyName1", cstr(code_) , path_ ) '- посылаем запись кода, получаем ответ 1 (если ОК)
code_1= VB.ReadINIKey ("section1", "KeyName1", path_ ) '- читаем что записали
oShell.AppActivate dblVB_ID '- фокус на окно
msgbox VB.Call_code(code_1) '- посылаем код на выполнение.
set fso =Nothing
Set VB =Nothing
Set sleep_=Nothing
end sub
on error resume next
set fso =Nothing
Set VB =Nothing
Set sleep_=Nothing
' принудитеьно закрываем VB6
oShell.Run("taskkill.exe /f /im VB6.EXE"),0,True
Set oShell =nothing
и да. Там в примере в скрипте есть класс на VBS sleep1
файл "Class_sleep1.vbs"
Class sleep1
'public tim
private objwsh
sub tm(tim)
Set objwsh = CreateObject("WScript.Shell")
objwsh.Run "Timeout /T " & tim & " /nobreak" ,0 ,true
Set objwsh = Nothing
end sub
End Class
Всё. Запускаем VB6_gen.vbs. Он у нас запускает 1-ин класс VB6 (можете запустить их хоть 10 шт в скрипте.)
Ему сразу посылается команда, сделать ini файл (где лежит сам скрип), с секцией "section1" и ключом "KeyName1". Параметр будет иметь строку
a=10:msgbox a:a=a+1:msgbox a
Строка имеет вид кода.
Объявляем переменную "а", которая сразу будет иметь значение "=10", выскочит окно с этим значением, потом к переменно сделаем "+1", и опять окно с ней. Т.е. вот так будет работать посланная нами строка кода на выполнение. При этом, мы эту строку пишем в ini, потом читаем от туда и посылаем её на выполнение.
Короче чистая проверка на вшивость работы СОМ объекта с API.
Теперь про ОНлайн, и рунтайм.
Все файлы текстовые. И поэтому не надо ничего компилить. А за счёт того что выпонение идёт в рунтайме, то и изменения в кодах может быть в онлайне, без остановки процесса выполнения.
VBскрипт можно впихнуть в "HTA" и оттуда управлять тектсами и направлениями передачи.
Вот получился полноценный доступ ко всем API вмна через, скрипты.
.. комент к этому всему.
В блокноте правим файл класса. Пишем туда наши хотелки для исполнения VB6.
Эта фича с VB6 пашет и с VBA. Я проверял на всех, winword, exel, access, короче все кто имеет в себе VBA. Просто на тот момент, я не знал что VB6 будет маленький, а мне нужно было (очень хотелось) заиметь в VBS API функции. Правда при этом сами проги Офисных облочек портабле получались в разы больше чем VB6. Да и если захочется доп библиотеку соорудить под это дело, то лучше применять VB6.
вдогонку. Про портабле.
Если вы принесли к другу или переложили у себя вашу портабле папку. То если вы уже раньше у себя регистрировали лицензии то больше их трогать не надо. А вот если вы принесли портабле к другу у которого нет лицензии то надо ему будет запускать файл 1.reg. Это про лицензию. Теперь про VB6.exe. Если вы папку "portable" переложите в другое место то нужно опять там запускать VB6.exe с правами админа. И только тогда она у вас будет запускаться из скриптов. Так же нужно поступать и у друга. Также всё будет пахать и с флешки. Лиж бы пути были в скриптах верные. Но если с флешки то у друга надо будет только запустить рег файл. Но и я думаю всё таки придётся и с правами и на ехе нажимать, потому что наверняка у друга буквы дисков будут другие. А VB6 капризный на это при регистрации у себя свою OBL библиотеку. И ещё вспомнил. Пробовал в строке, передать новую дкларацию API , не проходит, по причине конца, строки. Как я понял, компилятор в VB6 проверяет конец строки в декларации. А в функции по передачи кода одной строкой, это не проходит. А 2-е сткоки это уже 2-е отдельно взятые функции (процессы) которые между собой не видятся. Т.е. декларация в одной строке, не будет видна в другой, той которая ссылается на эту функции API.
VB6 это конечно хорошо, в плане того что есть доступ у VBS к API вина.
Но всё таки я нашёл вещь!!
Полностью COM сервер на VBS, без регистрации.
Много писать для объяснения, поэтому буду подробно и не за раз.
1- есть в вине уже есть полностью VBS-ная приблуда для установки и регистрации COM на VBS.
2- есть 2-а варианта с ней работать (правильнее сказать регистрировать написанную СОМ).
3- при первом варианте, нужно на COM пр кнп мыши -> в меню регистрация или unрегистрация. Автоматом будет регистрация подобная regsrv32 путь\COM.
4- При втором варианте, в самой СОМ объявляется класс , точно так же как это делается в VBS с классами. И уже тогда в самом VBS - клиенте , прописывается просто путь к этому COM и VBS уже работает с ним как будто СОМ зарегистрирован.
...
Всё это касалось сервера. Но нам нужно что бы этот сервер что-то нам делал посланное клиентом и нам возвращал.
Вот для этого у винды уже установлена приблуда под названием MSScriptControl.ScriptControl
Это COM OCX библиотека msscript.ocx
Цитата:
Файл msscript.ocx входит в состав Microsoft Office Access 2010 14,
Windows 10 и Windows 8.1.
Т.е. у меня на машине win10 х64 она лежит в
"C:\Windows\SysWOW64\msscript.ocx"
И уже была зарегистрирована как таковая.
---------------------------
Данный объект имеет следующие свойства / ScriptControl Properties:
AllowUI - Если установлено в True, программа может получать доступ к элементам пользовательского интерфейса таким, как MsgBox. (Type:=Bollean, Mode:=Read/Write, Default:=True)
CodeObject - Возвращает набор объектов, которые были добавленные в пространство имен с помощью метода AddObject. (Type:=Object, Mode:=Read, Default:=Nothing)
Error - Возвращает объект ошибки, содержащий информацию об ошибке в скрипте. По умолчанию свойства объекта ошибки не содержат информации. (Type:=Object, Mode:=Read, Default:=Standard_Error_Object)
Clear() - Метод. Очищает объект ошибки.
Column - Свойство. Содержит номер столбца кода числа, где произошла ошибка. (Type:=Long, Mode:=Read, Default:=0)
Description - Свойство. Описание ошибки. (Type:=String, Mode:=Read, Default:="")
HelpContext - Свойство. Ссылка на файл справки с описанием ошибки. (Type:=Long, Mode:=Read, Default:=0)
HelpFile - Свойство. Имя файла справки, содержащего вспомогательную информацию. (Type:=String, Mode:=Read, Default:="")
Line - Свойство. Номер строки исходного кода, где произошла ошибка. (Type:=Long, Mode:=Read, Default:=0)
Number - Свойство. Номер ошибки. (Type:=Long, Mode:=Read, Default:=0)
Source - Свойство. Описывает общий тип ошибки. (Type:=String, Mode:=Read, Default:="")
Text - Свойство. Cодержит строку исходного кода, где произошла ошибка. (Type:=String, Mode:=Read, Default:="")
Language - Возвращает/задает язык, интерпретатор которого будет реализовывать компонент. В стандартной поставке доступны VBScript и JScript, однако, если в системе установлены расширения Windows Script Host, возможно использование других языков, таких как Perl или Rexx. (Type:=String, Mode:=Read/Write, Default:="")
Modules - Содержит коллекцию объектов модулей. (Type:=Object, Mode:=Read, Default:=Standard_Modules_Object)
Add(Name[, Object]) - Метод. Добавляет модуль с заданным именем. (Name:=String, Object:=Object)
Item(Index) - Свойство по умолчанию. Возвращает модуль по индексу. (Index:=Number/String)
AddCode(Code) - Метод. См. описание.
CodeObject - Свойство. См. описание.
Eval(Code) - Метод. См. описание.
ExecuteStatement(Code) - Метод. См. описание.
Name - Свойство. Имя модуля. (Type:=String, Mode:=Read)
Procedures - Свойство. См. описание.
Run(Function_Name[, Arguments]) - Метод. См. описание.
Count - Свойство. Возвращает количество добавленных модулей. По умолчанию 1 ("Global"). (Type:=Long, Mode:=Read, Default:=1)
Procedures - Содержит коллекцию объектов процедур. Описание объекта процедур см. ниже. (Type:=Object, Mode:=Read, Default:=Standard_Procedures_Object)
Item(Index) - Свойство по умолчанию. Возвращает модуль по индексу. (Index:=Number/String)
HasReturnValue - Свойство. Возвращает True, если функция возвращает значение. (Type:=Bollean, Mode:=Read)
Name - Свойство. Имя процедуры. (Type:=String, Mode:=Read)
NumArgs - Свойство. Возвращает количество обязательных аргументов функции/процедуры. (Type:=Long, Mode:=Read)
Count - Свойство. Возвращает количество добавленных модулей. (Type:=Long, Mode:=Read, Default:=0)
SitehWnd - Содержит "ссылку" на дескриптор окна программы, которое будет использовано для отображения графического интерфейса пользователя (GUI). (Type:=Long, Mode:=Read, Default:=0)
State - Определяет, как будут обрабатываться события объектов, добавленные с помощью метода AddObject. (Type:=Long, Mode:=Read/Write, Default:=0)
Timeout - Максимальное количество миллисекунд, после которого будет сгенерирована ошибка. Значение –1 позволяет отключить ошибки, связанные с истечением отведенного времени (timeout), что позволит скрипту исполняться неограниченное время. (Type:=Long, Mode:=Read/Write, Default:=10000)
UseSafeSubset - При установке этого свойства в True компонент может выполнять ограниченный набор действий, заданный текущими установками безопасности в системе. Это свойство полезно, если планируется запуск скриптов, полученных, например, через Интернет. (Type:=Bollean, Mode:=Read/Write, Default:=False)
Методы / ScriptControl Methods:
AddCode(Code) - Добавляет код к списку процедур компонента. В дальнейшем эти процедуры могут быть вызваны при помощи метода Run либо из других процедур скрипта. Не обязательно добавлять только функции или процедуры, это может быть любой валидный код. (Code:=String)
AddObject(Name, Object[, Basic]) - Добавляет объект к пространству имен, который будет доступен в коде скрипта. Имя объекта задает параметр Name. Объект может быть объявлен как основной, путем установки третьего необязательного параметра Basic в True. В JScript, например, он будет доступен как this, если добавлено несколько объектов. Можно оперировать любыми объектами, будь то UserForm, Application или что-то еще. (Name:=String, Object:=Object, Basic:=Boolean)
Eval(Code) - Выполняет код, заданный параметром Code, и возвращает результат исполнения. Позволяет выполнить код без добавления его к списку процедур компонента. (Code:=String)
ExecuteStatement(Code) - Выполняет одну инструкцию. В отличие от метода Run не позволяет передавать аргументы. (Code:=String)
Reset() - Сбрасывает компонент в начальное состояние, удаляя все добавленные ранее объекты и код.
Run(Function_Name[, Arguments]) - Выполняет именованную функцию/процедуру из числа ранее добавленных при помощи метода AddCode и возвращает результат. (Function_Name:=String, Arguments:=Variant)
---------------------------
В принципе это тоже самое что и в vba6.dll (см выше пост про VB6), но vba6.dll не возвращает (по крайней мере я не нашёл как, возможно и возвращает что-то), а вот эта MSScriptControl.ScriptControl полностью возвращает, более того она даже может выполнять внутри себя крутые вещи.
начну с сервера.
Сервер, это текстовый файл, пополам разделённый, первая часть файла это наподобие манифеста (SxS технология), а вторая часть текста это обычный VBS.
Я решил упростить для себя задачу, и решил поступать с этой СОМ в регистрацией по второму варианту (см выше пост). Т.е. объявить в ней класс и т.о. VBS-клиент будет сам подхватывать этот сервер и работать с ним без регистрации.
мой тест был оформлен вот так.
Файл COM_VBS.wsc
<?xml version="1.0" encoding="windows-1251" standalone="yes"?>
<?component error="true" debug="true"?>
<component>
<registration progid="Server_VBS"/>
<public>
<method name="Init"/>
</public>
<object id="Com_" progid="MSScriptControl.ScriptControl"/>
<script language="VBScript"><![CDATA[
'---------конец первой части COM--------------------------
'---------начало второй части COM--------------------------
Function Init()
Set Init = New ServerClass
End Function
'-----------------------------------
Class ServerClass
Private Str_Code
Public Property Let Str_(Byval Code_)
Com_.Language = "VBScript"
Com_.AddCode Code_
End Property
Public Function Execute_Script(Str_,ind)
Com_.Language = "VBScript"
Com_.Run Str_,ind
End function
End Class
]]></script>
</component>
Окончание файла .wsc как тряпка для быка, в винды. Винда сразу на этот файл накидывается как на исполняемый объект. Как будто это exe файл. И если его выделить и пр_кн_мыши то появляется в меню пункты, такие как регистрировать и унрегистрировать.
В моём файле COM_VBS.wsc, присутствует объявление класса, поэтому его мы не будет регистрировать вообще.
теперь внутренности, файла. Т.е его кишочки.
строка
<registration progid="Server_VBS"/>
Это объява, имени СОМ-а. Но т.к. я не собираюсь его регистрировать то в клиенте это имя вообще не "светиться" у меня. Но эта строка в сервере СОМ обяза нужна. Я назвал свой СОМ именем "Server_VBS".
До обяъвы класса (у меня) уже будет объявлена процедура (функция и т.д.). Это строка
<method name="Init"/>
Эта процедура у меня уже ниже прописана как функция.
Function Init()
Set Init = New ServerClass
End Function
Т.е. все функции которые НЕ ВНУТРИ класса, а только принадлежащие СОМ объекту все прописываются тут с этой строкой.
типа так :
<method name="a1"/>
<method name="a2"/>
<method name="a3"/>
...
<method name="a10"/>
И все они потом должны быть прописаны на языке, на котором будет объявлен сам СОМ объект.
строка
<script language="VBScript">
как раз нам и говорит об этом.
А вот выше интересненькое у меня.
Строка
<object id="Com_" progid="MSScriptControl.ScriptControl"/>
Это как раз объява внутри СОМ объекта ещё одного СОМ объекта.
Имя ему будет у меня Com_. Эта строка прототип строки с объявлением в VBS объектов типа
Set Com_ = CreateObject("MSScriptControl.ScriptControl")
Т.е. в СОМ объявляется другой объект.
После обычных станадартных записей, у меня идёт объява моего класса с которым я буду работать в клиенте.
Class ServerClass
Т.к. объяект "MSScriptControl.ScriptControl" в СОМ уже объявлен ДО класса, то имя
Com_ уже присутствует как экземпляр того класса.
Поэтому я к нему внутри своего класса обращаюсь как к объявленному заранее.
внутри своего свойства класса.
Public Property Let Str_(Byval Code_)
Com_.Language = "VBScript"
Com_.AddCode Code_
End Property
Я устанавливаю язык Com_.Language = "VBScript", и добавляю ему VBS код который он будет потом выполнять (см выше пост про объект "MSScriptControl.ScriptControl")
А в функции
Public Function Execute_Script(Str_,ind)
Com_.Language = "VBScript"
Com_.Run Str_,ind
End function
Я передаю ей, какую процедуру выполнить и с какими аргументами.
Ну а ниже уже идёт стандартные строки.
Клиент.
Файл test.vbs
option explicit
'============загрузка других модулей
' это нужно вставлять в каждый модуль vbs
Call IncludeFile("run_vbs_x64.vbs")
Sub IncludeFile(fname)
executeGlobal CreateObject("Scripting.FileSystemObject").openTextFile(fname).readAll()
end sub
Dim Com_Server
Dim Com_Server_Class,scr_
Set Com_Server = GetObject("script:С:\COM_VBS.wsc")
Set Com_Server_Class = Com_Server.Init()
scr_="Function s(ss) ss=ss+1 end function"
Com_Server_Class.Str_ = scr_
dim dd
dd=1
Com_Server_Class.Execute_Script "s", dd
msgbox dd
On Error resume next
Set Com_Server_Class = Nothing
Set Com_Server = Nothing
клиент тоже короткий.
Самое ПЕРВОЕ. Это вверху
Call IncludeFile("run_vbs_x64.vbs")
Sub IncludeFile(fname)
executeGlobal CreateObject("Scripting.FileSystemObject").openTextFile(fname).readAll()
end sub
Файл "run_vbs_x64.vbs" я всегда добавляю во все свои VBS коды из-за непонятках с х64 ОС и х32 VBS кода. Приходиться или строкой писать где находиться
"С:\Windows\System32\WScript.exe" твойФайл.vbs
"С:\Windows\System32\СScript.exe" твойФайл.vbs
или
"С:\Windows\SysWOW64\WScript.exe" твойФайл.vbs
"С:\Windows\SysWOW64\СScript.exe" твойФайл.vbs
или вот так как я автоматом.
Я выбрал автоматом.
файл run_vbs_x64.vbs
option explicit
' C:\Windows\System32\WScript.exe = WScript.exe
Dim ScriptHost : ScriptHost = Mid(WScript.FullName, InStrRev(WScript.FullName, "\") + 1, Len(WScript.FullName))
Dim oWs : Set oWs = CreateObject("WScript.Shell")
Dim oProcEnv : Set oProcEnv = oWs.Environment("Process")
' Am I running 64-bit version of WScript.exe/Cscript.exe? So, call script again in x86 script host and then exit.
If InStr(LCase(WScript.FullName), LCase(oProcEnv("windir") & "\System32\")) And oProcEnv("PROCESSOR_ARCHITECTURE") = "AMD64" Then
' rebuild arguments
If Not WScript.Arguments.Count = 0 Then
Dim sArg, Arg
sArg = ""
For Each Arg In Wscript.Arguments
sArg = sArg & " " & """" & Arg & """"
Next
End If
Dim sCmd : sCmd = """" & oProcEnv("windir") & "\SysWOW64\" & ScriptHost & """" & " """ & WScript.ScriptFullName & """" & sArg
'WScript.Echo "Call " & sCmd
oWs.Run sCmd
WScript.Quit
End If
'============загрузка других модулей
' это нужно вставлять в каждый модуль vbs
'Call IncludeFile("run_vbs_x64.vbs")
'Sub IncludeFile(fname)
' executeGlobal CreateObject("Scripting.FileSystemObject").openTextFile(fname).readAll()
'end sub
Из-за этой автоматики, я не задумываюсь, что там и как там, а жму мышою на выполнение файла vbs на своей х64 ОС.
Клиент.
Вот эта
Set Com_Server = GetObject("script:С:\COM_VBS.wsc")
хитрая строка показывает где находиться наш сервер .wsc.
При этом эта строка его объявляет, как прототип объявления объектов СОМ.
типа
Set ИМЯ = CreateObject("ИМЯ_ОБЪЕКТА")
Но такая строка требует обяза регистрации его на машине.
А эта хитрая строка, этого не требует. Но она накладывает некоторые ограничения.
Например.
Даже если у вас , как например у меня сам файл COM_VBS.wsc, будет лежать
там же где и данный клиент VBS , и в клиенте будет строка
Set Com_Server = GetObject("script:COM_VBS.wsc")
То VBS ругнётся на типа, не знаю такую процедуру вообще, как бы намекает, без пути "диск и т.д." я не знаю никакие такие процедуры.
Поэтому в той строке обяза должен быть полный путь к файлу .wsc серверу.
далее всё просто.
Set Com_Server_Class = Com_Server.Init() '-- инициализирую свой класс
scr_="Function s(ss) ss=ss+1 end function" '- записываю в строку функцию с аргументами.
Com_Server_Class.Str_ = scr_'- засылаю в СОМ сервер эту строку функцию.
dim dd
dd=1 '- выставляю переменную равною 1.
Com_Server_Class.Execute_Script "s", dd '- посылаю на сервер исп. фун-ю s с аргументом dd
msgbox dd '- после исполнения на сервере функции s, сервер отдаёт клиенту результат.
И я его вижу результат, равен 2. Был dd=1 стал dd=2.
Вот так оформлен сервер на VBS.
Жалко конечно что MSScriptControl.ScriptControl не работает с VB или с VBA, что бы можно было вот так просто получать доступ к API функциям на VBS.
VB6 это конечно хорошо, в плане того что есть доступ у VBS к API вина.
Но всё таки я нашёл вещь!!
Полностью COM сервер на VBS, без регистрации.
На форуме уже были примеры использования *.wsc в скриптах. Вы не могли бы привести краткий пример реализации именно обмена данными и объектами между скриптами, можете предложить какой-то новый вариант?
3wedsmncjklvjvd73734 пишет:VB6 это конечно хорошо, в плане того что есть доступ у VBS к API вина.
Но всё таки я нашёл вещь!!
Полностью COM сервер на VBS, без регистрации.На форуме уже были примеры использования *.wsc в скриптах. Вы не могли бы привести краткий пример реализации именно обмена данными и объектами между скриптами, можете предложить какой-то новый вариант?
Да! Я видел, и даже скачивал,чего то там. Но там было смесь одного с другим (в плане языков). Сервер вроде был написан на джаве, клиент и такой и сякой. Вроде так. Поэтому я сразу на ту схему не запал.
Но странно для меня слышать, вы просите того про что я уже тут "Целую песенку спел"(R) х.ф.Золушка . Наверное я там увлёкся подробностями, что забыл объяснить суть.
...
Короче. В моей схеме, как обычно тут и было - сервер это *.wsc. В который вмонтирован COM от Микромягкого. Этот СОМ MSScriptControl.ScriptControl который уже имеется у всех на вине, и даже зарегистрирован при установке вина. Пишем сервер на *.wsc и туда вписываем этот СОМ. Получаем на выходе сервер с приблудой, которая может обрабатывать строки VBS или Jscript (все языки только от микрософта, но там наверху в посте прописано и про другие языки), на выполнения кода. Запускаем *.wsc, он ждёт от клиента строки кода. Вы ему код. Он выполняет его на стороне сервера и возвращает результат. ..
Почитайте. Там у меня всё есть. И пример с файлами. Блокнот. Копировать/вставить. Получаем 3-и фала. *.wsc и 2-а vbs фала. Один vbs , это клиент для общения с сервером, другой vbs, это приблуда от меня что бы vbs х32 не пудрил мозги, на машине с ОС х64. всего 3-и файла.
Там в примере у меня, у клиента переменная dd имеет значение 1. Посылает функцию сложения, с этой переменной. Сервер её складывает и отдаёт результат. На выходе получаем изменение переменной dd равной 2. Это как с API получается. Когда до применения функции АПИ нужно сформировать буфер для памяти, в который АПИ положит ответ. В примере точно так же получилось. Т.к. передаётся dd без "ByVal", то в ней сервер меняет данные. И отдаёт их через неё.
Если у вас Винда то мой пример в rar от сюда все вам покажет. MSScriptControl.ScriptControl у вас уже есть и поэтому мой код сработает.
MSScriptControl.ScriptControl
Это COM OCX библиотека msscript.ocx
Которая есть у всех, в винах. У меня она лежит в х64 каталоге "SysWOW64".
Вот её я и цепляю и впихиваю в сервер *.wsc.
Этот СОМ msscript.ocx это исполнитель кода на языках VBScript и других.
Такая же штука как у VB6 c API функцией (см смотри мой ранее пост про VB6),
Private Declare Function EbExecuteLine Lib "vba6.dll" (ByVal StringToExec As Long, ByVal Any1 As Long, ByVal Any2 As Long, ByVal CheckOnly As Long) As Long
Но в Vb6 она находиться в "vba6.dll" , а MSScriptControl.ScriptControl находиться в msscript.ocx. И обслуживают разные языки. одна только VB , вторая библиотека и VBS другие (кроме VB и VBA). "vba6.dll" надо регистрировать для обслуживания, а msscript.ocx уже зарегистрирован у всех.
При этом я видел в иннете как MSScriptControl.ScriptControl обрабатывает запросто WMI запросы. Точно так же как будто вы их выполняете локально.
можете предложить какой-то новый вариант?
Я ранее писал тут, что до применения VB6 с его АПИ, я пробовал на WinWord и всех прогах, которые вмонтированы в MSOfiice. И у которых присутствует компилятор языка VBA.
Могу тут выложить пример работы с WinWord. В принципе там точно так же как и с VB6 получается. Объявляется СОМ
Word.Application.
И ему посылается от клиента макрос на VBA, на исполнение. Т.к. у всех прог MSOfiice которые имеют в себе VBA есть рунтайм, то этот макрос исплоняется и ждёт как сервер, команды которые клиент ему даст. Применяя функцию
Private Declare Function EbExecuteLine Lib "vba6.dll" (ByVal StringToExec As Long, ByVal Any1 As Long, ByVal Any2 As Long, ByVal CheckOnly As Long) As Long
Сервер может исполнять, все коды посланные клиентом но только на языке VBA. VB6 в этом плане более всеяден как мне показалось.
Но а современный мой пример с msscript.ocx, все эти способы перебивает по развитию. Правда есть одно НО. msscript.ocx не работает с АПИ.
Есть ещё у Микрософта в вине приблуда. Которая я так думаю сделана для тех кто не хочет писать коды в блокноте.
C:\Windows\system32\comexp.msc
Служба компонентов.
3wedsmncjklvjvd73734, поясню о чем речь. Предположим, у меня запущено 2 VBS скрипта. Мне нужно из первого скрипта передать объект (ссылку на объект) во второй скрипт. Ну или во втором скрипте забрать объект из первого скрипта. Пусть это будет, например, Scripting.Dictionary с какими-то данными. Собственно, данная тема, в основном, об этом. Как это можно сделать, используя ваш подход? Хотелось бы увидеть код, который можно просто скопировать и запустить, без развернутых пояснений.
Пусть это будет, например, Scripting.Dictionary с какими-то данными.
В примере, выпадает окно с перечисленными данными Dictionary, ДО сервера.
В сервере меняется один первый индекс с данными с "One" на "Один".
После этого опять выпадает окно с перечисленными данными Dictionary, НО уже после сервера. С новыми изменёнными данными.
Не забудьте в файле "test.vbs" указать полный путь до сервера "COM_VBS.wsc"
3wedsmncjklvjvd73734, в примере вы запускаете только один vbs скрипт. Есть пример для двух vbs скриптов?
Сразу отпишусь тут.
Думаю что "comexp.msc" (Служба компонентов.) , что это выставлялка в работу на машине сервиса. Т.е. пишем серверную прогу. Запускаем эту бодягу "comexp.msc", она наш сервер выставляет на машине как сервис с постоянной работой. Т.о. наша прога сервер будет пахать удалённо на другой машине как сервис, и клиент удалённо сможет обращаться к этому сервису по имени и общаться с ним.
в примере вы запускаете только один vbs скрипт. Есть пример для двух vbs скриптов?
Два сервера? У меня вроде был пример, что один сервер второй клиент.
Нужно два сервера?
omegastripes
Я так понимаю что сервер, эта такая штука, которая пашет где то там, а мы можем к ней обращаться. ...
А вы хотите что бы 2-а скрипта между собой общались? В принципе можно замутить и это... Надо просто подумать, что бы было меньше долбёжки как например с регистрацией сервера.
3wedsmncjklvjvd73734, просто запускаем 2 VBS скрипта и между ними происходит обмен. Я не знаю должен ли быть там где-то сервер или нет, поэтому и прошу привести практический пример как использовать ваш подход.
А вы хотите что бы 2-а скрипта между собой общались?
Данная тема посвящена именно этому.
и прошу привести практический пример как использовать ваш подход.
Так сервер это и есть уже один скрипт. второй то VBS тоже такой же скрипт.
Просто есть понимание того что если что-то сервер, причём удалённо, то в его коде менять там что-то там нельзя (наверное и скрипт также), Так чем этот скрип (под названием сервер), вам не годен?
omegastripes
Не пойму вас. Чем скрипт (под именем сервер) вам не понраву? У него расширение не то?
omegastripes
И особо замечу. Мой вариант с серверной частью, способен пахать удалёно на другой машине. Когда как тут приведённый ранее пример, способен пахать только на локальной машине где пашут оба скрипта. Потому что они общаются по hwndID между собой, которое видно только на локальной машине.
omegastripes
Знаете что? Я вот тут подумал и решил. Вот смотрите. У вас есть 2-а скрипта. В которых там что-то написано что бы что-то там выполнять. Так вот один скрипт у меня уже есть (клиентская часть), а второй вы пишите сами динамически за счёт встроенной в сервер утилиты MSScriptControl.ScriptControl.
Т.к. она интерпретатор строки кода то вы в неё забивает всё что хотите у себя написать во 2-ом своём скрипте. И у вас полноценные 2-а VBS скриптах при чем оба находятся на разных машинах удалённо.
Чем вам такой вариант не понраву? Вы понимаете меня о чём я говорю?
Ремарка.
Сервер позволяет динамически менять 2-ой скрипт.
omegastripes
Если вам в моём варианте (примере), не понраву VBS скрипт, то поменяйте в моём примере на JScript и можете сами всё опробовать.
MSScriptControl.ScriptControl и .wsc оба поддерживают оба языка.
А сам Микрософт заявил что обе эти библиотеки могут понимать и языки такие как Perl и Rexx. Но для этого как они там предупредили - "долбёжки много" надо сделать.
3wedsmncjklvjvd73734
Еще раз поясню о чем эта тема форума. На практике могут работать 2 и более VBS|JS скриптов, каждый из которых - это отдельный процесс wscript.exe, процессы могут работать параллельно, нагружая разные ядра процессора и при этом не блокируя друг друга, и между ними нужно наладить обмен данными. Поэтому меня интересуют именно обычные скрипты, запущенные в разных процессах.
В вашем примере "сервер" - это даже не отдельный процесс, всё происходит в единственном процессе wscript.exe, который создается при запуске VBS скрипта. Грубо говоря, инстанс COM-сервера создается в скопе скрипта, и код в WSC не может работать параллельно с кодом этого VBS скрипта.
Я сейчас не говорю о DCOM и запуске скриптов на удаленной машине, поскольку этого в вашем примере нет, да и далеко не всегда нужна эта самая удаленная машина.
Чисто умозрительно справедливо отметить, что в вашем примере код расположен в 2 разных файлах, и между ними происходит обмен данными, но в контексте данной темы истинный интерес уделяется не обмену данными между файлами скриптов *.vbs|*.js, а обмену данными между процессами скриптов wscript.exe.
Если ваша реализация COM-сервера позволила бы один и тот же инстанс использовать из нескольких процессов wscript.exe, то это, вероятно, решало бы поставленную задачу.
omegastripes
Да я понял вас. На пальцах это должно быть выглядеть так. Запускаем 2-а терминала и там выводим например команды, на одном "dir c:", а на другом "dir d:", и оба выполняют, а потом одно окно должно передать свой список во второе окно. 2-а терминала это 2-а отдельных процеccа "cmd.exe". Я правильно понимаю?
Так вот в моём примере как раз тоже 2-а разных процесса. Один это VBS скрипт, который выполняется "wscript.exe" -ом, а второй это msscript.ocx, который запускает свой отдельный какой то внутренний компилятор (возможно и при помощи АПИ). Потому что вы этот msscript.ocx можете впихнуть в любую прогу которая поддерживает ActiveX. И эти ActiveX имеют свой собственный hwndID помимо того что имеет прога в которой этот ActiveX крутиться. Т.е. у HTML один hwnd, а у ActiveX, другой hwnd, хотя он внутри крутиться HTML. Понимаете меня. ActiveX имеет свой собственный hwnd не смотря внутри чего бы он там не крутился
Так вот в моём примере как раз тоже 2-а разных процесса.
Вы уверены в этом или только предполагаете? Что это за второй процесс?
omegastripes
Сейчас проверяю в диспетчере задач.
Сейчас проверяю в диспетчере задач.
Вероятно стоит сразу прикрутить вот этот код.
Появление на экране одновременно 2 msgbox'ов с разными process id после запуска одного скрипта это уже половина успеха.
у HTML один hwnd, а у ActiveX, другой hwnd
Одному процессу может принадлежать несколько hwnd.
omegastripes
Пока ищу возможность засечь.
Тут такое дело. Если даже IE внутри себя будет запускать ActiveX то hwnd будет только IE.
ActiveX при этом будет не видим для процессов, Именно из-за такой зависимости от "родителя" происходит сразу закрытия всего, что было открыто в IE. Достаточно закрыть IE и все процессы будут закрыты.
Есть ещё способ. Достаточно удалить (переместить куда либо)
C:\Windows\SysWOW64\msscript.ocx
а потом с помощью comexp.msc сделаить и запустить службу с этой msscript.ocx , лежащей в другом месте. То служба начинает с ней (с ОСХ) работать. НО vbs всё равно подхватывает тот ОСХ который я переложил. Т.е. при запуске службы автоматом происходит регистрация ОСХ, которая лежит в другом месте.
Но зато hwnd совершенно другой у службы. Но не понятка пока, с этими hwnd, то ли vbs берёт из ОСХ библиотеку, то ли из службы. Чувствую надо отдохнуть мне с этим. Всё обмыслить.
Вероятно стоит сразу прикрутить вот этот код.
Я взял. Спасибо. Буду им отлавливать. Но потом. Пока - отдых.
omegastripes
Не
не получается каменный цветок.
Я же говорю. Всё что внутри, всё принадлежит одному процессу.
Буду думать. Главное получил инфу, теперь надо её обработать.
Я месягу делаю внутри .wsc, а он объявляется в vbs.
Весь этот hwnd принадлежит одному vbs.
Сервер(служба) даже и не затрагивается.
Есть одна мысль. Изначально все библиотеки это файлы библиотек. А раз так то я имею право работать с ними, так?
Все эти осх, dll,tlb, api все это файлы.
3wedsmncjklvjvd73734
Добавляйте пожалуйста к скриншотам код.
omegastripes
Да добавлять то нечего.
Ерунда там чес слово. Потому что...
Короче. Я во внутрь ОСХ впихнул скрипт код с ожиданием 2-ух минут.
Ничего не делать. Так этот ОСХ (который в .wsc) весь vbs остановил. Т.е. после моей команды на выполнение кода в ОСХ сам vbs остановился и ждал исполнения в ОСХ. Только после этого всё продолжело исполняться, с месягами и т.д.
Так что то что делается с помощью ОЛЕ, СОМ, и др. ничего не выйдет с разделением процессов.
Но есть вариант. Это развязаться от связи через память и файлы. Т.е. сеть. Посмотрел что быстро сделать можно ОDBC только с базами. Остаётся только сервер TCP , который получает и отдаёт данные клиентам. И все клиенты общаются между собой только через него. Такая схема пройдёт. На сервере установлена ОСХ, которая всеядная ко всем типам данных (это что бы не проверять типы и не подстраиваться под них)..
Короче. вот на скорую придумал это. Иначе никак. Всё время происходит внутри все действия основного процесса.
..
сейчас пришла ещё идейка... Но в начале надо проверить её.
omegastripes
Я вот тут придумал, как скоренько передавать друг другу hwnd своего процесса.
Через клипбоард (буфер обмена). В 1-ом vbs файле командой shell.run файл.vbs запускаются несколько разных процессов vbs. каждый из них в начале берёт из буфера, что послал первый, и т.д. Там даже в посланиях можно вкладывать имя процесса, что бы не путались проги между собой.Через
shell.run точно запускаются разные процессы.
Теперь осталось придумать как передавать объекты.
Через клипбоард
А через параметры командной строки не вариант?
А через параметры командной строки не вариант?
Не, не прокатывает этот вариант. Потому что он строго однонаправленный.
А нужно 2-ух направленный, + независим по времени. Т.е. все проги слушают клипа, как слушает сокета сеть, командой "листинг". В принципе - ДА. в каждой проге вложена сокета которая слушает сеть. Как только сокета услышала что ей что-то там, то сразу мяукнула сама... Короче. Подумаю над этой связкой. По крайней мере есть портабле vb6 в котором можно мутить в онлайне API функции, на которых можно позырить вот это--> цитата
C++
HANDLE SetClipboardData(UINT uFormat, HANDLE hMem)
Значение, которое вы указываете для параметра uFormat, должно быть либо стандартным форматом буфера обмена (таблица 2), либо зарегистрированным форматом. Зарегистрированные форматы — это пользовательские форматы, которые позволяют задавать форматы для данных, специфичных для приложения. Мы рассмотрим этот формат позже.
Пример с сокетой, далеко ходить не надо.
У меня стоит, и слушает сеть, как сервер на порте 443 (SSL).
В VB6 есть ОСХ сокета, которая может всё это делать и с помощью которой можно "мутить."
У меня она стоит на 127.0.0.1 и слушает. Как только кто мяукнул ей, не важно, кто и что, она быстренько его вырубила. Т.е. отк. соединение. Т.о. я освобождаю свою машину от лишних напряг по ответу тому кто мяукнул на порт 443 и на локалхост 127.0.0.1. В файле etc/hosts , у меня прописаны серваки которым я не доверяю. Как только html страница обратилась к такому серваку, то браузер первым делом лезет в файл etc/hosts, и если там его нет, то спрашивает уже DNS сервера на стороне провайдера. далее я умолкаю. Это не тема тут.
Короче.
Вот зип. там сокета и х32 и х64. Взяты из VB6. Т.к. это всё из VB6 , то всё что находиться от VB всё подлежит лицензированию. Т.е все осх имеют там свой код который метиться в реестре в ветке
HKEY_CLASSES_ROOT\Licenses\
При установке VB6 прога туда прописывает свои лицензии на все свои ОСХ которые у неё вообще есть.
Там у меня рабочий пример, который я применяю для "не хороших ребят" для сокеты 443.
Код простой.
Dim Winsock
Dim bClose
bClose = True
Set Winsock = WScript.CreateObject("MSWinsock.Winsock")
Winsock.LocalPort = 443
Winsock.Protocol = 0
Winsock.Listen
Do While (bClose)
WScript.Sleep(500)
Loop
код
Do While (bClose)
WScript.Sleep(500)
Loop
Это что бы vbs не заканчивала свою роботу и продолжала находиться в работе "вечно".
Создаётся сокета, ей даётся номер порта 443 (SSL), т.к. она запускается локально то автоматом уже имеет IP 127.0.0.1. Командой "Winsock.Listen", мы прослушиваем сеть.
Если вам нужно слушать другие порты напрмиер 80 или 39(Микрософский порт передачи файлов), то создавайте ещё одну сокету. Для каждого порта своя сокета.
Dim Winsock
Dim Winsock1
Dim Winsock2
...
Dim Winsock10
Set Winsock1 = WScript.CreateObject("MSWinsock.Winsock")
Winsock1.LocalPort = 80
Winsock1.Protocol = 0
Winsock1.Listen
и т.д
Т.к. после соединения моя сокета не отвечает тому кто мяукнул ей, то связь моментально рвётся и т.о. номер сокеты освобождается. Т.е. я ЭТИМ методом даю возможность своей винде продолжать плодить сокеты. В виндах по умолчанию, можно создать одновременно 5-10 сокет. Поэтому приходиться по долгу ждать некоторые сайты для загрузки где много картинок (данных). Каждая картинка - сокета. И пока кто-то не освободит место из 10-и следующее соединение не произойдёт. Поэтому некоторые "не хорошие люди" , могут удерживать связь (на стороне сервера) и не давать закрыться открытой сокете, и т.о. заглушить ваш браузер. А мой метод отлавливает таких дядей, и отключает их моментально, освобождая номера сокет, что бы их всё время было 10 штук одновременно для работы.
..
Поэтому мой метод по прослушиванию мяуканий из программ, с сокетой в проге уже на >90% решён. Осталось только решить как передать объекты.
С сетке принято применять для нужд юзеров сокеты начиная с 1024. Все которые меньше имеют номер служебные (напрмимер 80 HTTP ). Мы можем занимать например начиная с 60000 номера. Нам хватит этого. Редко кто в сетке достигает такого номера по сокете.
Я ничего не понимаю в VB6, кроме того, что он уже не поддерживается лет двадцать, и его нужно специально устанавливать. Не проще ли пользоваться доступным и более мощным PowerShell?
кроме того, что он уже не поддерживается лет двадцать
Хи-хи.
Недавно только что установил SP6 (был SP3), стал SP6. Официально VB6 установлен с Визуал студио. Они его обновили по причине того что внедряют в него технологию SxS, которая упрощает регистрацию библиотек которые сделаны на .Net #C и VB. Теперь у меня все мои DLL и другие сделанные мной библиотеки могут быть запущены (увидены), без регистрации. Про это потом и не тут.
ремарка.
SP6 - 2023 года , как мне указывают обновленные в VB6 все ОСХ файлы.
Не проще ли пользоваться доступным и более мощным PowerShell?
Для меня нет , не проще. там столько надо долбить, сколько на #С, причём совершенно в другом формате выступает этот язык. Ну всё там поменяно.. как увидел- отвернулся. Возможно кому вообще ничего не известно о программировании, наверное пойдёт. Это как сесть с мерса на запор - для меня.
teadrinker
В принципе я не против того или другого языка. Главное освоить технологию передачи. А каким языком это дело 5-ое.
Просто на VB сразу можно проверить 100 вариантов из-за его простоты. Меньше времени уйдёт на тесты чем писаниной заниматься во всех остальных языках.
VB6 тестовый язык. VBS ещё быстрее для тестов - но ограничен.
Ха!
Решение практически найдено.
Оказывается можно через буфер обмена передавать даже "биткоины".
https://habr.com/ru/companies/beget/articles/841446/
цитата
------------
Подход Figma с копированием закодированных в base64 строк в HTML‑представление груб, но эффективен для обхода ряда ограничений, связанных с работой с Clipboard API. Это неплохой подход для передачи собственного типа данных через буфер обмена.
Т.е. тип данных выставляются как txt/html а передаётся всё как base64.Мы в начале шифруем данные в base64, потом передаём как html, потом разархивируем из base64 , и вуаля. "Биткоины", перекочевали из одного приложения в другое.
"Всё просто" (это для Ивана из тридевятого царства). Знаю что в VBS команда "TypeName" нам показывает тип данных, который имеет переменная (когда она уже приняла данные ). Но до этого когда она только объявлялась, тип был "variant". Теперь остаётся только одно. Взять и в битовой форме получать эти данные из переменных, что бы из окна проги А переменная с текстом "траляляляля", полностью передалась и воспроизвелась в окне проги Б.
omegastripes
Я вижу решение в следующем.
Каждая прога имеет в себе HTML сервер. Который слушает и передаёт переменные и т.д. Если через буфер обмена, то получиться только локальная работа этой штуковины. А со встроенном сервером, это сразу 2-а зайца.
..
Есть что либо на уме по поводу выцарапывания битных данных из переменных?
вот мне первое что пришло в голову следующее.
в VB и в VBS есть такое объявление переменных. ByVal, которая указывает что этой переменной делается копия всех данных и её самой.
Если нам создать свой ящик с битами (по типу ADOB stream) а туда класть эту переменную, то можем передать хоть чёрта.
Function (byval b)
a=b
end Function
Уверен что в этих данных присутствует и данные о том что бы TypeName смог распознать тип данных этого набора битов.
omegastripes Я просто уверен что можно поступить проще. Короче.
Если я вам по почте перешлю файлик vbs, с Dictionary, и он чем то заполненн, какими то записями. То открывая мой vbs вы получите все данные которые были туда вложены. Но вот если например проект состоит из нескольких vbs в которых этот Dictionary, тоже чем то заполняется, то у вас этот ваш Dictionary будет не полностью заполнен из-за нехватки у вас других vbs.
Я уверен надо в первую очередь подумать над этим. Передать то передадим (даже сам файл vbs), только все ли там будут данные? Вот в чём вопрос.
При всех схемах пересылки объектов, изначально подразумевается наличие на той машине, куда отсылается объект, всех библиотек, которые нужны для работы данного объекта.
omegastripes
"Всё уже украдено до нас !" (R)
Вот почитайте
https://learn.microsoft.com/ru-ru/dotne … alization/
лично меня интересует вот эти части.
запись класса
https://learn.microsoft.com/ru-ru/dotne … n-xml-file
и чтение класса
https://learn.microsoft.com/ru-ru/dotne … n-xml-file
надо поковырять это...
3wedsmncjklvjvd73734
Поделюсь соображениями.
Использовать буфер обмена - не комильфо, как минимум, по отношению к пользователю.
Любая сериализация или маршаллинг предполагает клонирование данных, а передача ссылки на объект в другой процесс во-первых быстрее при больших объемах, а во-вторых позволяет (в большинстве случаев) в том процессе обращаться напрямую к свойствам и методам этого объекта, что, несомненно, более привлекательно. Передача ссылки подразумевает решение задачи по доступу к скопу другого скрипта.
omegastripes В начале про свои находки. Читаю и радует что мой путь (про сеть), правильный. Но удручает только одно - ТАМ они ЭТО давно сделали , а я не знал этого.
а передача ссылки на объект в другой процесс во-первых быстрее при больших объемах, а во-вторых позволяет (в большинстве случаев) в том процессе обращаться напрямую к свойствам и методам этого объекта, что, несомненно, более привлекательно. Передача ссылки подразумевает решение задачи по доступу к скопу другого скрипта.
Я склоняюсь к обратному. Пример.
Предположим ваш метод.
Вы имеете объект. List. занёсли туда данные. Он(объект) по вашей схеме "сериализовался" (назовём ЭТО для примера именем которое дали ОНИ в Микрософте) целой ссылкой. Где то там в Сочи, ваша жена (или тёща или сын или дочь), воспроизвели вашу схему "сериализации". Потом вы для себя выяснили, что вам надо не list а Dictionary, меняете у себя в vbs-ке , и что? Как в Сочи по вашей версии должно всё измениться? Опишите ваши хотелки...
Я чёт, не шибко перевариваю ваши хотелки. Мне сразу влоб пришло на ум реализация - слать целый файл vbs, и всё, учитывая то что на том краю света (в Сочи), на ноуте установлена ОС винда, в которой воспроизводиться как и у вас, vbs файлы. Понимаете меня? НО вот в микрософте ЭТО понимают и говорят, сериализация, это передача ДАННЫХ, которые меняются. Т.е. распределённая база данных, но для програмёров.
..
ремарка.
Я запускал терминалы на биржах и видел, онлайн изменения биржевых котировок по сети. Занимался репликацией данных по базам данных, включая и доки Микрософского офиса... Но НИФИГА не понимаю что вы хотите.
omegastripes Я видел примеры по сериализации, где програмёры сами без микрософта решали данный вопрос, простым методом, перебирая с помощью "case" все типы данных, и передавали их, "клиенту". И т.о. у клиента менялись переменные и их типы данных в онлайне (клиент это програмёр).
Помните наш пример с ОСХ? там на "другом" конце, автоматом подключился тип данных Dictionary и автоматом изменил там данные, мол бери клиент я всё сделал.
3wedsmncjklvjvd73734
Меня интересует передача ссылки на объект из одного процесса в другой, на одной машине, локально, и без сериализации. Цель - организовать параллельную работу нескольких скриптов, чтобы при этом можно было в скрипте одинаково работать как со "своими" объектами, так и с объектами, созданными в других скриптах, будто они созданы в своем скрипте. Скажем так, хотелось бы хотя бы отчасти приблизиться к асинхронной парадигме и к синтаксису asyncio, только без GIL в случае WSH.
Еще раз подчерку, данная тема посвящена передаче данных между процессами на одном ПК, оффлайн.
Любая сериализация или маршаллинг предполагает клонирование данных, а передача ссылки на объект в другой процесс
У микрософта при изготовлении их XML сразу указывается объекту (например dictionary), что он подлежит сериализации. и поэтому ОН будет включон в XML и там будут изменяться данные (value).
И второе. Я вот смотрю примеры и вижу как микрософт свою схему по сиреализации впихнул только в *.NET и в #С. Но не стал этим заниматься в чистом VB. Думаю что тут пахнет готовой exe, а в рунтайме не пашет... но это возможно на мой первый взгляд...
3wedsmncjklvjvd73734, нет сериализация не интересует по вышеуказанным причинам, интересует именно передача ссылки, как это сделано в других примерах в начале темы.
omegastripes
Я понял вас так. На пальцах. Есть длинная портянка с кодом. Я делю её на 2-е части и делаю 2-а файла vbs. Они выполняют одну и туже работу как и в длинной портянке. Но для того что бы работала 2-ая часть кода на другом процессе, ей нужны данные от первой. А первая тоже может как то зависеть от второй части если во второй части например произошёл сбой и возврат по error которая находиться на первой части. Я правильно понял вас?
Я правильно понял вас?
Абсолютно. Простой пример, где это было бы полезно - "многопоточный" парсер.
omegastripes
надо подумать. Я прочёл то что было в 11-ом году с IE. Всё меняется и то что было в 11-ом теперь не прокатит.
..
Конечно сразу.
1-Надо делать только через сеть, и не важно локально или нет. Потому что ЭТО проще.
2-в этой схеме надо предусматривать обяза процедуру ожидания по получению данных от другого объекта.
3- возможно можно организовать автоматическую систему которая анализировала бы портянку, и сама искалеа только те части которые будут независимы от других данных, и сама их делила на части и запускала несколько кодов через "run" (что бы были разные процессы), а возврат результата от кода передавала в параметре запуска через аргументы.
omegastripes
надо подумать. Я прочёл то что было в 11-ом году с IE. Всё меняется и то что было в 11-ом теперь не прокатит.
Опция с getobject("new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}") работает прекрасно по сей день.
omegastripes
Спасибо. Я посмотрю, ещё раз... "вчерася", только глазами пробежал, зная что уже IE нет нигде, думал что всё уже умерло. Ещё раз спасибо. буду смотреть и думать. ИНФЫ, полна голова. И это важно, и это самое главное для реализации этого проекта.
omegastripes
Посмотрел как пашет 1.vbs и 2.vbs (самые первые коды).
Да внутри одного объекта, всё это крутиться. Даже когда запускается 2-скрипт. Он цапает этот объект и цепляет от него данные. На первый взгляд сразу понятна схема. Это глобальный объект и при его изготовлении в новом процессе, он не делит себя (на размножает себя), а просто формирует у себя отдел памяти. Хотя имея глобальную переменную, он её передаёт в другие процессы запросто.
Да. рабочая схема.
Надо подумать.
1-имеем ОС (общий объект),
2-связь между ними не память а сеть...(с памятью долбёжки много, да она и не открыта для юзера, а это не айс для нас разработчиков)
3- надо вот "эту" схему воплотить , основываясь на "ТОЙ" .
зная что уже IE нет нигде
Вообще-то, IE тоже никуда не делся, всё работает, по крайней мере на 10 винде.
связь между ними не память а сеть
Сеть - это сериализация, а значит передается не ссылка.
надо вот "эту" схему воплотить , основываясь на "ТОЙ"
Я предполагал, что нужно поколдовать с компонентом WSC, вероятно это позволит организовать в нем (или через него) некий расшаренный скоп, через который можно связать скрипты.
omegastripes
ха-ха-ха-ха.
Короче. я первый раз просто тупо скопировал/вставил код и всё.
А только что просмотрел внимательно в кишёчки.
Короче.
GetObject("new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}")
Это обычный ActiveX. У всех ОСХ в VB6 есть свойства их. Я даже скажу больше для этого объекта уверен есть помимо "Property" есть ещё "tag" , "Caption", и "Description".
Если ЭТО делал Микрософт то там это на 90% должно быть. Я раньше через эти параметры передавал данные - было такое. Теперь про данные (глобальные). ВСе ОСХ-ы хранят данные (например установленные юзером, если програмёр разрешил это делать, когда делал проект ОСХ), параметра своего окна, шрифт и т.д. в отдельном рядом стоящем с ОСХ файле, и если этот файл удалить, то переменные улетят в трубу. Я это уже проходил и не раз. А некоторый раз даже не смог их поменять поэтому начал искать причину и наткнулся на вот такой вот кеш, файл данных.. Тоже было такое. В принципе эта схема схожа со схемой распределённых данных в МС Офисе, с доками. Где так же есть кеши на Hdd.
И если этот ОСХ передать юзеру в Сочи, без этого кеша-фала, то тот юзер ничего не увидит по данным которые автор внёс в ОСХ до передачи юзеру.
omegastripes
сейчас покажу на примере.
Это обычный ActiveX
Вы удивитесь, но я больше скажу, это обычное окно Internet Explorer.
в отдельном рядом стоящем с ОСХ файле
Но для передачи ссылки на объект подобный файл вряд ли каким-то боком задействован.
Вы удивитесь, но я больше скажу, это обычное окно Internet Explorer.
Это обычный СОМ, который ActiveX и который поэтому в VB6 в проектах "высвечивается" именно так.-- потом покажу.
сейчас покажу пример про другие ОСХ-ы.
3wedsmncjklvjvd73734 пишет:Это обычный ActiveX
Вы удивитесь, но я больше скажу, это обычное окно Internet Explorer.
3wedsmncjklvjvd73734 пишет:в отдельном рядом стоящем с ОСХ файле
Но для передачи ссылки на объект подобный файл вряд ли каким-то боком задействован.
Тоже всё потом.
...
Вот пример из обычных ОСХ которые в VB6.
Если я сделаю проект и сделаю свой ОСХ, то автоматом рядом с ним появиться кеш файл, в котором буду лежать эти данные.
У IE он тоже есть потомому что это "ОСХ", под другим именем.
сейчас найду и IE.
3wedsmncjklvjvd73734
Я одного не пойму, какая практическая польза от этого OCX кэша в контексте задачи?
omegastripes
Я одного не пойму, какая практическая польза от этого OCX кэша в контексте задачи?
Как это не пойму?
Прямая зависимость. Весь этот ОСХ пашет с кеш, потому что юзеру автор програмёр позволил менять параметры своего ОСХ-а. А как его сохранить? только файлом, что бы не загрязнять реестр, потмоу что там есть такие параметры как Picture (см ранее мой пост). А как эту самую пикчу, сохранить для "завтра"? В реестр её не кинешь. А так, скопировал её (ОСХ) вместе с кешем, и перенёс в Сочи без реестра.
ремарка.
Нашёл этот IE, сейчас выложу.
и перенёс в Сочи.
При чем здесь Сочи?
начнём с этого.
При чем здесь Сочи?
давайте напишу так.
"Не только для локальной работы, но и даже для работы в Сочи"
Не только для локальной работы
Но интересует только локальная работа. Какой толк в удаленной работе при распараллеливании локальных процессов?
продолжим поиски
C:\Windows\WinSxS\wow64_microsoft-windows-shdocvw_31bf3856ad364e35_10.0.19041.3636_none_66612e9af59b6401\f
C:\Windows\WinSxS\wow64_microsoft-windows-shdocvw_31bf3856ad364e35_10.0.19041.3636_none_66612e9af59b6401\r
C:\Windows\WinSxS\wow64_microsoft-windows-shdocvw_31bf3856ad364e35_10.0.19041.3636_none_66612e9af59b6401
Но интересует только локальная работа. Какой толк в удаленной работе при распараллеливании локальных процессов?
Да мне пофиг. Просто можно так и эдак с этим кешем.
Продолжу.
начну с локально директории
У меня в VB6 подхватывает файл только который корень
C:\Windows\WinSxS\wow64_microsoft-windows-shdocvw_31bf3856ad364e35_10.0.19041.3636_none_66612e9af59b6401
на остальные
C:\Windows\WinSxS\wow64_microsoft-windows-shdocvw_31bf3856ad364e35_10.0.19041.3636_none_66612e9af59b6401\f
C:\Windows\WinSxS\wow64_microsoft-windows-shdocvw_31bf3856ad364e35_10.0.19041.3636_none_66612e9af59b6401\r
Vb6 ругается.
Но сам VB6 подхватывает то подхватывает, но нигде не пишет про кишки этой библиотеки. Т.е. внутри ничего не могу в VB6 найти про неё.
вот что пишет иннет про неё.
--------
Shell Doc Object and Control Library (shdocvw.dll) — компонент операционной системы Microsoft Windows, разработанный корпорацией Microsoft. 13
Функция библиотеки — обеспечение основных функций веб-браузера Internet Explorer, таких как навигация в интернете, управление закладками и историей, а также поддержка функций контроля контента. 1
Некоторые особенности библиотеки:
Выполняется в фоновом режиме, завершить работу можно только с помощью диспетчера задач Windows. 3
Может влиять на другие приложения, изменяя их свойства. 3
Для проверки надёжности Microsoft предоставила библиотеке встроенный сертификат. 3
Расположение файла: по умолчанию — папка «C:\Windows\System32». 15
Важно: устаревшая или повреждённая версия shdocvw.dll может вызывать проблемы для компьютера, включая замедление работы и появление ошибок. 3
Также стоит учитывать, что некоторые вредоносные программы могут маскироваться под shdocvw.dll. 13
Я у себя IE не устанавливал, сижу на Edge, поэтому у меня его нет в C:\Windows\System32, а это другое. Но сам объект из 1.vbs подхватился потмому что ОН лежит в спец каталоге для не зарегистрированных библиотек, в каталоге SxS который у вина предназначен именно для таких библиотека которые сделаны для этой технологии (по старому "манифест")
OCX и OCA — это расширения файлов, связанных с приложением Visual Basic от корпорации Microsoft. 23
OCX — это файл настраиваемого элемента управления. Для каждого такого файла в Visual Basic есть сопутствующий OCA-файл с таким же именем. Например, к GRAPH16.OCX прилагается файл OCA с именем GRAPH16.OCA. 32
OCA — это двоичный файл, который выполняет функции библиотеки расширенного типа и кэша для файла настраиваемого элемента управления. В нём сохраняются описания объектов, методы и свойства. 231
Таким образом, OCX содержит сам настраиваемый элемент управления, а OCA — информацию, необходимую для его работы.
У IE такой кеш находиться в директории где находиться сама exe. Например у Edge его парметры по его настройке находяться в файле юзера профиля... Бери этот файл юзера и перетаскивай хоть в "Сочи" (сорри- локально на другой комп)
..
Но опять же замечу. Если програмёр , делавший свою ОСХ дал возможность менять программно параметры в ОСХ (какие параметры я выкладывал ранее) сделал, то юзер сможет их менять, и тогда будет изготавливаться рядом лежащий с ОСХ файл ОСА.
omegastripes
Можно для вашей затеи замутить такое же. В классе - запросто. И его тогда будут цеплять другие запущенные проги.
И вторая прога будет видеть, что там "намутила" с параметрами первая.
Т.к. ОСХ в VB6 запросто без напрягов делает такое с собой, то можно там изготовить срец такой ОСХ который будет просто набит всякими параметрами. Т.е. этот ОСХ будет служить обычным буфером обмена данными, и будет только это и делать, и больше ничего.
Надо только поподробнее узнать, как этот ОСХ сделать таким , что бы он не "размножался" при его объявлении в других прогах, а цеплял свои параметры из локальных данных и не создавал новые кеши для каждой проги.
omegastripes
Решение в лоб.
изготавливается .wsc в котором есть fso с локальным двоичным файлом, с личным юзер типом данных. Меняются только эти параметры и проги пишут туда локально свои данные. Т.к. проги уже имеют в себе все объекты то лишние добавочные объекты не к чему мутить изготавливать...
Хотя можно и это.
..
Т.к. .wsc один и тот же fso и файл, то все данные локальны и ГЛОБАЛЬНЫ. что и требовалось - заказчику.
omegastripes
Могу по этой схеме
https://forum.script-coding.com/viewtop … 88#p162188
замутить dll-ку которую будут цеплять все проги. И прописывать в общий ini файл свои параметры... Можно закрывать тему.
...
каждая прога будет отслеживать дату изменения файла и т.о. "соображать", стоит ли туда заглянуть за изменёнными параметрами или пока заняться своими расчётами.
В принципе этот вариант
https://forum.script-coding.com/viewtop … 09#p137509
тоже годен. И даже проще. Но тогда нужно "всем" (это я про Сочи) иметь у себя Access библиотеки.
А вот этот пост
https://forum.script-coding.com/viewtop … 53#p137653
говорит о том что в кеше IE всё записано, и поэтому ОН всё помнит, кто что менял у него там в его параметрах
omegastripes
Есть ещё вопросик по поводу динамического изменения объекта.
С параметрами разобрались. Да и в принципе и с объектами тоже можно.. НО.
Если уже изготовлена портянка то там нет возможности впихивать динамику по объектам.
А вот если эта портянка динамическая такая же как например в HTML страницами, то мне непонятно, как будет вести себя вторая прога в которой, по причине первой проги, вдруг не с того не с сего образовался новый объект и причём уже на пройденом этапе подсчёта/прогона обработки строк?
Как поведёт себя прога ? А вообще как она должна себя повести в таком случае?
для access у меня есть список нужных Dll-ок.
Для изготовления бызы mdb ACCESS
нужны эти DLL
Список этих библиотек:
Msjetoledb40.dll; 1
Msjet40.dll; 1
Mswstr10.dll; 1
Msjter40.dll; 1
Msjint40.dll. 1
Для 64-разрядных машин эти библиотеки обычно находятся в папке C:\Windows\Syswow64 или C:\Winnt\Syswow64. 1
regsvr32 Msjetoledb40.dll
regsvr32 Msjet40.dll
regsvr32 Mswstr10.dll
regsvr32 Msjter40.dll
regsvr32 Msjint40.dll
у меня уже они все есть. Я занимаюсь уже давно вплотную ими (mdb) программно.
omegastripes
Хотите много поточность в VBS?
вот вариант много поточности. Но эту самую много поточность должен сам програмёр организовать своим кодом.
Вот пример.
всё дело в хитрой команде на исполнение скрипта.
3wedsmncjklvjvd73734
Я пока так и не уловил мысль, как использование кэша OCX, применение различных перечисленных DLL, .wsc c fso с локальным файлом и прочее помогут расшарить ссылку на объект между процессами. Покажите пожалуйста код.
Кроме того, иногда приходится запускать скрипты на компе без административных полномочий, и нет возможности что-либо устанавливать, или вызывать regsvr32.
Да мне пофиг. Просто можно так и эдак с этим кешем.
Я думаю, что для обсуждения взаимодействия между скриптами на разных компах лучше создать новую тему, а то тут каша получается. В этой теме "удаленно" означает "в другом процессе", но не на другом компе.
Я предполагаю следующий подход.
Чтобы COM-сервер, создаваемый из WSC, был доступен в разных процессах, нужно сделать его singleton'ом, для этого при инициализации он должен регистрироваться в ROT, и тогда можно получить его инстанс в другом скрипте с помощью GetObject(), далее получаем Me инстанса, а, имея в наличии Me, все остальное делается элементарно.
А вот далее у меня только догадки. Насколько я понял, регистрацию в ROT можно выполнить неким вызовом API винды, но этой темой я не владею. И для вызова API функций из скрипта не очень-то хочется таскать с собой DynamicWrapperX или что-то подобное, хотя, вероятно, можно выкрутиться через PS/.Net.
omegastripes
Фу ты ну ты.. Опять, спешка. Как только начал внимательнее в кишках разбираться в этом -->
https://forum.script-coding.com/viewtop … 932#p45932
то всё понял и сейчас повнимательнее прочёл и .. "по лбу себя".. там же всё написано было!!. Фигли сидеть и корпеть? (это я себе сейчас)
Для начала используется метод Open("name"), чтобы открыть уже готовый либо создать новый контейнер, в котором будут храниться данные.
Короче.
Этот код вообще при открытии 2.vbs не изготавливает класс (СОМ). Он просто цепляет уже открытый класс от 1.vbs скрипта. Поэтому там прописана функция поиска приложения у которого есть свойства ""container_name", name" (в самом начале этот name объявляется равным "storage").
Ну ещё короче.
открываем 1.vbs , он сразу назначает name="storage" при вызове OPEN. В этой процедуре ОPEN происходит поиск открытого приложения (СОМ) со свойствами = "container_name", "storage"", Если нашёл , то выход и всё закрывается. Если нет то он сразу переходит к созданию этого объекта СОМ ({C08AFD90-F2A1-11D1-8455-00A0C91F3880}). Получает от него wnd и прописывает ему назначенные заранее свойства "container_name", "storage"" И только потом он переходит к выполнению "input", что бы юзер ввёл новое свойство.
После этого, этот СОМ не закрывается и открывается 2.vbs , и опять начинает проверять на уже открытые все приложения в которых есть уже заранее прописанное свойство "container_name", "storage"". Т.к. оно открыто то прога подхватывает этот открытый whd и сразу переходит к чтению свойств ранее записанные 1.vbs свойство.
Вот и весь фокус. Никакого диска ничего вообще. только по hwnd открытых окон.
Спец смотрел прогой oleview, эту dll-ку от IE . Там переменные на свойствах variant. А это как раз то что нужно для VBS.
Именно поэтому у него проходит запись объектов.
Если изучит повнимательнее как самому интерактивно создавать свойства то можно свою сотворить для этого СОМ-у.
Я почему то уверен что это можно сотворить и с wsс, даже без всяких лишних объяв сторонних сом..
Вообщем есть над чем подумать.
Я предполагаю следующий подход.
Чтобы COM-сервер, создаваемый из WSC, был доступен в разных процессах, нужно сделать его singleton'ом, для этого при инициализации он должен регистрироваться в ROT, и тогда можно получить его инстанс в другом скрипте с помощью GetObject(), далее получаем Me инстанса, а, имея в наличии Me, все остальное делается элементарно.
А вот далее у меня только догадки. Насколько я понял, регистрацию в ROT можно выполнить неким вызовом API винды, но этой темой я не владею. И для вызова API функций из скрипта не очень-то хочется таскать с собой DynamicWrapperX или что-то подобное, хотя, вероятно, можно выкрутиться через PS/.Net.
omegastripes
Вот пробуйте код.
Dim dic,dic1,fso
Set dic = CreateObject("Scripting.Dictionary")
set dic1 =dic
msgbox typename(dic1)
set fso = CreateObject("Scripting.FileSystemObject")
set dic1 =fso
msgbox typename(dic1)
dic1 =22
msgbox typename(dic1) & " = " & dic1
ОН там кстати не сохраняет переменную temp, он её переназначает как я в fso.
Вот вся связка. Как он там и написал, этот его код не для... а для того что бы не устанавливая ничего на машину уже применить то что уже стоит.
Думаю продолжать городить огороды не стоит.
там же всё написано было
Я рад, что вы, наконец-то, начали знакомиться с темой, хотя с этого стоило бы начать, перед тем как что-то писать. Советую прочитать полностью. А то зафлудили уже всю тему.
Короче.
Так все в курсе как это работает.
Я почему то уверен что это можно сотворить и с wsс, даже без всяких лишних объяв сторонних сом..
Я эту мысль пытаюсь донести до вас уже второй день. Есть предложения как из WSC вызвать RegisterActiveObject?
omegastripes
С самого начала.
1- В Его скрипте, он во 2.vbs проверят и ищет открытый СОМ , который уже зарегистрированный и уже поэтому имеет статус "Shell.Application". И поэтому он этим статусом проверяется на GetProperty запись, которую туда сделал 1.vbs. И за счёт "Shell.Application" у него получается.
Я тоже вроде (с wsc), всё записал , и там же проверил что мол записано (держу msgbox не закрытым). И в это время ищу по "Shell.Application" эту самую открытую в 1.vbs , wsc . И он не находит её. Потому что wsc по настоящему не зарегистрирован и не имеет статуса Shell.Application. Поэтому 2-а решения. Или как то регистрировать его или...
надо думать как ...
Если регистрировать то нажо искать старую при старую штуку. wizart по ней.
https://samag.ru/archive/article/1972
Она выдаёт ей GUI который можно внести в wsc и она тогда будет светиться всем как "Shell.Application".
omegastripes
С другой стороны, в раннем примере (см стр 1), там код который всё делает. Что не хватает вам?
Там вроде передаётся объект, хоть winword передавай. Чего не хватает?
Если из-за интереса, то ...
надо досконально узнать, как в запущенном скрипте, можно через оболочку окон получить как можно больше инфы о работающем скрипте.
Вот в СОМ там оно сканируется на присутствие в нём GetProperty. Типа там у всех должен быть стандарт по этому признаку. А как в сриптах?
например , вот тут -->
https://forum.script-coding.com/viewtopic.php?id=1037
есть хороший пример по параметрам, в Jscript. Я повторил и у меня запросто там передавались данные по 2-ум параметрам. При этом если такое оформлять на VB то долбёжки много. Но как я знаю там можно в wsc оформлять много этажность, т.е. как в HTML блоки по языкам. Но главное другое. Если в теле а не в классе объявлять GetProperty, то они видны всем снаружи. Т.е. надо на файле wsc пркнмыши, и в меню. "Generate type library.." и появляется TLB файл, который запросто виден в простмотрщиках по СОМ-ам (OLE). И там появляется этот самый GetProperty. А если его объявлять в классе, то он не виден в tlb. И второе. если выполнить команду regsvr32 и зарегить файл wsc, то ошибки не будет и в реестре в CLASS\ROOT появляется по имени которое прописанов wsc, GUID код. Но он не срабатывает при его createobject. Т.е файл wsc то в скрипте виден и наверяняка как и с ОСХ там с наружи должен святиться этот GetProperty от wsc,..
Но это только ради интереса.
omegastripes
Зачем мудрить? Уже всё есть и было давно.
https://forum.script-coding.com/viewtopic.php?id=1803
Я тоже вчера об этом подумал. Скрипт запускает hta (а HTA можно делать километровый с переменными).
Туда в hta скрипт кладёт всё что нужно другим, другие забирают от туда что нужно. Т.о. HTA служит перевалочным пунктом как и IE в раннем примере. Единственное отличие , это то что в HTA можно выставить лишние переменные и др. При этом туда в HTA можно гнать на выполнение скрипты, как с МССкриптконторл.
При этом HTA лучше чем .wsc из-за того что HTA уже COM зарегистрированный.
Почитайте как ТАМ ОНИ вызывают у окна GetProprety.
Конечно тот пример не точное воплощение наших хотелок, но технология точно такая же как у нашего Т.З.
omegastripes
ВАУ!
Решил ещё раз проверить тот вариант с IE по передачи полноценного объекта с его инициализированными данными.
Я файл 2.vbs положил на другой диск в другой каталог.
и дописал следующее после
'----- файл 2.vbs ---------
Dim gCon
Set gCon = New GlobalContainer
gCon.Open "storage"
MsgBox "Значение переменной ""test"": " & gCon.GetProperty("test") ,vbInformation
MsgBox "Тип переменной ""fso"": " & TypeName(gCon.GetProperty("fso")),vbInformation
'----- моя дописка ниже
MsgBox "путь где находится файл 1.vbs : = " & gCon.GetProperty("fso").GetAbsolutePathName(".")
Проверка заключалась в следующем.
Если всё правильно работает, то 1.vbs когда создавал свой fso в него вложит все параметры которые в нём есть.
Я выбрал параметр каталога в котором ОН находится при создании его. Т.е. fso должен показывать (когда его спрашивают) именно тот каталог который был при его создании.
И О чудо!
файл 2.vbs показал каталог в котором находится файл 1.vbs. Хотя об этом его спрашивал файл 2.vbs, который вообще находиться на другом диске. И правда, ЧУДО! ВЕЩЬ!.
Так как объект с CLSID {C08AFD90-F2A1-11D1-8455-00A0C91F3880} — это обычный объект Shell Window, то в качестве подобного контейнера может быть использовано любое существующее окно Проводника, например Рабочий стол. Я не владею WSH, поэтому пример на AHK (который, думаю, легко переписать на vbs).
Первый скрипт:
#Requires AutoHotkey v2
Persistent
VT_UI4 := 0x13, SWC_DESKTOP := 0x8
shellWindows := ComObject('Shell.Application').Windows
desktopShellWindow := shellWindows.Item(ComValue(VT_UI4, SWC_DESKTOP))
desktopShellWindow.PutProperty('myObj', {key: 'Hello!'})
Второй скрипт:
#Requires AutoHotkey v2
VT_UI4 := 0x13, SWC_DESKTOP := 0x8
shellWindows := ComObject('Shell.Application').Windows
desktopShellWindow := shellWindows.Item(ComValue(VT_UI4, SWC_DESKTOP))
MsgBox desktopShellWindow.GetProperty('myObj').key
Одна проблема: если Проводник перезапустить, данные будут потеряны.