Tôi đã ba mẩu mã mà tôi đang làm việc với tại thời điểm này:Tiếp cận đối tượng COM đăng ký từ trăn qua một TLB đăng ký
- Một đóng ứng dụng mã nguồn (main.exe)
- Một đóng nguồn VB COM đối tượng thực hiện như một dll (comobj.dll)
- Mã mà tôi đang phát triển bằng Python
comobj.dll tổ chức một đối tượng COM (cho phép nói, 'MainInteract') mà tôi muốn sử dụng từ Python. Tôi đã có thể sử dụng đối tượng này hoàn toàn tốt đẹp từ IronPython, nhưng do các yêu cầu khác tôi cần phải sử dụng nó từ Python thông thường. Tôi tin rằng phương pháp tốt nhất ở đây là sử dụng win32com, nhưng tôi không thể thực hiện bất kỳ tiến bộ nào cả.
Thứ nhất, một số mã làm việc 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)
Và bây giờ đoạn code mà tôi đã cố gắng bằng Python thường xuyên:
>>> 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)
Tôi cũng đã cố gắng sử dụng tên thân thiện của 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)
Thực ra, thành công duy nhất tôi có được là:
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)
Nhưng tôi không chắc chắn cách đi từ đó để lấy vật thể. Tôi nghĩ rằng vấn đề của tôi là tôi cần phải tải dll vào quá trình của tôi và làm cho nó để đăng ký chính nó với nguồn COM của quá trình của tôi, vì vậy tôi có thể đúng CoCreateInstance/win32com.client.Dispatch() trên đó.
Tôi cũng thấy Activation Contexts được tham chiếu, đặc biệt khi nói về 'không có đăng ký COM', nhưng thường trong một câu như "Windows sẽ tạo ngữ cảnh cho bạn nếu bạn chỉ định đúng nội dung trong tệp .manifest của bạn". Tôi muốn tránh các tập tin manifest nếu có thể, như một trong những sẽ được yêu cầu trong cùng một thư mục như (đóng nguồn) COM đối tượng dll, và tôi không muốn thả bất kỳ tập tin trong thư mục đó nếu tôi có thể tránh nó.
Cảm ơn sự giúp đỡ.
Tôi không biết câu trả lời ra khỏi đỉnh đầu của tôi, nhưng nếu bạn có thể làm điều đó với C++ sau đó bạn có thể khá trivially quấn đó. – ConcernedOfTunbridgeWells
Vâng vâng, tôi cho rằng đó là một lựa chọn, nhưng tôi đã hy vọng để tránh nó. –