I am trying to load a windows COM DLL in Python to get all the exposed interfaces.
Using the dependency walker tool I can list the functions in the dll. I see only 4 functions:
- DllCanUnloadNow
- DllGetClassObject
- DllRegisterServer
- DllUnregisterServer
If I understood correctly, I need to get an object of the class using DllGetClassObject() and then use the exposed interfaces.
I am using pythoncom and win32com.client to extract the object (got the recipe from another stackoverflow post)
import pythoncom
import win32com.client
def CreateInstanceFromDll(dll, clsid_class, iid_interface=pythoncom.IID_IDispatch, pUnkOuter=None, dwClsContext=pythoncom.CLSCTX_SERVER):
from uuid import UUID
from ctypes import OleDLL, c_long, byref
e = OleDLL(dll)
print (e)
#print (e.DllRegisterServer())
clsid_class = UUID(clsid_class).bytes_le
iclassfactory = UUID(str(pythoncom.IID_IClassFactory)).bytes_le
com_classfactory = c_long(0)
hr = e.DllGetClassObject(clsid_class, iclassfactory, byref(com_classfactory))
MyFactory = pythoncom.ObjectFromAddress(com_classfactory.value, pythoncom.IID_IClassFactory)
i = MyFactory.CreateInstance(pUnkOuter, iid_interface)
d = win32com.client.__WrapDispatch(i)
return d
print (CreateInstanceFromDll('PTSControl.dll', '{32a917e0-b1d4-4692-b0d7-793d81d9c8b5}'))
I got the cls_id
from the windows registry for the PTSControl tool. But this throws an WindowsError.
<OleDLL 'PTSControl.dll', handle 70010000 at 2451470>
Traceback (most recent call last):
File "C:\wp\automation.py", line 35, i
n <module>
print (CreateInstanceFromDll('PTSControl.dll', '{32a917e0-b1d4-4692-b0d7-793
d81d9c8b5}'))
File "C:\wp\automation.py", line 29, i
n CreateInstanceFromDll
hr = e.DllGetClassObject(clsid_class, iclassfactory, byref(com_classfactory)
)
File "_ctypes/callproc.c", line 945, in GetResult
WindowsError: [Error -2147467262] No such interface supported
Any ideas what I am doing wrong? I do not have access to the tool's source code.
In C++ this is 2-step process but no idea how to do it in Python:
- CoInitializeEx()
- CoCreateInstance()
In general, what is the best technique to access a Windows COM DLL in python? Thanks !!