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(). Но это всё можно определить, когда уже будет с чем работать.

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