pywinauto
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWindows UI 自动化(pywinauto)
Windows UI 自动化(pywinauto)
通过 pywinauto 操作任意 Windows 桌面应用:发现窗口、检查控件、点击按钮、输入文字、读取内容。
支持两种后端:Win32 API(传统应用)和 MS UI Automation(现代应用)。
通过 pywinauto 操作任意 Windows 桌面应用:发现窗口、检查控件、点击按钮、输入文字、读取内容。
支持两种后端:Win32 API(传统应用)和 MS UI Automation(现代应用)。
使用场景
使用场景
- 用户说「帮我在 XX 应用里点一下那个按钮」「自动填一下这个表单」
- 需要操作没有 API 的桌面应用(如 ERP 系统、内部管理系统)
- 需要批量操作 GUI 应用(如自动录入数据)
- 需要读取其他应用界面上的文字内容
- 用户说「帮我在 XX 应用里点一下那个按钮」「自动填一下这个表单」
- 需要操作没有 API 的桌面应用(如 ERP 系统、内部管理系统)
- 需要批量操作 GUI 应用(如自动录入数据)
- 需要读取其他应用界面上的文字内容
后端选择
后端选择
| 后端 | 参数 | 适用应用 |
|---|---|---|
| Win32 API | | MFC、VB6、VCL、简单 WinForms |
| MS UI Automation | | WinForms、WPF、UWP Store 应用、Qt5、浏览器 |
不确定用哪个时,优先尝试 ;如果找不到控件,切换为 。
uiawin32| 后端 | 参数 | 适用应用 |
|---|---|---|
| Win32 API | | MFC、VB6、VCL、简单 WinForms |
| MS UI Automation | | WinForms、WPF、UWP Store 应用、Qt5、浏览器 |
不确定用哪个时,优先尝试 ;如果找不到控件,切换为 。
uiawin32命令参考
命令参考
连接到已有应用
连接到已有应用
python
from pywinauto import Applicationpython
from pywinauto import Application方式 1:通过窗口标题连接
方式 1:通过窗口标题连接
app = Application(backend="uia").connect(title="记事本", timeout=10)
app = Application(backend="uia").connect(title="记事本", timeout=10)
方式 2:通过进程名连接
方式 2:通过进程名连接
app = Application(backend="uia").connect(path="notepad.exe")
app = Application(backend="uia").connect(path="notepad.exe")
方式 3:通过进程 ID 连接
方式 3:通过进程 ID 连接
app = Application(backend="uia").connect(process=12345)
undefinedapp = Application(backend="uia").connect(process=12345)
undefined启动新应用
启动新应用
python
from pywinauto import Application
app = Application(backend="uia").start("notepad.exe")python
from pywinauto import Application
app = Application(backend="uia").start("notepad.exe")等待窗口出现
等待窗口出现
app.window(title_re=".记事本.").wait("ready", timeout=10)
undefinedapp.window(title_re=".记事本.").wait("ready", timeout=10)
undefined发现窗口和控件
发现窗口和控件
python
undefinedpython
undefined列出所有顶层窗口
列出所有顶层窗口
from pywinauto import Desktop
windows = Desktop(backend="uia").windows()
for w in windows:
print(f"{w.window_text()} — {w.class_name()}")
from pywinauto import Desktop
windows = Desktop(backend="uia").windows()
for w in windows:
print(f"{w.window_text()} — {w.class_name()}")
打印窗口控件树(调试用)
打印窗口控件树(调试用)
dlg = app.window(title_re=".记事本.")
dlg.print_control_identifiers()
undefineddlg = app.window(title_re=".记事本.")
dlg.print_control_identifiers()
undefined点击按钮和菜单
点击按钮和菜单
python
dlg = app.window(title="记事本")python
dlg = app.window(title="记事本")点击菜单
点击菜单
dlg.menu_select("文件->打开")
dlg.menu_select("文件->打开")
点击按钮(通过文本匹配)
点击按钮(通过文本匹配)
dlg.child_window(title="确定", control_type="Button").click()
dlg.child_window(title="确定", control_type="Button").click()
点击按钮(通过 auto_id)
点击按钮(通过 auto_id)
dlg.child_window(auto_id="btnSubmit").click()
undefineddlg.child_window(auto_id="btnSubmit").click()
undefined输入文字
输入文字
python
dlg = app.window(title="记事本")python
dlg = app.window(title="记事本")输入到编辑框
输入到编辑框
edit = dlg.child_window(control_type="Edit")
edit.set_text("要输入的内容")
edit = dlg.child_window(control_type="Edit")
edit.set_text("要输入的内容")
模拟键盘输入(支持特殊键)
模拟键盘输入(支持特殊键)
edit.type_keys("Hello{ENTER}World", with_spaces=True)
edit.type_keys("Hello{ENTER}World", with_spaces=True)
特殊键:{ENTER} {TAB} {ESC} {DELETE} {BACKSPACE}
特殊键:{ENTER} {TAB} {ESC} {DELETE} {BACKSPACE}
修饰键:^ = Ctrl, % = Alt, + = Shift
修饰键:^ = Ctrl, % = Alt, + = Shift
例:Ctrl+A = ^a, Ctrl+Shift+S = ^+s
例:Ctrl+A = ^a, Ctrl+Shift+S = ^+s
undefinedundefined读取界面内容
读取界面内容
python
dlg = app.window(title="记事本")python
dlg = app.window(title="记事本")读取文本框内容
读取文本框内容
content = dlg.child_window(control_type="Edit").window_text()
content = dlg.child_window(control_type="Edit").window_text()
读取列表项
读取列表项
listbox = dlg.child_window(control_type="List")
items = [item.window_text() for item in listbox.children()]
listbox = dlg.child_window(control_type="List")
items = [item.window_text() for item in listbox.children()]
读取表格
读取表格
table = dlg.child_window(control_type="Table")
for row in table.children():
cells = [c.window_text() for c in row.children()]
print(" | ".join(cells))
undefinedtable = dlg.child_window(control_type="Table")
for row in table.children():
cells = [c.window_text() for c in row.children()]
print(" | ".join(cells))
undefined等待与同步
等待与同步
python
undefinedpython
undefined等待窗口出现
等待窗口出现
dlg = app.window(title="保存").wait("visible", timeout=10)
dlg = app.window(title="保存").wait("visible", timeout=10)
等待窗口消失
等待窗口消失
app.window(title="加载中...").wait_not("visible", timeout=30)
app.window(title="加载中...").wait_not("visible", timeout=30)
等待控件可用
等待控件可用
dlg.child_window(title="提交").wait("enabled", timeout=5)
undefineddlg.child_window(title="提交").wait("enabled", timeout=5)
undefined窗口管理
窗口管理
python
dlg = app.window(title="记事本")python
dlg = app.window(title="记事本")最大化 / 最小化 / 还原
最大化 / 最小化 / 还原
dlg.maximize()
dlg.minimize()
dlg.restore()
dlg.maximize()
dlg.minimize()
dlg.restore()
移动和调整大小
移动和调整大小
dlg.move_window(x=100, y=100, width=800, height=600)
dlg.move_window(x=100, y=100, width=800, height=600)
置顶
置顶
dlg.set_focus()
dlg.set_focus()
关闭
关闭
dlg.close()
undefineddlg.close()
undefined滚动
滚动
python
from pywinauto import mousepython
from pywinauto import mouse向下滚动 3 格(在指定坐标位置)
向下滚动 3 格(在指定坐标位置)
mouse.scroll(coords=(500, 400), wheel_dist=-3)
mouse.scroll(coords=(500, 400), wheel_dist=-3)
向上滚动 5 格
向上滚动 5 格
mouse.scroll(coords=(500, 400), wheel_dist=5)
mouse.scroll(coords=(500, 400), wheel_dist=5)
在控件内滚动(先获取控件位置)
在控件内滚动(先获取控件位置)
rect = dlg.child_window(control_type="List").rectangle()
mouse.scroll(coords=(rect.mid_point()), wheel_dist=-3)
undefinedrect = dlg.child_window(control_type="List").rectangle()
mouse.scroll(coords=(rect.mid_point()), wheel_dist=-3)
undefined鼠标坐标操作
鼠标坐标操作
python
from pywinauto import mousepython
from pywinauto import mouse移动鼠标到坐标
移动鼠标到坐标
mouse.move(coords=(500, 300))
mouse.move(coords=(500, 300))
在指定坐标左键点击
在指定坐标左键点击
mouse.click(coords=(500, 300))
mouse.click(coords=(500, 300))
右键点击
右键点击
mouse.right_click(coords=(500, 300))
mouse.right_click(coords=(500, 300))
双击
双击
mouse.double_click(coords=(500, 300))
undefinedmouse.double_click(coords=(500, 300))
undefined拖拽
拖拽
python
from pywinauto import mousepython
from pywinauto import mouse拖拽:从 (100,200) 到 (300,400)
拖拽:从 (100,200) 到 (300,400)
mouse.press(coords=(100, 200))
mouse.move(coords=(300, 400))
mouse.release(coords=(300, 400))
undefinedmouse.press(coords=(100, 200))
mouse.move(coords=(300, 400))
mouse.release(coords=(300, 400))
undefined典型工作流
典型工作流
1. 用 Desktop().windows() 列出当前打开的窗口
2. 用 app.connect() 连接到目标应用
3. 用 dlg.print_control_identifiers() 查看控件树
4. 根据控件类型和属性定位目标元素
5. 执行操作(click / set_text / type_keys / scroll)
6. 读取结果或等待操作完成1. 用 Desktop().windows() 列出当前打开的窗口
2. 用 app.connect() 连接到目标应用
3. 用 dlg.print_control_identifiers() 查看控件树
4. 根据控件类型和属性定位目标元素
5. 执行操作(click / set_text / type_keys / scroll)
6. 读取结果或等待操作完成安全规则
安全规则
- 操作前必须 HITL 确认:告知用户即将操作哪个应用的哪个控件
- 不自动关闭用户文档:不调用未保存文档的 close()
- 不操作管理员窗口:跳过 UAC 弹窗和系统设置
- 操作失败时截图反馈:让用户看到当前界面状态
- 每步操作间隔 0.5 秒:避免操作过快导致 UI 来不及响应
- 操作前必须 HITL 确认:告知用户即将操作哪个应用的哪个控件
- 不自动关闭用户文档:不调用未保存文档的 close()
- 不操作管理员窗口:跳过 UAC 弹窗和系统设置
- 操作失败时截图反馈:让用户看到当前界面状态
- 每步操作间隔 0.5 秒:避免操作过快导致 UI 来不及响应