que tengo tres piezas de código que estoy trabajando con en el momento:Acceso a objetos COM no registrados de pitón a través de una TLB registrada
- una aplicación de origen (Main.exe) cerró
- Una fuente cerrada VB objeto COM implementado como una DLL (comobj.dll)
- el código que estoy desarrollando en Python
comobj.dll alberga un objeto COM (digamos, 'MainInteract') que me gustaría usar desde Pitón. Ya puedo usar este objeto perfectamente de IronPython, pero debido a otros requisitos necesito usarlo de Python regular. Creo que el mejor método aquí es usar win32com, pero no puedo hacer ningún progreso en absoluto.
En primer lugar, un cierto código IronPython de trabajo:
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)
Y ahora el código que he tratado en Python normal:
>>> 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)
También he intentado usar el nombre descriptivo de la 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)
De hecho, el único éxito que he tenido fue la siguiente:
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)
pero no estoy seguro de cómo ir desde allí a conseguir un objeto. Creo que mi problema es que necesito cargar el dll en mi proceso y hacer que se registre con el origen COM de mi proceso, para que pueda CoCreateInstance/win32com.client.Dispatch() correctamente en él.
También he visto Activation Contexts mencionado, especialmente cuando se habla de 'no registro COM', pero normalmente en frases como "Windows creará un contexto para usted si especifica las cosas correctas en sus archivos .manifest". Me gustaría evitar los archivos manifiestos si es posible, ya que uno sería necesario en la misma carpeta que el dll de objeto COM (fuente cerrada), y preferiría no soltar ningún archivo en ese directorio si puedo evitarlo.
Gracias por la ayuda.
no sé la respuesta de la parte superior de mi cabeza, pero si se puede hazlo con C++, entonces puedes envolverlo de manera bastante trivial. – ConcernedOfTunbridgeWells
Bueno, sí, supongo que es una opción, pero esperaba evitarla. –