<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; VBS: Функции COM-библиотеки в VBScript]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=14494&amp;type=atom" />
	<updated>2019-01-24T15:40:28Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/viewtopic.php?id=14494</id>
		<entry>
			<title type="html"><![CDATA[Re: VBS: Функции COM-библиотеки в VBScript]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=131575#p131575" />
			<content type="html"><![CDATA[<p>Хм. Тут надо экспериментировать.</p><p>Вот справочник по типам переменных в VB<br /><a href="http://www.codenet.ru/progr/vbasic/bit/Variables.php">http://www.codenet.ru/progr/vbasic/bit/Variables.php</a></p><p>Для того, чтобы VBScript адекватно принял дату, ему на выход нужен либо сразу Date, либо Date возвращённый через Variant, как в примере Выше, если отдавать через параметры. Я бы попробовал поэкспериментировать с ним (Date), а потом уж если не сложится, то попробовать универсальный вариант - буфер Byte().</p>]]></content>
			<author>
				<name><![CDATA[Xameleon]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=8836</uri>
			</author>
			<updated>2019-01-24T15:40:28Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=131575#p131575</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBS: Функции COM-библиотеки в VBScript]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=131562#p131562" />
			<content type="html"><![CDATA[<p><strong>Xameleon</strong><br />Кстати, еще появился такой вопрос. <br />Типа LongLong в VB нет? </p><p>В СИ++ время в секундах с 1970 года передается как LongLong (Это время может быть разным - и 2,365e+9(2045 год), и 1,104e+9 (2005 год)) <br />Получается для хранения таких больших переменных что можно использовать в VB?</p>]]></content>
			<author>
				<name><![CDATA[don_777_11]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=39892</uri>
			</author>
			<updated>2019-01-24T12:29:38Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=131562#p131562</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBS: Функции COM-библиотеки в VBScript]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=131561#p131561" />
			<content type="html"><![CDATA[<p><strong>Xameleon</strong><br />Добрый день.&nbsp; Я просто решил писать на VBA (Оказалось, что никому это не важно...). Просто объявляю переменную и обозначаю ее тип.<br />Т.е. я просто прописал так: <br /></p><div class="codebox"><pre><code>Dim outCert As String
err = HCL.X509ExportCertificateFromStore(&quot;&quot;, 0, outCert)</code></pre></div><p>Ну вот сейчас принимаюсь за создание всего кода. Думаю теперь особых проблем не должно быть)<br />Спасибо большое за советы) Обычно у меня так всегда, нужен небольшой пинок)</p>]]></content>
			<author>
				<name><![CDATA[don_777_11]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=39892</uri>
			</author>
			<updated>2019-01-24T12:28:33Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=131561#p131561</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBS: Функции COM-библиотеки в VBScript]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=131452#p131452" />
			<content type="html"><![CDATA[<p>Спасибо, хорошая статья.<br /></p><div class="quotebox"><blockquote><p>ПРИМЕЧАНИЕ<br />COM старается помещать внутрипроцессные объекты в то же подразделение, что и у создающих их потоков.</p></blockquote></div><p>Т.е. те, кто помечает свои многопоточные объекты как &quot;free&quot;, почему-то не желают, чтобы они создавались в STA. Наверно, просто хотят избежать затрат на системный маршалинг вызовов, который их объектам не нужен.</p><p>А вот это мне как-то не приходило в голову:<br /></p><div class="quotebox"><blockquote><p>Даже ThreadingModel=Apartment объекты должны быть &quot;немного потокобезопасными&quot;, поскольку ThreadingModel=Apartment не мешает нескольким объектам созданным в одной DLL ссориться из-за разделяемых данных (в случае, если они попадут в разные STA).</p></blockquote></div><p>Вот ещё важная вещь:<br /></p><div class="quotebox"><blockquote><p>Некоторые программисты используют локальную память потока (TLS) как временное хранилище данных. Предположим, вы реализуете COM метод и вам нужно сохранить некоторую информацию о текущем вызове и которая понадобится при следующем вызове. Вы можете воспользоваться TLS. И в STA это будет работать. Но если объект, который вы пишете находится в MTA, вы должны избегать TLS как чумы.</p><p>Почему? Потому что вызов, попадающий в MTA перемещается в RPC потоки. Каждый вызов запросто может попасть в различные RPC потоки, даже если все они были из одного потока и одного и того же подразделения. Поток B не имеет доступа к локальной памяти потока A, так что если вызов номер 1 попадает в поток A и объект помещает данные в TLS, то если вызов номер 2 попадает в поток B и объект пытается получить данные записанные в TLS при первом вызове, он их не получит. Никак.</p><p>Избегайте использовать TLS для сохранения данных между вызовами MTA-шных объектов. Это будет работать, только если все вызовы придут из одного и того же объекта и из того же самого MTA, в котором находится объект.</p></blockquote></div><p>У меня в TLS может храниться код последней ошибки, возвращаемый вызовом GetLastError после вызова API-функции. Его потом можно запросить, вызвав метод LastError.</p><p>Конечно, в VBS и JS, выполняемых Windows Script Host, DWX в MTA не попадёт. Но теоретически, т.к. он вообще-то потокобезопасный (2-я версия), где-то и когда-то может попасть. При этом, правда, ещё надо, чтобы его вызывали из STA. Довольно сложный сценарий.</p>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2019-01-20T16:11:53Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=131452#p131452</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBS: Функции COM-библиотеки в VBScript]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=131450#p131450" />
			<content type="html"><![CDATA[<p><a href="https://rsdn.org/article/com/apartmnt.xml">https://rsdn.org/article/com/apartmnt.xml</a>.</p><p>Вот тут хорошо расписано. Я даже вроде бы понял. ) Хотел коротко пояснить, но чую, что буду дублировать статью.</p>]]></content>
			<author>
				<name><![CDATA[Xameleon]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=8836</uri>
			</author>
			<updated>2019-01-20T14:48:28Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=131450#p131450</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBS: Функции COM-библиотеки в VBScript]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=131447#p131447" />
			<content type="html"><![CDATA[<p>Если однопоточный объект заявит себя многопоточным, то могут быть проблемы, конечно, т.к. он же не умеет разруливать одновременные вызовы из разных потоков. При обратной ситуации проблем не должно быть, по идее.</p><p>Хотя я тут, похоже, не знаю каких-то тонкостей, т.к. не понимаю, зачем нужна поточная модель &quot;both&quot;. Казалось бы, если объект многопоточный, то и шабаш. Чего ещё надо-то? Зачем специально указывать ещё и возможность работы в однопоточном апартменте? Что-то тут нечисто. Казалось бы это само собой разумеется, но нет, зачем-то указывают. Какую способность объекта это предполагает? Непонятно. <img src="//forum.script-coding.com/img/smilies/roll.png" width="15" height="15" /></p>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2019-01-20T12:24:31Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=131447#p131447</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBS: Функции COM-библиотеки в VBScript]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=131445#p131445" />
			<content type="html"><![CDATA[<p>Могу ошибаться, подтверждения в инете не нашёл, но мне всегда казалось, что ThreadingModel задаётся для DLL при компиляции и по идее если в реестре будет указана иная ThreadingModel, то может не работать ?</p>]]></content>
			<author>
				<name><![CDATA[Xameleon]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=8836</uri>
			</author>
			<updated>2019-01-20T08:26:27Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=131445#p131445</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBS: Функции COM-библиотеки в VBScript]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=131432#p131432" />
			<content type="html"><![CDATA[<p>Хотя, если обёртка именно подсовывается вместо, то она будет создана системой с учётом записей в реестре для основного объекта, так что ThreadingModel потока будет правильной. Я скорее подумал о создании объекта, в реестре не записанного, где уже мы должны помнить о его особенностях. Но это же не наш случай. <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2019-01-19T03:10:02Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=131432#p131432</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBS: Функции COM-библиотеки в VBScript]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=131424#p131424" />
			<content type="html"><![CDATA[<p><strong>YMP</strong>, да, именно так. Вот я как раз об этом и думал, когда написал<br /></p><div class="quotebox"><blockquote><p>По идее должен создаться наш компонент оболочки, если описание в ветках реестра не противоречит описанию объекта внутри DLL.</p></blockquote></div>]]></content>
			<author>
				<name><![CDATA[Xameleon]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=8836</uri>
			</author>
			<updated>2019-01-18T17:02:58Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=131424#p131424</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBS: Функции COM-библиотеки в VBScript]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=131421#p131421" />
			<content type="html"><![CDATA[<p>Кстати, при создании объекта нужно ещё его ThreadingModel учитывать. Не должно быть противоречия с той, что была указана в CoInitializeEx потока, где работает создающий объект код. Иначе, я так понимаю, для объекта нужно создавать отдельный поток с соответствующей ему инициализацией COM.</p>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2019-01-18T16:31:51Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=131421#p131421</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBS: Функции COM-библиотеки в VBScript]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=131419#p131419" />
			<content type="html"><![CDATA[<p><strong>Xameleon</strong><br />Всё верно. Обёртка же по идее уже знает, где лежит основная dll и знает CLSID нужного объекта и ID нужного интерфейса. Реестр ей не нужен. А создавая основной объект, она взаимодействует только с кодом внутри основной dll и получает от неё объект. Основной dll реестр для этого тоже ни к чему, она и так про себя всё знает.</p><p>Насчёт<br /></p><div class="codebox"><pre><code>REFIID riid,      // Ссылка на интерфейс связанный с объектом</code></pre></div><p>уточню, что тут передаётся ID нужного интерфейса ClassFactory (есть просто IClassFactory и есть более продвинутый IClassFactory2), а не интерфейса того объекта, чей ID в rclsid. Интерфейс объекта запрашивается уже потом, в методе CreateInstance.</p>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2019-01-18T15:32:58Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=131419#p131419</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBS: Функции COM-библиотеки в VBScript]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=131414#p131414" />
			<content type="html"><![CDATA[<p><strong>YMP</strong>, Хм... Вот как. А зачем такая возможность понадобилась в DWX, если не секрет ?</p><div class="quotebox"><blockquote><p>А здесь-то она зарегистрирована, так что ситуация другая. Имитировать наличие записей в реестре не нужно.</p></blockquote></div><p>Да, библиотека то зарегистрирована, но пути то тогда будут смотреть на подменённую DLL ? Но если создавать, как Вы говорите, то получается при этом можно как-то напрямую указывать путь до нужного DLL ?</p><p>Не совсем понимаю как, если </p><div class="quotebox"><blockquote><p>STDAPI DllGetClassObject<br />(&nbsp; <br />	REFCLSID rclsid,&nbsp; // Уникальный идентификатор объекта<br />	REFIID riid,&nbsp; &nbsp; &nbsp; // Ссылка на интерфейс связанный с объектом<br />	LPVOID * ppv&nbsp; &nbsp; &nbsp; // адрес переменной которая получит интерфейс<br />);</p></blockquote></div><p>Функция на вход же принимает <strong>rclsid</strong> ?</p><p>Попробую более подробно пояснить, что мне пока непонятно.</p><p>Представим:<br />У нас имеется некая COM.dll, сделанная сторонним разработчиком (будем называть её сторонняя).<br />Мы делаем свою COM.dll обёртку (будем называть её наша)</p><p>Изначально регистрируем стороннюю COM.dll через regsvr32.<br />Получаем в реестре некие записи: <br />	HKEY_CLASSES_ROOT\COM.Object\CLSID c параметром REG_SZ и некоторым классидом (Например:{0E57F1D5-1FСE-11D0-8FF2-00A0В10018BC})<br />и <br />	HKEY_CLASSES_ROOT\CLSID\{0E57F1D5-1FСE-11D0-8FF2-00A0В10018BC}<br />в которой несколько подразделов отвечающих за информацию о компоненте в числе которых подраздел <strong>InProcServer32</strong>, который содержит параметр по умолчанию REG_SZ с путём до зарегистрированной DLL - (например:C:\MyActiveX\COM.dll)</p><p>Теперь мы берём и подменяем зарегистрированную DLL на нашу, а исходную называем COM1.dll<br />Получаем:<br />	C:\MyActiveX\COM.dll - наша DLL<br />	C:\MyActiveX\COM1.dll - переименованная сторонняя DLL </p><p>Теперь, к примеру, в скрипте выполняем CreateObject(&quot;COM.Object&quot;)</p><p>По идее должен создаться наш компонент оболочки, если описание в ветках реестра не противоречит описанию объекта внутри DLL.<br />Далее, как Вы говорите, мы должны вызвать DllGetClassObject ? Я пока не имел опыта работы с ней и сейчас поиск в гугл не дал мне понятного ответа.<br />Но я так понимаю, что она должна обратиться в реестр для получения информации по переданному classid-у, а там путь, указывающий на &quot;C:\MyActiveX\COM.dll&quot;. Т.е на нашу DLL ?<br />Или всё работает иначе и я ошибаюсь ?</p><p><strong>(*) Ааа.... Кажется понял...</strong></p><p>Первым делом вызывается CoLoadLibrary или LoadLibrary для подгрузки библиотеки в память, далее получаем указатель на экспортируемую DllGetClassObject и передаём ей классид создаваемого объекта ? И по идее ей тогда в реестр обращаться нет нужды ?</p>]]></content>
			<author>
				<name><![CDATA[Xameleon]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=8836</uri>
			</author>
			<updated>2019-01-18T13:58:37Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=131414#p131414</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBS: Функции COM-библиотеки в VBScript]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=131413#p131413" />
			<content type="html"><![CDATA[<p>Ну, там задача явно более масштабная.<br /></p><div class="quotebox"><blockquote><p>создание условий при которых VB &quot;думает&quot; что библиотека зарегистрирована.</p></blockquote></div><p>А здесь-то она зарегистрирована, так что ситуация другая. Имитировать наличие записей в реестре не нужно. VBS всего лишь запросит IDispatch, который обёртка ему и выдаст. А основной объект создаст сама. Механизм, описанный мной, работает, мне ведь пришлось его реализовывать в DWX. Никаких шорткатов от системы я не использовал. IClassFactory, IUnknown, IDispatch — всё ручной работы. <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2019-01-18T13:53:06Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=131413#p131413</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBS: Функции COM-библиотеки в VBScript]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=131411#p131411" />
			<content type="html"><![CDATA[<p><strong>YMP</strong>,</p><div class="quotebox"><blockquote><p>Так для этого же dll и экспортирует функцию DllGetClassObject. Из неё получаем объект ClassFactory и создаём объект нужного класса методом CreateInstance. То же самое делает CoCreateInstance.</p></blockquote></div><p>Кривить душой не буду. Сам не пробовал. )) Возможно и так как Вы говорите можно реализовать.</p><p>Порылся на форуме, нашёл - <a href="http://bbs.vbstreets.ru/viewtopic.php?f=28&amp;t=45527">http://bbs.vbstreets.ru/viewtopic.php?f=28&amp;t=45527</a>. Вроде бы оно</p><p>Если открыть архив, то в коде модуля modTrickUnregControl.bas, автор пишет:<br /></p><div class="quotebox"><blockquote><p>&#039; Функция перехвата CLSIDFromProgID<br />&#039; При передаче нашего ProgID мы обманываем вызывающую сторону, делая вид что в реестре есть запись HKCR\CLSID\ProgID\CLSID</p><p>&#039; Функция перехвата CoGetClassObject<br />&#039; <strong>Здесь мы создаем объект (обычно фабрики классов), используя не запись в реестра, а переданные параметры для имени библиотеки</strong></p><p>&#039; Функция перехвата OleRegGetMiscStatus<br />&#039; <strong>Здесь мы обманываем вызывающую строну, делая вид что в реестре есть запись HKCR\CLSID\MiscStatus и подсовываем ей свой</strong></p><p>&#039; Функция перехвата RegQueryValue<br />&#039; <strong>Здесь мы обманываем вызывающую строну, делая вид что в реестре есть записи HKCR\CLSID\(TypeLib, InprocServer32, Version) и подсовываем ей свой</strong></p></blockquote></div><p>Вот об этом я и вспомнил. )</p>]]></content>
			<author>
				<name><![CDATA[Xameleon]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=8836</uri>
			</author>
			<updated>2019-01-18T13:10:28Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=131411#p131411</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBS: Функции COM-библиотеки в VBScript]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=131410#p131410" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>Xameleon пишет:</cite><blockquote><p>Тогда возникает вопрос как создавать инстанс исходного компонента в оболочке ). Ведь обычный вызов CoCreateInstance обратится в реестр, там найдёт путь до DLL и попробует создать её от туда, а там лежит наша DLL. )</p></blockquote></div><p>Так для этого же dll и экспортирует функцию DllGetClassObject. Из неё получаем объект ClassFactory и создаём объект нужного класса методом CreateInstance. То же самое делает CoCreateInstance.</p><div class="quotebox"><cite>Xameleon пишет:</cite><blockquote><p>Помню был вариант на форуме VBStreets. Приходилось делать хук - перехват API, подменять данные...</p></blockquote></div><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header" data-lang-open="открыть спойлер" data-lang-close="скрыть спойлер"><strong>+</strong>&nbsp;открыть спойлер</div><div class="fancy_spoiler"><p><span class="postimg"><img src="https://cs.pikabu.ru/images/big_size_comm/2013-09_1/13783048769859.jpeg" alt="https://cs.pikabu.ru/images/big_size_comm/2013-09_1/13783048769859.jpeg" /></span></p></div></div><p><img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /><br />Хотя, может, там всё же что-то другое было.</p>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2019-01-18T12:44:45Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=131410#p131410</id>
		</entry>
</feed>
