Python 调用 Windows API 与 COM 组件的高效方案:win32exts 详解

Aria
Aria
发布时间:2026-10-13 | 4人浏览过
原创

本文介绍一种在Python中调用Win32 API和COM组件的高效方案。通过轻量级的win32exts库,无需繁琐配置即可实现具名函数调用、带回调函数处理及COM组件交互。文章详细展示了load_sym、callback及co_create等核心接口的用法,适用于32位Python环境,旨在提供比PyWin32更简洁、功能更强大的系统级编程支持。

Python调用Windows API的新方案概述

在Python环境中调用Win32 API,开发者通常依赖PyWin32或ctypes库。然而,这两种方式往往存在依赖文件众多或使用逻辑繁琐的问题。

本文旨在介绍一种在Python中调用Win32 API或COM组件的更优解决方案,该方案不仅功能更为强大,且使用体验更佳。

使用该方案的前提是确保Python解释器为32位版本,支持2.x或3.x系列。

首先需要获取通用扩展库:win32exts for Python。

该库的GitHub地址为:https://github.com/tankaishuai/win32exts_for_Python

部署时,仅需将win32exts.pyd文件放入Python安装目录下的DLLs文件夹中即可。在发布应用程序时,仅需包含这一个文件,极大简化了分发流程。

import win32exts

win32exts基础用法与具名函数调用

win32exts的基本调用方法如下所示:

(1)常规具名函数调用(以MessageBoxA/W为例):

首先需导入模块符号。load_sym函数的第一个参数指定待加载的模块名称,支持绝对路径;若传入"*",则代表当前进程加载的所有模块。

第二个参数指定函数符号名称,若传入"*",则表示加载该模块下的所有符号。


win32exts.load_sym("*", "*")
或 win32exts.load_sym("C:\\windows\\system32\\user32.dll", "MessageBoxW")
或 win32exts.load_sym("user32", "MessageBoxA")
或 win32exts.load_sym("user32", "*")

接下来进行具体调用:

win32exts.MessageBoxA(0, "call MessageBoxA", "", 1)

对于宽字符参数,需使用win32exts.L()进行包装,这与C/C++中的处理方式类似。

win32exts.MessageBoxW(0, win32exts.L("call MessageBoxW"), None, 1)

带回调函数的API调用实现

(2)带回调函数的调用(以EnumWindows为例):

首先需预先分配一块内存空间供后续使用:

g_buf = win32exts.malloc(2*260)

接着定义一个回调函数:


def EnumWndProc(args): 
  #【args为参数包,以下取参数】
  hWnd = win32exts.arg(args, 1)
  lParam = win32exts.arg(args, 2)
  win32exts.GetWindowTextW(hWnd, g_buf, 260)
  #【读取内存中的宽字符串】
  #【read_***系列接口读内存,write_***系列接口写内存】
  strText = win32exts.read_wstring(g_buf, 0, -1)
  win32exts.MessageBoxW(0, win32exts.L(strText), g_buf, 1)
  strRetVal = "1, 8"
  g_index = g_index + 1
  if g_index > 3: #【假设只弹框三次】
   strRetVal = "0, 8"
  #【返回值是形如这样的字符串: "回调返回值, 参数字节数",
  # 对于 cdecl 调用约定,参数字节数总是取 0 】
  return strRetVal

最后执行调用:


win32exts.EnumWindows(win32exts.callback("EnumWndProc"), 0)
win32exts.callback()用于包装一个Python回调函数。

匿名函数与COM组件的高级调用

(3)匿名(非具名)函数调用:

假设已通过某种接口获取到目标函数的地址lFuncAddr,可采用如下方式进行调用:


win32exts.push_value(arg1) 【参数是整数】
win32exts.push_wstring("arg2") 【参数是宽字符串】
win32exts.push_astring(arg3) 【参数是多字节字符串】
win32exts.push_double(arg4) 【参数是双精度浮点数】
win32exts.push_float(arg5) 【参数是单精度浮点数】
win32exts.push_function("FunctionName") 【参数是回调函数】

iRetVal = win32exts.call( lFuncAddr )

具名函数同样支持此类调用方式,例如:


win32exts.push_value(0)
win32exts.push_astring("Py_MessageBoxA_V1")
win32exts.push_value(0)
win32exts.push_value(0)
iRetVal = win32exts.sym_call("MessageBoxA") #【或用 func_call】

(4)COM组件调用:


import win32exts
#
# 测试 COM 组件, 打开计算器
#
wsh = win32exts.co_create_ ("W .Shell")
win32exts.co_push_start()
win32exts.push_bstr("calc")
win32exts.co_invoke(wsh, "Run")
win32exts.co_release(wsh)

知识点扩展:

python调用windows api


import ctypes
# 方式一
ctypes.windll.user32.MessageBoxA(None, 'message', 'title', 0)
# 方式二
ctypes.WinDLL('user32.dll').MessageBoxA(None, 'message', 'title', 0)

总结

以上介绍了Python调用Windows API及COM组件的新方法,希望能为读者提供帮助。如有疑问,欢迎留言交流,小编会及时回复。感谢大家对本站的支持! 若本文对您有所帮助,欢迎转载,请注明出处,谢谢!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表