1 (изменено: don_777_11, 2019-01-15 13:03:14)

Тема: VBS: Функции COM-библиотеки в VBScript

Доброго времени суток!

Пишу обёртку на VBS для dll.
Есть COM-библиотека HybridCOM.dll. В ней ряд методов, которые должны вызываться в программе VBS.

Вот так подключаю библиотек:

Set HCL = CreateObject(HybridCOMLib.HybridCOM")

Подключилась.

Далее вызываю следующие функции из dll:

STDMETHODIMP HybridCOM::Init()
{
---
return 0;
}
 
и 
 
STDMETHODIMP HybridCOM::LoadKeyStore(INT storage, BSTR password, BSTR container)
{
---
return 0;
}
HCL.Init()
er = HCL.LoadKeyStore(1, "Pasword", "C:\1.p12")

Это работает и ошибку не выдает (Ну вроде как работает, чтобы проверить точно ли работает, надо запустить следующую функцию на вывод)

Т.е. теперь пытаюсь вызвать функцию, которая возвращает значение:

STDMETHODIMP HybridCOM::X509ExportCertificateFromStore(BSTR alias, INT flag, BSTR* outCert)
{
---
return 0;
}

Как прописать в VBS, чтобы outCert заходила в функцию и возвращалась измененной?
Пишу вот так, но результат нулевой.


er = HCL.X509ExportCertificateFromStore("", 0, (outCert))

Получается, что главный вопрос таков:
Как отправлять возвратную переменную в функцию COM-a?

И если этих возвратных переменных несколько, как тогда писать? (Вот например есть такие функции, где на возврат идут 3 переменных:

STDMETHODIMP HybridCOM::VerifyData(BSTR alias, INT flags, INT inCertID, BSTR inData, BSTR inSign, BSTR* outData, BSTR* outVerifyInfo, BSTR* outCert))

2

Re: VBS: Функции COM-библиотеки в VBScript

Вероятно, это должно быть прописано  в Type library. Откуда же ещё VBS знать о типах аргументов.

3

Re: VBS: Функции COM-библиотеки в VBScript

wisgest
Спасибо за совет. Только вот я не совсем понял что там есть полезного... Либо я в упор не вижу ничего, либо по моей теме там ничего не описано

4 (изменено: YMP, 2019-01-15 12:04:18)

Re: VBS: Функции COM-библиотеки в VBScript

Последний выходной параметр в таком определении, насколько помню, будет в скрипте возвращаемым значением (тем, что слева от = ). А то, что эти функции явно возвращают (командой return), это для внутреннего потребления, так сказать. В скрипте не получить. Только движок среагирует выводом окна об ошибке, если вернётся не 0.

А для выходных строк там, перед последним параметром, наверно, всё равно, какую переменную передавать, лишь бы переменную. Ведь VBS передаёт переменные по ссылке. Так что, думаю, функция по этой ссылке пойдёт и положит там что ей надо.

Ну, или на всякий случай передать строку достаточной длины, если функция в переданную строку должна писать.

5 (изменено: don_777_11, 2019-01-15 13:05:02)

Re: VBS: Функции COM-библиотеки в VBScript

YMP
Ого! Интересно. Получается об return можно забыть. И тогда у меня должно работать вот так:

 
Set HCL = CreateObject(HybridCOMLib.HybridCOM")
Dim out1, outCert, er

HCL.Init()   																					 'ошибок нет
er = HCL.LoadKeyStore(1, "Pasword", "C:\1.p12")						 'ошибок нет

out1 = HCL.X509ExportCertificateFromStore ("", 0, outCert)

Только так не работает... Если outCert не брать в скобки, то постоянно ошибка.

6

Re: VBS: Функции COM-библиотеки в VBScript

А что за FSO у вас там? И можно попробовать предварительно в out1 и в outCert какие-нибудь строки записать. Не появится ли в них потом что-то?

7 (изменено: don_777_11, 2019-01-15 13:15:57)

Re: VBS: Функции COM-библиотеки в VBScript

YMP
С FSO опечатка вышла. Нечаянно с другого блокнота вытащил) уже поменял.

Пробовал задавать значения вот так:

Set HCL = CreateObject(HybridCOMLib.HybridCOM")
Dim out1, outCert, er

HCL.Init()   																					 'ошибок нет
er = HCL.LoadKeyStore(1, "Pasword", "C:\1.p12")						 'ошибок нет

out1 = "qwerty"
outCert = "www"
out1 = HCL.X509ExportCertificateFromStore ("", 0, (outCert))
MsgBox outCert & out1

На вывод пришло вот так: www
Получается значение out1 перезаписывается на пустое

8

Re: VBS: Функции COM-библиотеки в VBScript

А этот сертификат большой? Может, ему строку надо соответствующего размера? В VBS есть функция Space для создания строк с нужным размером.

9

Re: VBS: Функции COM-библиотеки в VBScript

YMP


Set HCL = CreateObject(HybridCOMLib.HybridCOM")
Dim out1, er

HCL.Init() 
er = HCL.LoadKeyStore(1, "Pasword", "C:\1.p12")

out1 = "qwerty"
outCert = Space(2048)
out1 = HCL.X509ExportCertificateFromStore ("", 0, (outCert))
MsgBox outCert & out1

На выходе пустая длииинная строчка.

10

Re: VBS: Функции COM-библиотеки в VBScript

А out1 почему так же не попробовали?

11

Re: VBS: Функции COM-библиотеки в VBScript

YMP

А out1 почему так же не попробовали?

Тоже самое)) Никакой разницы... Он вообще становится безразмерным

Поискал статейки в интернете... Советуют писать обертку между COM и  VBS. Тип вот такого: http://automation-beyond.com/2009/09/23/gp-automation-vbscript-limitation/

Но пока не понял как это работает и как это мне поможет)
Спасибо за содействие!) И буду ждать еще новых идей)

