Pywinauto Windows 桌面应用 Python 自动化实战
Pywinauto 是一个用于自动化 Windows 图形用户界面(GUI)的 Python 库。它允许你通过编程方式控制 Windows 应用程序,模拟用户操作(如点击按钮、输入文本、选择菜单等)。简单来说,它就是让 Python 成为你的'鼠标和键盘'。
环境准备
使用 pip 安装即可:
pip install pywinauto
安装完成后,可以通过 pip list 确认版本。
核心概念与后端选择
Pywinauto 支持两种主要的后端技术,选择合适的 backend 至关重要:
- Win32 API (backend='win32'):适用于传统的 MFC、VB6、WinForms 等老式界面。
- MS UI Automation (backend='uia'):适用于 WPF、Qt、Modern UI(UWP)等较新的界面。
大多数现代 Windows 应用推荐使用 uia 后端,兼容性更好。
常用操作流程
启动与连接应用
你可以直接启动新进程,也可以连接到已经运行的进程。
from pywinauto.application import Application
# 启动记事本
app = Application(backend='uia').start('notepad.exe')
# 连接已运行的进程(需知道 PID)
# app = Application(backend='uia').connect(process=12345)
# 或通过窗口句柄连接
# app = Application(backend='uia').connect(handle=66666)
定位窗口
定位窗口通常基于标题、类名或正则匹配。print_control_identifiers() 是个好帮手,能帮你查看窗口内部的控件树结构。
# 精确匹配
win = app.window(title='Hello,Pywinauto! - Notepad')
# 正则匹配
win = app.window(title_re='.*Notepad')
# 注意:best_match 有时会因为控件名称包含特殊字符而失效,建议优先使用 title 或 class_name
窗口状态控制
常见的窗口操作包括最大化、最小化、关闭等。
win.maximize()
assert win.is_maximized()
win.minimize()
assert win.is_minimized()
win.restore()
win.close()
控件交互
这是自动化中最核心的部分。Pywinauto 提供了丰富的控件类型,如按钮、编辑框、列表等。
定位控件
除了使用 child_window,还可以利用 print_control_identifiers() 输出的信息来辅助定位。
# 通过索引查找
btn = win['保存']
# 通过属性查找
btn = win.child_window(auto_id='SaveButton', control_type='Button')
等待机制
自动化脚本最怕的就是元素还没加载完就操作。务必加上等待逻辑。
# 等待元素可见且启用
btn.wait('ready', timeout=10)
# 自定义等待函数
def is_visible():
return win.is_visible()
wait_until(10, 0.5, is_visible)
鼠标与键盘
当控件级操作无法满足需求时,可以使用坐标级的鼠标操作。
from pywinauto.mouse import mouse
# 点击指定坐标
mouse.click(coords=(x, y))
# 滚动滚轮
mouse.scroll(coords=(x, y), wheel_dist=1)
键盘输入方面,type_keys 比 send_keys 更常用,因为它不依赖焦点窗口。
# 输入文本
win.type_keys('hello world')
# 带延迟输入
win.type_keys('你好', pause=1)
# 虚拟键码
win.type_keys('{ENTER}')
win.type_keys('^a') # Ctrl+A
实战案例:微信自动发消息
下面是一个完整的场景示例,演示如何连接微信并发送消息。这里的关键在于验证消息是否发送成功,通常通过检查消息列表的数量和内容来实现。
from datetime import datetime
from pywinauto.application import Application
# 1. 连接微信进程
app = Application(backend='uia').connect(process=2832)
# 2. 定位聊天窗口
win = app.window(title='文件传输助手', control_type='Window')
win.wait('visible')
# 3. 记录发送前的消息条数
message_list = win.child_window(title='消息', control_type='List')
count_before = message_list.item_count()
# 4. 构造唯一消息内容(使用时间戳避免重复)
msg_content = 'Test Message ' + str(datetime.now().timestamp())
edit_box = win.child_window(title='输入', control_type='Edit')
edit_box.click_input()
edit_box.type_keys(msg_content, with_spaces=True)
# 5. 点击发送
send_btn = win.child_window(title='发送 (S)', control_type='Button')
send_btn.click_input()
# 6. 验证结果
# 发送后消息数量可能增加 1 条或 2 条(取决于时间戳显示)
count_after = message_list.item_count()
assert count_after == count_before + 1 or count_after == count_before + 2
# 获取最后一条消息内容校验
last_msg = message_list.get_item(row=count_after - 1).window_text()
assert last_msg == msg_content
总结
Pywinauto 在处理 Windows 桌面应用自动化时非常强大。关键在于理解控件树结构,合理选择后端,以及做好异常处理和等待机制。实际开发中,建议结合 UISpy 等工具辅助调试控件定位。

