я три куска кода, что я работаю с на данный момент:Доступ к незарегистрированным COM объектов из питона с помощью зарегистрированного TLB
- Замкнутых исходное приложение (main.exe)
- Закрытом источник реализован в виде DLL (comobj.dll) VB COM объект
- код, который я развиваю в Python
comobj.dll хостов COM объект (позволяет сказать, «MainInteract»), что я хотел бы использовать от Python. Я уже могу использовать этот объект совершенно отлично от IronPython, но из-за других требований мне нужно использовать его из обычного Python. Я считаю, что лучший способ здесь - использовать win32com, но я не могу добиться какого-либо прогресса.
Во-первых, некоторые из которых работают код IronPython:
import clr
import os
import sys
__dir__ = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, __dir__)
sys.path.append(r"C:\Path\To\comobj.dll") #This is where the com object dll actually is
clr.AddReferenceToFileAndPath(os.path.join(__dir__, r'comobj_1_1.dll')) #This is the .NET interop assembly that was created automatically via SharpDevelop's COM Inspector
from comobj_1_1 import clsMainInteract
o = clsMainInteract()
o.DoStuff(True)
А теперь код, который я попытался в очередной Python:
>>> import win32com.client
>>> win32com.client.Dispatch("{11111111-comobj_guid_i_got_from_com_inspector}")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python26\lib\site-packages\win32com\client\__init__.py", line 95, in Dispatch
dispatch, userName = dynamic._GetGoodDispatchAndUserName(dispatch,userName,clsctx)
File "C:\Python26\lib\site-packages\win32com\client\dynamic.py", line 104, in _GetGoodDispatchAndUserName
return (_GetGoodDispatch(IDispatch, clsctx), userName)
File "C:\Python26\lib\site-packages\win32com\client\dynamic.py", line 84, in _GetGoodDispatch
IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx, pythoncom.IID_IDispatch)
pywintypes.com_error: (-2147221164, 'Class not registered', None, None)
Я также попытался с помощью понятного имени TLB :
>>> import win32com.client
>>> win32com.client.Dispatch("Friendly TLB Name I Saw")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python26\lib\site-packages\win32com\client\__init__.py", line 95, in Dispatch
dispatch, userName = dynamic._GetGoodDispatchAndUserName(dispatch,userName,clsctx)
File "C:\Python26\lib\site-packages\win32com\client\dynamic.py", line 104, in _GetGoodDispatchAndUserName
return (_GetGoodDispatch(IDispatch, clsctx), userName)
File "C:\Python26\lib\site-packages\win32com\client\dynamic.py", line 84, in _GetGoodDispatch
IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx, pythoncom.IID_IDispatch)
pywintypes.com_error: (-2147221005, 'Invalid class string', None, None)
На самом деле, единственный успех у меня был был такой:
import pythoncom
tlb = pythoncom.LoadRegTypeLib("{11111111-comobj_guid_i_got_from_com_inspector}",1,1,0)
>>> tlb
<PyITypeLib at 0x00AD7D78 with obj at 0x0025EDF0>
>>> tlb.GetDocumentation(1)
(u'clsMainInteract', None, 0, None)
Но я не уверен, как идти оттуда, чтобы получить объект. Я думаю, что моя проблема в том, что мне нужно загрузить DLL в мой процесс и заставить его зарегистрироваться в источнике COM моего процесса, поэтому я могу правильно использовать CoCreateInstance/win32com.client.Dispatch().
Я также видел Activation Contexts, ссылаясь на него, особенно когда речь идет о «отсутствии регистрации COM», но обычно в таких предложениях, как «Windows создаст для вас контекст, если вы укажете нужный материал в файлах .manifest». Я хотел бы, если это возможно, избегать файлов манифеста, поскольку один из них потребуется в той же папке, что и DLL COM-объекта (закрытый источник), и я бы предпочел не удалять файлы в этом каталоге, если я могу его избежать.
Спасибо за помощь.
Я не знаю ответа у верхней части моей головы, но если вы можете сделайте это с помощью C++, тогда вы можете довольно тривиально обернуть это. – ConcernedOfTunbridgeWells
Ну да, я полагаю, что это вариант, но я надеялся избежать этого. –