如何在Python中正确加载Windows COM DLL

时间:2014-06-27 09:36:46

标签: python ctypes win32com pythoncom

我正在尝试在Python中加载一个Windows COM DLL以获取所有公开的接口。

使用dependency walker工具,我可以列出dll中的函数。我只看到4个功能:

  1. DllCanUnloadNow
  2. 的DllGetClassObject
  3. 的DllRegisterServer
  4. DllUnregisterServer的
  5. 如果我理解正确,我需要使用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。但这会抛出一个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
    

    任何想法我做错了什么?我无法访问该工具的源代码。

    在C ++中,这是两步过程,但不知道如何在Python中执行此操作:

    1. 的CoInitializeEx()
    2. 的CoCreateInstance()
    3. 一般来说,在python中访问Windows COM DLL的最佳技术是什么?谢谢!!

1 个答案:

答案 0 :(得分:0)

我无法弄清楚如何直接调用DllGetClassObject,但以下方法对我有用。它也应该为你做,因为你的DLL有DllRegisterServer和DllUnregisterServer:

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

然后在Python中:

import win32com.client
lib = win32com.client.Dispatch("Some.Thing")
lib.SomeFunction()

我不确定您应该指定什么作为Dispatch的参数。我的DLL带有一个示例VB应用程序,它执行此操作:

Dim lib As New Some.Thing
lib.SomeFunction()