我试图在Python中加载一个windows COM DLL来获取所有公开的接口。
使用dependency walker工具,我可以列出dll中的函数。我只看到4个功能:
DllCanUnloadNow公司
DllGetClassObject对象
注册过程
DllUnregisterServer服务器
如果我理解正确,我需要使用DllGetClassObject()获取类的对象,然后使用公开的接口。
我正在使用pythoncom和win32com.client提取对象(从另一个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}'))

我从windows注册表中获得了PTSControl工具的cls_id。但这会抛出一个窗口错误。
<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

你知道我做错了什么吗?我无法访问该工具的源代码。
在C++中,这是两步过程,但不知道如何在Python中完成:
CoInitializeEx()
CoCreateInstance()
一般来说,在python中访问Windows COM DLL的最佳技术是什么?谢谢!!

最佳答案

我不知道如何直接调用DllGetClassObject,但以下方法对我有效。它也应该对您有用,因为您的DLL有DllRegisterServer和DllUnregisterServer:

cd c:\path\to\libs
regsvr32 YourLib.dll

然后在Python中:
import win32com.client
lib = win32com.client.Dispatch("Some.Thing")
lib.SomeFunction()

我不确定您应该指定什么作为分派参数。我的DLL附带了一个VB应用程序示例:
Dim lib As New Some.Thing
lib.SomeFunction()

10-05 21:33