12

Re: VBS: Функции COM-библиотеки в VBScript

don_777_11 пишет:

Тоже самое)) Никакой разницы... Он вообще становится безразмерным

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

13

Re: VBS: Функции COM-библиотеки в VBScript

YMP
Добрый день.

Может ли она возвращать пустую строку в каком-то случае?

Может, если первые функции, которые отправляю -  не работают.

Может, не находит этот самый сертификат?

LoadKeyStore должна подгружать сертификат в О. память. И затем из нее X509ExportCertificateFromStore получается сертификат

14

Re: VBS: Функции COM-библиотеки в VBScript

Инфа по вашей ссылке выше, думаю, объясняет суть проблемы. В VBS нету типа переменной, который соответствовал бы BSTR*. Есть только BSTR. Тип BSTR является указателем на строку (на первую букву строки), а функции нужен указатель на такой указатель. Она не пишет текст в предоставленную строку, а создаёт строку сама, а указатель на неё кладёт в указанное в этом параметре место.

15 (изменено: alexii, 2019-01-16 20:31:30)

Re: VBS: Функции COM-библиотеки в VBScript

По поводу передачи параметра «в скобках»:

don_777_11 пишет:

out1 = HCL.X509ExportCertificateFromStore ("", 0, (outCert))

Когда Вы заключаете параметр в скобки — передаваться будет не ссылка на переменную outCert, а ссылка на вычисленный результат выражения «(outCert)». И таким образом в саму переменную ничего не вернётся — поскольку передаётся не её адрес, а адрес неименованного результата вычисления выражения.

16

Re: VBS: Функции COM-библиотеки в VBScript

alexii
А что можете посоветовать? Как тогда лучше отправить?

17

Re: VBS: Функции COM-библиотеки в VBScript

don_777_11, ничего.

18

Re: VBS: Функции COM-библиотеки в VBScript

Никак не могу сообразить... Ребят, кто еще что подскажет?

19

Re: VBS: Функции COM-библиотеки в VBScript

don_777_11

Средствами только VBScript - никак. Потому что все переменные в коде VBScript "оборачиваются" в Variant (Универсальный тип хранения данных), а судя по описанию метода этой библиотеки, она требует для outcert только BSTR и требуется передать указатель на указатель. А передать ей из VBScript BSTR, Вы можете только по значению ByVal, но не по ссылке ByRef.

