【问题标题】:How to correctly load a Windows COM DLL in Python如何在 Python 中正确加载 Windows COM DLL
【发布时间】:2014-08-18 08:58:24
【问题描述】:

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

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

  1. DllCanUnloadNow
  2. DllGetClassObject
  3. DllRegisterServer
  4. 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。但这会引发 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()

一般来说,在 python 中访问 Windows COM DLL 的最佳技术是什么?谢谢!!

【问题讨论】:

  • 如果DLL未注册,您只需按照您链接的帖子中的示例进行操作。因为它必须是 CoCreateInstance 在 C++ 中工作的寄存器,所以你不需要走极端。 win32com 应该支持 CoCreateInstance 或具有相同效果的东西。

标签: python ctypes win32com pythoncom


【解决方案1】:

我不知道如何直接调用 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()

【讨论】:

  • 感谢您的意见。至少通过您的输入,我能够打开应用程序,但是在打开应用程序后我的 python 脚本立即崩溃并出现以下错误 - pywintypes.com_error: (-2147467262, 'No such interface supported', None, None) 有什么想法吗?
猜你喜欢
  • 2011-02-27
  • 2016-01-29
  • 1970-01-01
  • 2014-02-14
  • 1970-01-01
  • 2021-01-28
  • 2023-03-25
  • 1970-01-01
相关资源
最近更新 更多