Ho tre pezzi di codice che sto lavorando con in questo momento:Accesso oggetti COM non registrati da python tramite un TLB registrato
- un'applicazione di origine (Main.exe) ha chiuso
- Una fonte chiusa VB oggetto COM implementato come una DLL (comobj.dll)
- codice che sto sviluppando in Python
comobj.dll ospita un oggetto COM (diciamo, 'MainInteract') che vorrei da utilizzare Pitone. Posso già usare questo oggetto perfettamente bene da IronPython, ma a causa di altri requisiti ho bisogno di usarlo dal normale Python. Credo che il metodo migliore qui sia quello di usare win32com, ma non posso assolutamente fare progressi.
In primo luogo, un po 'di codice di lavoro 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)
E ora il codice che ho tentato in Python regolare:
>>> 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)
ho anche tentato con il nome descrittivo del 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)
In realtà, l'unico successo che ho avuto è stato questo:
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)
ma non sono sicuro di come andare da lì per ottenere un oggetto. Penso che il mio problema è che ho bisogno di caricare la DLL nel mio processo e farlo registrare con la sorgente COM del mio processo, così posso correttamente CoCreateInstance/win32com.client.Dispatch() su di esso.
Ho anche visto il riferimento Activation Contexts, in particolare quando si parla di "nessuna registrazione COM", ma in genere in frasi come "Windows creerà un contesto per te se specifichi le cose giuste nei tuoi file .manifest". Mi piacerebbe evitare i file manifest se possibile, in quanto uno sarebbe richiesto nella stessa cartella del dll oggetto COM (closed source), e preferirei non lasciare alcun file in quella directory se posso evitarlo.
Grazie per l'aiuto.
non so la risposta fuori dalla parte superiore della mia testa, ma se si può fallo con il C++, quindi puoi tranquillamente includerlo. – ConcernedOfTunbridgeWells
Beh sì, suppongo che sia un'opzione, ma speravo di evitarlo. –