Вариантов решения несколько:
1) Если доступен исходный код библиотеки, то исправить тип параметра outcert, возвращающий данные на Variant.
2) Написать оболочку ActiveX Wrapper на эту библиотеку и там пофиксить передачу параметра.
3) Сменить язык программирования на VBA или AutoIt или AHK. Словом на язык, где можно явно указывать тип переменной.
4) Как правильно заметил коллега wisgest, неплохо бы попробовать поковырять TLB от этой библиотеки, попробовать изменить тип параметра в ней и перекомпилить TLB.
5) Отказаться от идеи использовать этот COM, и взять другой, который адаптирован к работе с VBS / JS. Возможно CAPICOM Вам поможет ?
6) Судя по фрагментам кода, Вы хотите что-то делать с сертификатами p12 PKCS12. Если так, то на VBS вполне можно сделать обёртку на утилиту openssl

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

20

Re: VBS: Функции COM-библиотеки в VBScript

Xameleon
Добрый день! Спасибо за столь развернутый ответ!

она требует для outcert только BSTR

Да. Необходимо, чтобы была string-овая переменная. Вот например в других языках я отправлял вот так:

Вот на PHP:
$PHP_LIB->X509ExportCertificateFromStore($alias, $Flags, &$outCert);

Вот на c#
Hybrid.X509ExportCertificateFromStore(alias, (uint)Flags, out outCert);

Вот на GoLang:
oleutil.MustCallMethod(comtest, "X509ExportCertificateFromStore", "", 0, &outCert).ToIDispatch()

Вот на Python:
outCert = Hybrid.X509ExportCertificateFromStore(alias, 0)

Я не могу изменять код библиотеки. И не могу выбрать другой язык) Да, работаю с сертификатами, только уже с готовой COM-библиотекой. Эта библиотека уже есть обертка для openssl (openssl здесь изменили и добавили свои методы).
Про враппер на ActivX даже не слышал) Попробую поискать...

21

Re: VBS: Функции COM-библиотеки в VBScript

А что разработчик-то библиотеки, уже умер?

22

Re: VBS: Функции COM-библиотеки в VBScript

YMP

А что разработчик-то библиотеки, уже умер?

Не дай Бог!
Разработчики сказали, что менять библиотеку не будут. Тип много компаний работают именно с этой библиотекой. И только ради VBS отдельно заниматься поддержкой новой библиотеки они не будут. Так что я пытаюсь работать с тем, что есть)

23

Re: VBS: Функции COM-библиотеки в VBScript

don_777_11,

1) Саму библиотеку увидеть можно ? Или есть хотя бы полная документация по ней ?
2) Поясните, почему нет возможности выбрать другой язык ?
3) Какая конечная цель обёртки в VBS ? Расскажите подробнее о конечной цели.
4) Сделал поиск по progid библиотеки в google. Нашёл следующие результаты:

Сообщение от miskiv_danil за 11.01.2019, 07:33
http://www.cyberforum.ru/post13231332.html

Сообщение от Danil_lll за 14.08.2018 - 15:28
http://www.phpforum.su/index.php?showtopic=93724

Сообщение от user1036472 за 22.08.18 08:33
http://forum.infostart.ru/forum9/topic6 … age2034870

Сообщение от Danil за 22 авг '18 в 6:30
https://ru.stackoverflow.com/questions/ … %D0%B2-php

Из увиденного позволил себе сделать вывод, что либо множество "Даниилов" ещё с августа 2018 ищут ответ на свой вопрос, штурмуя форумы либо это один человек, которому эта задача не даёт покоя. Но ответ до сих пор не найден.

Возвращаясь к вопросу о коде. Здесь Danil_lll, даже приводит часть кода модулей на C, т.е есть исходник.

http://phpforum.su/index.php?s=7e464b4b … mp;limit=1

Так может есть возможность пересобрать библиотеку ?

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

24

Re: VBS: Функции COM-библиотеки в VBScript

