現時点で作業している 3 つのコードがあります。
- クローズド ソース アプリケーション (Main.exe)
- dll (comobj.dll) として実装されたクローズド ソースの VB COM オブジェクト
- 私がPythonで開発しているコード
comobj.dll は、Python から使用したい COM オブジェクト (「MainInteract」など) をホストします。このオブジェクトは既に 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() を実行できます。
特に「登録なしのCOM」について話すときに、アクティベーションコンテキストが参照されているのを見たことがありますが、通常は「.manifestファイルに適切なものを指定すると、Windowsはコンテキストを作成します」のような文で参照されます。(クローズド ソース) COM オブジェクト dll と同じフォルダーにマニフェスト ファイルが必要になるため、可能であればマニフェスト ファイルを避けたいと思います。
助けてくれてありがとう。