<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; LangMF 9.0: Создание COM Automation объекта без регистрации библиотеки]]></title>
		<link>https://forum.script-coding.com/viewtopic.php?id=11254</link>
		<atom:link href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=11254&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «LangMF 9.0: Создание COM Automation объекта без регистрации библиотеки».]]></description>
		<lastBuildDate>Fri, 22 Jan 2016 20:35:27 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[LangMF 9.0: Создание COM Automation объекта без регистрации библиотеки]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=100614#p100614</link>
			<description><![CDATA[<p><em>Без гарантий! Используете на свой страх и риск.</em></p><p>Скрипт предназначен для создания Automation объектов без регистрации COM библиотеки в реестре.</p><p>Аргументы функции GetObjectFromDLL:<br /> sPath&nbsp; &nbsp; Путь к COM библиотеке, строка.<br /> sCLSID&nbsp; &nbsp;Идентификатор класса CLSID, строка вида &quot;{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}&quot;.<br /> sUUID&nbsp; &nbsp; Идентификатор интерфейса IID, строка вида &quot;{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}&quot;.</p><br /><p>Например, в библиотеке AutoItX3 (3.2.0.1), класс [AutoItX3 Class], содержит Automation интерфейс [IAutoItX3 Interface]. Класс имеет идентификатор {1A671297-FA74-4422-80FA-6C5D8CE4DE04}, а идентификатор интерфейса {3D54C6B8-D283-40E0-8FAB-C97F05947EE8}. Пользуясь этимими идентификаторами можно получить объект [AutoItX3.Control].</p><p>Потребуется установленный <a href="http://langmf.ru/ftp/archive/LangMF_9.0.exe">LangMF 9.0</a>.<br />OC WinXP</p><div class="codebox"><pre><code>
&#039; Без гарантий! Используете на свой страх и риск.
&#039;------------------------------------------------------------------------------------------
&#039; Скрипт предназначен для создания Automation объектов без регистрации библиотеки в реестре.
&#039;
&#039; Аргументы функции GetObjectFromDLL:
&#039; sPath    Путь к COM библиотеке, строка.
&#039; sCLSID   Идентификатор класса CLSID, строка вида &quot;{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}&quot;.
&#039; sUUID    Идентификатор интерфейса IID, строка вида &quot;{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}&quot;.
&#039;
&#039;
&#039; Потребуется установленный LangMF 9.0 (http://langmf.ru/ftp/archive/LangMF_9.0.exe)
&#039; OC WinXP
&#039;------------------------------------------------------------------------------------------
Public Declare Function CLSIDFromString Lib &quot;ole32&quot; (ByVal lpsz As Long, pclsid As Guid) As Long
&#039;------------------------------------------------------------------------------------------
&lt;#Module=DispNoRegCall&gt;

&#039;------------------------------------------------------------------------------------------
&#039; Создание Automation объектов и работа с ними
&#039;------------------------------------------------------------------------------------------
Sub Load(cmdstr)

	Dim oAU3, oWshExtra
	Dim sFile

	&#039; WshExtra.FileChooser
	&#039;-----------------------------------------------------------------------------------
	Set oWshExtra = GetObjectFromDLL(&quot;G:\WshExtra.dll&quot;, _
					&quot;{D199C0CE-78E8-4DE2-B863-CCDC022A2FCA}&quot;, _
					&quot;{1FBCEB53-17E7-438F-926E-643ABC236A51}&quot;)
					
	MsgBox &quot;Созданный тип [&quot; &amp; TypeName(oWshExtra) &amp; &quot;].&quot;, vbSystemModal + vbInformation, &quot;Reply&quot;
		oWshExtra.Title = &quot;Открытие файла...&quot;
		oWshExtra.Filter = &quot;Все файлы|*.*|&quot;
		sFile = oWshExtra.Browse(&quot;C:\&quot;) 
		If Len(sFile)&lt;&gt;0 Then MsgBox &quot;Выбранный файл: &quot; &amp; sFile, vbSystemModal + vbInformation, &quot;Reply&quot;

	&#039; AutoItX3.Control
	&#039;-----------------------------------------------------------------------------------
	Set oAU3 = GetObjectFromDLL(	&quot;G:\AutoItX3.dll&quot;, _
					&quot;{1A671297-FA74-4422-80FA-6C5D8CE4DE04}&quot;, _
					&quot;{3D54C6B8-D283-40E0-8FAB-C97F05947EE8}&quot;)
					
	MsgBox &quot;Созданный тип [&quot; &amp; TypeName(oAU3) &amp; &quot;].&quot;, vbSystemModal + vbInformation, &quot;Reply&quot;	
	oAU3.ToolTip vbCRLF &amp; &quot;Создание Automation объекта без регистрации библиотеки...&quot; &amp; vbCRLF, 100, 100
	oAU3.Sleep(4000)
	&#039;-----------------------------------------------------------------------------------
	EndMF
End Sub

&#039;------------------------------------------------------------------------------------------
&#039; Создать Automation объект из незарегистрированной в реестре библиотеки
&#039;------------------------------------------------------------------------------------------
Function GetObjectFromDLL(sPath, sCLSID, sUUID)

	Const S_OK = 0
	Const CreateInstanceID = 3
	Const GetTypeInfoOfGuidID = 6
	Const QueryInterfaceID = 0
	Const REGKIND_NONE = 2
	Const REGKIND_DEFAULT = 0
	&#039;-----------------------------------------------------------------------------------
	Dim hRes
	Dim pvarRes
	Dim pCLSID, pIClassFactory, pIDispatch, pIUnknown, pUUID
	Dim p1, p2, p3, p4, p5, p6
	Dim objX

	&#039;-----------------------------------------------------------------------------------
	Const sIID_IClassFactory = &quot;{00000001-0000-0000-C000-000000000046}&quot;
	Const sIID_IDispatch = &quot;{00020400-0000-0000-C000-000000000046}&quot;
	Const sIID_IUnknown = &quot;{00000000-0000-0000-C000-000000000046}&quot;

	&#039;-----------------------------------------------------------------------------------
	Sys.DynAPI.CallFunction &quot;OLE32.DLL&quot;, &quot;CoInitialize&quot;, 0

	&#039; Подготовить память для GUID и возвращаемого результата
	&#039;-----------------------------------------------------------------------------------
	Sys.DynAPI.CurBuf = 0
	Sys.DynAPI.ReBuf(16)
	pCLSID = Sys.DynAPI.PtrBuf(0)

	Sys.DynAPI.CurBuf = 1
	Sys.DynAPI.ReBuf(16)
	pIClassFactory = Sys.DynAPI.PtrBuf(1)

	Sys.DynAPI.CurBuf = 2
	Sys.DynAPI.ReBuf(16)
	pIDispatch = Sys.DynAPI.PtrBuf(2)

	Sys.DynAPI.CurBuf = 3
	Sys.DynAPI.ReBuf(16)
	pIUnknown = Sys.DynAPI.PtrBuf(3)

	Sys.DynAPI.CurBuf = 4
	Sys.DynAPI.ReBuf(16)
	pUUID = Sys.DynAPI.PtrBuf(4)

	Sys.DynAPI.CurBuf = 5
	Sys.DynAPI.ReBuf(4)
	pvarRes = Sys.DynAPI.PtrBuf(5)

	&#039; Преобразовать строковые идентификаторы в GUID
	&#039;-----------------------------------------------------------------------------------
	Call CLSIDFromString(Sys.StrPtr(sCLSID), pCLSID)
	Call CLSIDFromString(Sys.StrPtr(sIID_IClassFactory), pIClassFactory)
	Call CLSIDFromString(Sys.StrPtr(sIID_IDispatch), pIDispatch)
	Call CLSIDFromString(Sys.StrPtr(sIID_IUnknown), pIUnknown)
	Call CLSIDFromString(Sys.StrPtr(sUUID), pUUID)

	
	&#039;===============================================
	&#039; Получить фабрику классов IClassFactory
	&#039;-----------------------------------------------------------------------------------
	hRes = Sys.DynAPI.CallFunction(sPath, &quot;DllGetClassObject&quot;, pCLSID, pIClassFactory, pvarRes)
		If hRes &lt;&gt; S_OK Then ErrMsg(hRes): Set GetObjectFromDLL = Nothing: Exit Function
		p1 = RetPtr()
		

	&#039; Вернуть указатель на IDispatch путем вызова CreateInstance из фабрики IClassFactory
	&#039;-----------------------------------------------------------------------------------
	hRes = Sys.DynApi.CallInterface(p1, CreateInstanceID, 3, 0, pIDispatch, pvarRes)
		If hRes &lt;&gt; S_OK Then ErrMsg(hRes): Set GetObjectFromDLL = Nothing: Exit Function
		p2 = RetPtr()
	
	&#039; Если здесь попробовать восстановить объект по указателю [Set GetObjectFromDLL = Sys.ObjFromPtr(p2)],
	&#039; то такая схема работать не будет, т.к TypeLib не зарегистрирована, будет получен &quot;пустой&quot;
	&#039; объект, без свойств и методов. Нужно подключить библиотеку типов и загрузить указатель
	&#039; на TypeInfo для заданного интерфейса UUID.
	
	&#039;===============================================
	&#039; Загрузить встроенную библиотеку типов
	&#039;-----------------------------------------------------------------------------------
	hRes = Sys.DynAPI.CallFunction(&quot;OLEAUT32.DLL&quot;, &quot;LoadTypeLibEx&quot;, Sys.StrConv(sPath,vbUnicode), REGKIND_NONE, pvarRes)
		If hRes &lt;&gt; S_OK Then ErrMsg(hRes): Set GetObjectFromDLL = Nothing: Exit Function
		p3 = RetPtr()

	&#039; Получить указатель на TypeInfo для заданного интерфейса UUID
	&#039;-----------------------------------------------------------------------------------
	hRes = Sys.DynApi.CallInterface(p3, GetTypeInfoOfGuidID, 2, pUUID, pvarRes)
		If hRes &lt;&gt; S_OK Then ErrMsg(hRes): Set GetObjectFromDLL = Nothing: Exit Function
		p4 = RetPtr()

	&#039; Получить IUnknown заданного интерфейса на основе TypeInfo 
	&#039;-----------------------------------------------------------------------------------
	hRes = Sys.DynAPI.CallFunction(&quot;OLEAUT32.DLL&quot;, &quot;CreateStdDispatch&quot;, 0, p2, p4, pvarRes)
		If hRes &lt;&gt; S_OK Then ErrMsg(hRes): Set GetObjectFromDLL = Nothing: Exit Function
		p5 = RetPtr()

	&#039; Получить IDispatch заданного интерфейса
	&#039;-----------------------------------------------------------------------------------
	hRes = Sys.DynApi.CallInterface(p5, QueryInterfaceID, 2, pIDispatch, pvarRes)
		If hRes &lt;&gt; S_OK Then ErrMsg(hRes): Set GetObjectFromDLL = Nothing: Exit Function
		p6 = RetPtr()

	&#039;===============================================
	&#039; Восстановить и вернуть объект
	&#039;-----------------------------------------------------------------------------------
	Set GetObjectFromDLL = Sys.ObjFromPtr(p6)
	If Not IsObject(GetObjectFromDLL) Then ErrMsg(&quot;Не удалось получить объект.&quot;): Set GetObjectFromDLL = Nothing: Exit Function
		
	
	&#039;-----------------------------------------------------------------------------------
	Sys.DynAPI.CallFunction &quot;OLE32.DLL&quot;, &quot;CoUninitialize&quot;

End Function

&#039; Извлечение значения из указателя
&#039;------------------------------------------------------------------------------------------
Function RetPtr()
	Dim buf()
	Sys.DynAPI.GetBuf buf, 5
	RetPtr = Sys.Conv.Byte4Long (buf(3),buf(2),buf(1),buf(0))	
End Function

&#039; Сообщение об ошибке
&#039;------------------------------------------------------------------------------------------
Sub ErrMsg(vMsg)
	Sys.DynAPI.CallFunction &quot;OLE32.DLL&quot;, &quot;CoUninitialize&quot;
	Sys.Sleep(100)
	MsgBox &quot;Произошла ошибка: &quot; &amp; CStr(vMsg), vbSystemModal + vbExclamation, &quot;Error Reply&quot;
End Sub
&#039;------------------------------------------------------------------------------------------
&lt;#Module&gt;
</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (Poltergeyst)]]></author>
			<pubDate>Fri, 22 Jan 2016 20:35:27 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=100614#p100614</guid>
		</item>
	</channel>
</rss>