Xameleon
1) Саму библиотеку не имею права распространять... Подсудное дело
2) Потому что мне дали план работы на 1 квартал. Там и было, написать на VBS обёртку к COM
3) Конечная цель: создать обертку и отправить всем, кто просит примеры по работе с COM на VBS... Т.е. что не получилось у других, должен придумать я) Хотя никогда с этим не работал...

До этого реализовал примеры на других языках (PHP, Python, GO), подключалось, вызывалось без проблем) А вот с этой задачей что-то загвоздка у меня получилась...

Получается мне нужна обёртка на другом языке (например на C#), в которой будут функции возвращать указатель на строку?

25

Re: VBS: Функции COM-библиотеки в VBScript

don_777_11,

Тогда "копнём глубже". Какие функции и методы должна реализовать обёртка на VBS ?

Получается мне нужна обёртка на другом языке (например на C#), в которой будут функции возвращать указатель на строку?

Подойдёт обёртка на любом другом языке, которая позволит
1) принять на вход Variant по указателю
2) взять из него значение
3) Создать BSTR переменную и положить в неё принятое значение
4) Сделать вызов функции и передать туда созданную переменную
5) Взять заполненное значение из BSTR переменной и положить обратно в Variant, чтобы отдать её на выход

Это один из вариантов реализации. Внешний интерфейс может быть и другим.

Предполагаю, что на VBA / VB6 это выглядело бы как-то так. Возможности проверить нет, поэтому на 100% уверен быть не могу.


Function X509ExportCertificateFromStore(ByVal alias As String, ByVal Flags As Long, ByRef outCert As Variant) As Long
    Dim outCert_BSTR As String
    'Положили из outCert значение в подготовленную переменную нужного типа
    outCert_BSTR = outCert
    'Вызвали функцию
    X509ExportCertificateFromStore = Hybrid.X509ExportCertificateFromStore(alias, Flags, outCert_BSTR)
    'Вернули в параметр, полученное значение
    outCert = outCert_BSTR
End Function

Возможно ещё потребуется заполнить outCert_BSTR пробелами, для выделения пространства под значение. Хотя по хорошему вместо String нужно использовать Byte(). Но это всё можно определить, когда уже будет с чем работать.

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

26

Re: VBS: Функции COM-библиотеки в VBScript

Xameleon

штурмуя форумы либо это один человек, которому эта задача не даёт покоя. Но ответ до сих пор не найден.

Все верно! Это один человек) Я!
В августе стояла задача написать на PHP. Также мучился, искал ходы и варианты.
Сейчас на VBS....

Какие функции и методы должна реализовать обёртка на VBS ?

Все методы, которые присутствуют в библиотеке... Они все COM-овские.

Получается так:


Set FSO = CreateObject(HybridCOMLib.HybridCOM") 			' Подключаю библиотеку
FSO.Init() 													'Вызываю первую функцию, которая  как бы проверяет подключение библиотеки
er = FSO.LoadKeyStore(1, "Pasword", "C:\1.p12") 			'Затем вызываю функцию, в которой подключаю сертификат и ввожу его пароль. Сертификат записывается в ОП
er = FSO.X509ExportCertificateFromStore("", 0, (outCert)) 	' Эта функция должна вывести сертификат из ОП. Т.е. просто передать его в переменную outCert

И еще таких функций больше 30 штук различного рода...
Но у всех одинаковый интерфейс в COM-e.
(STDMETHODIMP HybridCOM::Имя_функции(INT variable1, BSTR* variable2 или BSTR variable2...)  и так далее и тому подобное)
Сейчас у меня именно не получается возвращать(перезаписывать значения переменных)

27

Re: VBS: Функции COM-библиотеки в VBScript

Xameleon

Function X509ExportCertificateFromStore(ByVal alias As String, ByVal Flags As Long, ByRef outCert As Variant) As Long
    Dim outCert_BSTR As String
    'Положили из outCert значение в подготовленную переменную нужного типа
    outCert_BSTR = outCert
    'Вызвали функцию
    X509ExportCertificateFromStore = Hybrid.X509ExportCertificateFromStore(alias, Flags, outCert_BSTR)
    'Вернули в параметр, полученное значение
    outCert = outCert_BSTR
End Function

Здорово! Спасибо за "пинок") Как запущу, так сразу отпишусь)

28

Re: VBS: Функции COM-библиотеки в VBScript

don_777_11,

Все методы, которые присутствуют в библиотеке... Они все COM-овские.

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

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

1) Создавать ActiveX обёртку на библиотеку. Это значит, что Вам нужно на любом доступном Вам языке программирования скомпилировать компонент реализующий тот принцип оборачивания, который я привёл примером в сообщении выше. При этом исходный COM объект может создаваться внутри обёртки, может передаваться извне. Тут как Вам удобно.

2) Можно попробовать написать универсальный Wrapper, позволяющий на вход принимать ссылку на объект, а дальше через специальный интерфейс подготавливать для него параметры и методом типа CallFunction(...) вызывать у объекта его функции и методы. Звучит не совсем понятно. Проще - посмотрите в интернете DynamicWrapperX от уважаемого коллеги YMP.  К сожалению, на сколько мне известно, его Wrapper не умеет работать с внешними COM объектами для вызова их методов через прослойку, а только с stdcall и cdecl функциями в библиотеках.

(*) Но надо понимать, что при выборе первого и второго варианта каждый пользователь обречён на регистрацию этого компонента-обёртки у себя в реестре. Т.е это уже не portable решение (не так, что скопировал, запустил и работает.). Либо придётся заморачиваться с манифестами... А это уже совсем другая история.

3) В принципе, возможно реализовать EXE wrapper на COM библиотеку и общаться с ним через StdIn и StdOut....А уже обмен обернуть в VBS вызовы. Но это такой изврат, который Маркизу де Саду даже не снился. Зато такой вариант не требует регистрации чего-либо в реестре.

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

29

Re: VBS: Функции COM-библиотеки в VBScript

Xameleon пишет:

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

Может быть, dll промежуточного объекта подсовывать вместо dll основного, соответственно она будет загружаться по CreateObject, а потом уже будет загружать основную dll и создавать основной объект. Это уже, конечно, тоже махинации. Можно, наверно, основную dll засунуть в ресурсы обёртки и загружать оттуда. Вроде бы есть какой-то способ.

30

Re: VBS: Функции COM-библиотеки в VBScript

YMP,

Может быть, dll промежуточного объекта подсовывать вместо dll основного, соответственно она будет загружаться по CreateObject, а потом уже будет загружать основную dll и создавать основной объект.

Тогда возникает вопрос как создавать инстанс исходного компонента в оболочке ). Ведь обычный вызов CoCreateInstance обратится в реестр, там найдёт путь до DLL и попробует создать её от туда, а там лежит наша DLL. )

Помню был вариант на форуме VBStreets. Приходилось делать хук - перехват API, подменять данные... Но это черевато большими косяками в работе.

Можно, наверно, основную dll засунуть в ресурсы обёртки и загружать оттуда. Вроде бы есть какой-то способ.

+ открыть спойлер

https://cs.pikabu.ru/images/big_size_comm/2013-09_1/13783048769859.jpeg

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

31

Re: VBS: Функции COM-библиотеки в VBScript

Xameleon

Получилось вывести сертификат. Даже не изменяя предложенной вами функции) Огромное спасибо!
Значит буду писать обёртку.

Пока вопросов больше нет.
Очень благодарен за оказанное внимание и советы!

32

Re: VBS: Функции COM-библиотеки в VBScript

don_777_11,

Получилось вывести сертификат. Даже не изменяя предложенной вами функции) Огромное спасибо!
Значит буду писать обёртку.

Чудеса ). Неожиданно. А на чём собираетесь обёртку писать, если не секрет ?

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

33

Re: VBS: Функции COM-библиотеки в VBScript

Xameleon пишет:

Тогда возникает вопрос как создавать инстанс исходного компонента в оболочке ). Ведь обычный вызов CoCreateInstance обратится в реестр, там найдёт путь до DLL и попробует создать её от туда, а там лежит наша DLL. )

Так для этого же dll и экспортирует функцию DllGetClassObject. Из неё получаем объект ClassFactory и создаём объект нужного класса методом CreateInstance. То же самое делает CoCreateInstance.

Xameleon пишет:

Помню был вариант на форуме VBStreets. Приходилось делать хук - перехват API, подменять данные...

+ открыть спойлер

https://cs.pikabu.ru/images/big_size_comm/2013-09_1/13783048769859.jpeg


Хотя, может, там всё же что-то другое было.

34

Re: VBS: Функции COM-библиотеки в VBScript

YMP,

Так для этого же dll и экспортирует функцию DllGetClassObject. Из неё получаем объект ClassFactory и создаём объект нужного класса методом CreateInstance. То же самое делает CoCreateInstance.

Кривить душой не буду. Сам не пробовал. )) Возможно и так как Вы говорите можно реализовать.

Порылся на форуме, нашёл - http://bbs.vbstreets.ru/viewtopic.php?f=28&t=45527. Вроде бы оно

Если открыть архив, то в коде модуля modTrickUnregControl.bas, автор пишет:

' Функция перехвата CLSIDFromProgID
' При передаче нашего ProgID мы обманываем вызывающую сторону, делая вид что в реестре есть запись HKCR\CLSID\ProgID\CLSID

' Функция перехвата CoGetClassObject
' Здесь мы создаем объект (обычно фабрики классов), используя не запись в реестра, а переданные параметры для имени библиотеки

' Функция перехвата OleRegGetMiscStatus
' Здесь мы обманываем вызывающую строну, делая вид что в реестре есть запись HKCR\CLSID\MiscStatus и подсовываем ей свой

' Функция перехвата RegQueryValue
' Здесь мы обманываем вызывающую строну, делая вид что в реестре есть записи HKCR\CLSID\(TypeLib, InprocServer32, Version) и подсовываем ей свой

Вот об этом я и вспомнил. )

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

35

Re: VBS: Функции COM-библиотеки в VBScript

Ну, там задача явно более масштабная.

создание условий при которых VB "думает" что библиотека зарегистрирована.

А здесь-то она зарегистрирована, так что ситуация другая. Имитировать наличие записей в реестре не нужно. VBS всего лишь запросит IDispatch, который обёртка ему и выдаст. А основной объект создаст сама. Механизм, описанный мной, работает, мне ведь пришлось его реализовывать в DWX. Никаких шорткатов от системы я не использовал. IClassFactory, IUnknown, IDispatch — всё ручной работы.

36

Re: VBS: Функции COM-библиотеки в VBScript

YMP, Хм... Вот как. А зачем такая возможность понадобилась в DWX, если не секрет ?

А здесь-то она зарегистрирована, так что ситуация другая. Имитировать наличие записей в реестре не нужно.

Да, библиотека то зарегистрирована, но пути то тогда будут смотреть на подменённую DLL ? Но если создавать, как Вы говорите, то получается при этом можно как-то напрямую указывать путь до нужного DLL ?

Не совсем понимаю как, если

STDAPI DllGetClassObject

REFCLSID rclsid,  // Уникальный идентификатор объекта
REFIID riid,      // Ссылка на интерфейс связанный с объектом
LPVOID * ppv      // адрес переменной которая получит интерфейс
);

Функция на вход же принимает rclsid ?

Попробую более подробно пояснить, что мне пока непонятно.

Представим:
У нас имеется некая COM.dll, сделанная сторонним разработчиком (будем называть её сторонняя).
Мы делаем свою COM.dll обёртку (будем называть её наша)

Изначально регистрируем стороннюю COM.dll через regsvr32.
Получаем в реестре некие записи:
HKEY_CLASSES_ROOT\COM.Object\CLSID c параметром REG_SZ и некоторым классидом (Например:{0E57F1D5-1FСE-11D0-8FF2-00A0В10018BC})
и
HKEY_CLASSES_ROOT\CLSID\{0E57F1D5-1FСE-11D0-8FF2-00A0В10018BC}
в которой несколько подразделов отвечающих за информацию о компоненте в числе которых подраздел InProcServer32, который содержит параметр по умолчанию REG_SZ с путём до зарегистрированной DLL - (например:C:\MyActiveX\COM.dll)

Теперь мы берём и подменяем зарегистрированную DLL на нашу, а исходную называем COM1.dll
Получаем:
C:\MyActiveX\COM.dll - наша DLL
C:\MyActiveX\COM1.dll - переименованная сторонняя DLL

Теперь, к примеру, в скрипте выполняем CreateObject("COM.Object")

По идее должен создаться наш компонент оболочки, если описание в ветках реестра не противоречит описанию объекта внутри DLL.
Далее, как Вы говорите, мы должны вызвать DllGetClassObject ? Я пока не имел опыта работы с ней и сейчас поиск в гугл не дал мне понятного ответа.
Но я так понимаю, что она должна обратиться в реестр для получения информации по переданному classid-у, а там путь, указывающий на "C:\MyActiveX\COM.dll". Т.е на нашу DLL ?
Или всё работает иначе и я ошибаюсь ?

(*) Ааа.... Кажется понял...

Первым делом вызывается CoLoadLibrary или LoadLibrary для подгрузки библиотеки в память, далее получаем указатель на экспортируемую DllGetClassObject и передаём ей классид создаваемого объекта ? И по идее ей тогда в реестр обращаться нет нужды ?

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

37

Re: VBS: Функции COM-библиотеки в VBScript

Xameleon
Всё верно. Обёртка же по идее уже знает, где лежит основная dll и знает CLSID нужного объекта и ID нужного интерфейса. Реестр ей не нужен. А создавая основной объект, она взаимодействует только с кодом внутри основной dll и получает от неё объект. Основной dll реестр для этого тоже ни к чему, она и так про себя всё знает.

Насчёт

REFIID riid,      // Ссылка на интерфейс связанный с объектом

уточню, что тут передаётся ID нужного интерфейса ClassFactory (есть просто IClassFactory и есть более продвинутый IClassFactory2), а не интерфейса того объекта, чей ID в rclsid. Интерфейс объекта запрашивается уже потом, в методе CreateInstance.

38 (изменено: YMP, 2019-01-18 20:32:38)

Re: VBS: Функции COM-библиотеки в VBScript

Кстати, при создании объекта нужно ещё его ThreadingModel учитывать. Не должно быть противоречия с той, что была указана в CoInitializeEx потока, где работает создающий объект код. Иначе, я так понимаю, для объекта нужно создавать отдельный поток с соответствующей ему инициализацией COM.

39

Re: VBS: Функции COM-библиотеки в VBScript

YMP, да, именно так. Вот я как раз об этом и думал, когда написал

По идее должен создаться наш компонент оболочки, если описание в ветках реестра не противоречит описанию объекта внутри DLL.

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

40

Re: VBS: Функции COM-библиотеки в VBScript

Хотя, если обёртка именно подсовывается вместо, то она будет создана системой с учётом записей в реестре для основного объекта, так что ThreadingModel потока будет правильной. Я скорее подумал о создании объекта, в реестре не записанного, где уже мы должны помнить о его особенностях. Но это же не наш случай.

41

Re: VBS: Функции COM-библиотеки в VBScript

Могу ошибаться, подтверждения в инете не нашёл, но мне всегда казалось, что ThreadingModel задаётся для DLL при компиляции и по идее если в реестре будет указана иная ThreadingModel, то может не работать ?

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

42

Re: VBS: Функции COM-библиотеки в VBScript

Если однопоточный объект заявит себя многопоточным, то могут быть проблемы, конечно, т.к. он же не умеет разруливать одновременные вызовы из разных потоков. При обратной ситуации проблем не должно быть, по идее.

Хотя я тут, похоже, не знаю каких-то тонкостей, т.к. не понимаю, зачем нужна поточная модель "both". Казалось бы, если объект многопоточный, то и шабаш. Чего ещё надо-то? Зачем специально указывать ещё и возможность работы в однопоточном апартменте? Что-то тут нечисто. Казалось бы это само собой разумеется, но нет, зачем-то указывают. Какую способность объекта это предполагает? Непонятно.

43

Re: VBS: Функции COM-библиотеки в VBScript

https://rsdn.org/article/com/apartmnt.xml.

Вот тут хорошо расписано. Я даже вроде бы понял. ) Хотел коротко пояснить, но чую, что буду дублировать статью.

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

44 (изменено: YMP, 2019-01-20 20:21:14)

Re: VBS: Функции COM-библиотеки в VBScript

Спасибо, хорошая статья.

ПРИМЕЧАНИЕ
COM старается помещать внутрипроцессные объекты в то же подразделение, что и у создающих их потоков.

Т.е. те, кто помечает свои многопоточные объекты как "free", почему-то не желают, чтобы они создавались в STA. Наверно, просто хотят избежать затрат на системный маршалинг вызовов, который их объектам не нужен.

А вот это мне как-то не приходило в голову:

Даже ThreadingModel=Apartment объекты должны быть "немного потокобезопасными", поскольку ThreadingModel=Apartment не мешает нескольким объектам созданным в одной DLL ссориться из-за разделяемых данных (в случае, если они попадут в разные STA).

Вот ещё важная вещь:

Некоторые программисты используют локальную память потока (TLS) как временное хранилище данных. Предположим, вы реализуете COM метод и вам нужно сохранить некоторую информацию о текущем вызове и которая понадобится при следующем вызове. Вы можете воспользоваться TLS. И в STA это будет работать. Но если объект, который вы пишете находится в MTA, вы должны избегать TLS как чумы.

Почему? Потому что вызов, попадающий в MTA перемещается в RPC потоки. Каждый вызов запросто может попасть в различные RPC потоки, даже если все они были из одного потока и одного и того же подразделения. Поток B не имеет доступа к локальной памяти потока A, так что если вызов номер 1 попадает в поток A и объект помещает данные в TLS, то если вызов номер 2 попадает в поток B и объект пытается получить данные записанные в TLS при первом вызове, он их не получит. Никак.

Избегайте использовать TLS для сохранения данных между вызовами MTA-шных объектов. Это будет работать, только если все вызовы придут из одного и того же объекта и из того же самого MTA, в котором находится объект.

У меня в TLS может храниться код последней ошибки, возвращаемый вызовом GetLastError после вызова API-функции. Его потом можно запросить, вызвав метод LastError.

Конечно, в VBS и JS, выполняемых Windows Script Host, DWX в MTA не попадёт. Но теоретически, т.к. он вообще-то потокобезопасный (2-я версия), где-то и когда-то может попасть. При этом, правда, ещё надо, чтобы его вызывали из STA. Довольно сложный сценарий.

45

Re: VBS: Функции COM-библиотеки в VBScript

Xameleon
Добрый день.  Я просто решил писать на VBA (Оказалось, что никому это не важно...). Просто объявляю переменную и обозначаю ее тип.
Т.е. я просто прописал так:

Dim outCert As String
err = HCL.X509ExportCertificateFromStore("", 0, outCert)

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

46

Re: VBS: Функции COM-библиотеки в VBScript

Xameleon
Кстати, еще появился такой вопрос.
Типа LongLong в VB нет?

В СИ++ время в секундах с 1970 года передается как LongLong (Это время может быть разным - и 2,365e+9(2045 год), и 1,104e+9 (2005 год))
Получается для хранения таких больших переменных что можно использовать в VB?

47

Re: VBS: Функции COM-библиотеки в VBScript

Хм. Тут надо экспериментировать.

Вот справочник по типам переменных в VB
http://www.codenet.ru/progr/vbasic/bit/Variables.php

Для того, чтобы VBScript адекватно принял дату, ему на выход нужен либо сразу Date, либо Date возвращённый через Variant, как в примере Выше, если отдавать через параметры. Я бы попробовал поэкспериментировать с ним (Date), а потом уж если не сложится, то попробовать универсальный вариант - буфер Byte().

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