uiautomation基础教程
uiautomation 的核心是「控件」和「定位」:
1、控件(Control):桌面应用的可交互元素(窗口、按钮、输入框、菜单等),每个控件有唯一的层级和属性。
2、控件属性(关键定位依据):
Name:控件显示文本(如按钮 “确定”、窗口标题)。
ClassName:控件类名(如输入框 Edit、按钮 Button)。
AutomationId:控件唯一标识(WPF/Qt 应用常用,最稳定)。
ControlType:控件类型(如 ControlType.Button、ControlType.Edit)。
3、控件层级:所有桌面控件构成树形结构(桌面 → 应用窗口 → 子控件 → ...),uiautomation 可通过层级遍历或直接定位控件。
要求 Python 3.6+,下载地址:https://www.python.org/downloads/,安装时勾选「Add Python to PATH」。
2. 安装 uiautomation 库-命令行执行以下命令(国内用户可加清华源加速):
pip install uiautomation -i https://pypi.tuna.tsinghua.edu.cn/simple
3. 必备辅助工具(定位控件用)
必须用工具查看控件属性,推荐:
Inspect.exe(微软官方,首选):支持所有 UI 框架,能查看控件的 Name、AutomationId、ControlType 等核心属性。
下载地址:https://learn.microsoft.com/zh-cn/windows/win32/winauto/inspect-exe
用法:打开后点击左上角「十字图标」,拖动到目标控件,右侧「AutomationId」「Name」「ClassName」即为定位关键信息。
三、第一个示例:操控记事本(Notepad)
目标:打开记事本 → 输入文本 → 保存文件 → 关闭窗口,全程用 uiautomation 实现。
步骤 1:导入库并启动记事本
先导入 uiautomation 和 subprocess(用于启动应用),启动记事本后等待窗口加载:
import uiautomation as auto
import subprocess
import time
# 启动记事本(subprocess 用于执行系统命令)
subprocess.Popen("notepad.exe")
# 等待窗口加载(1 秒足够,根据电脑性能调整)
time.sleep(1)
步骤 2:定位记事本窗口
通过「窗口标题」(Name 属性)定位记事本主窗口,uiautomation 中用 WindowControl 表示窗口控件:
# 定位记事本窗口(Name 为「无标题 - 记事本」,ClassName 为「Notepad」) notepad_window = auto.WindowControl( Name="无标题 - 记事本", ClassName="Notepad" ) # 激活窗口(确保在前台,避免操作失败) notepad_window.SetActive() time.sleep(0.5) # 短暂休眠,确保激活成功
步骤 3:定位输入框并输入文本
记事本的输入框是「Edit」类控件(ClassName="Edit"),用 EditControl 定位,通过 SendKeys 模拟输入:
# 定位输入框(父控件是记事本窗口,ClassName="Edit")
edit_box = notepad_window.EditControl(ClassName="Edit")
# 输入文本(支持中文、特殊字符)
edit_box.SendKeys("Hello uiautomation! 这是原生 UI 自动化~")
步骤 4:通过菜单保存文件
记事本的「文件→保存」菜单是 MenuItemControl,需先定位「文件」菜单,再点击「保存」:
# 1. 定位「文件」菜单(父窗口,Name="文件",ControlType=MenuItem) file_menu = notepad_window.MenuItemControl(Name="文件") # 点击「文件」菜单(展开子菜单) file_menu.Click() time.sleep(0.5) # 2. 定位「保存」子菜单(父菜单是「文件」,Name="保存") save_menu = file_menu.MenuItemControl(Name="保存") save_menu.Click() time.sleep(1) # 等待「另存为」窗口弹出
步骤 5:处理「另存为」窗口(输入路径 + 保存)
「另存为」窗口也是 WindowControl,需定位「文件名输入框」和「保存按钮」:
# 定位「另存为」窗口(Name="另存为",ClassName="#32770") save_window = auto.WindowControl(Name="另存为", ClassName="#32770") save_window.SetActive() # 激活窗口 # 定位「文件名」输入框(ClassName="Edit",索引 1,因窗口有多个 Edit 控件) file_name_edit = save_window.EditControl(ClassName="Edit", Index=1) # 输入保存路径(r 表示原始字符串,避免路径转义) file_name_edit.SendKeys(r"C:\test_uiauto.txt") time.sleep(0.5) # 定位「保存」按钮(Name="保存",ClassName="Button") save_button = save_window.ButtonControl(Name="保存", ClassName="Button") save_button.Click() time.sleep(1) # 等待保存完成
步骤 6:关闭记事本窗口
直接调用窗口控件的 Close() 方法关闭:
# 关闭记事本窗口 notepad_window.Close()
完整代码
import uiautomation as auto
import subprocess
import time
# 1. 启动记事本
subprocess.Popen("notepad.exe")
time.sleep(1)
# 2. 定位记事本窗口并激活
notepad_window = auto.WindowControl(Name="无标题 - 记事本", ClassName="Notepad")
notepad_window.SetActive()
time.sleep(0.5)
# 3. 输入文本
edit_box = notepad_window.EditControl(ClassName="Edit")
edit_box.SendKeys("Hello uiautomation! 这是原生 UI 自动化~")
# 4. 菜单操作:文件→保存
file_menu = notepad_window.MenuItemControl(Name="文件")
file_menu.Click()
time.sleep(0.5)
save_menu = file_menu.MenuItemControl(Name="保存")
save_menu.Click()
time.sleep(1)
# 5. 另存为窗口操作
save_window = auto.WindowControl(Name="另存为", ClassName="#32770")
save_window.SetActive()
file_name_edit = save_window.EditControl(ClassName="Edit", Index=1)
file_name_edit.SendKeys(r"C:\test_uiauto.txt")
time.sleep(0.5)
save_button = save_window.ButtonControl(Name="保存", ClassName="Button")
save_button.Click()
time.sleep(1)
# 6. 关闭窗口
notepad_window.Close()
四、核心操作详解
1. 控件定位的 3 种常用方式
uiautomation 定位控件的核心是「指定控件类型 + 筛选属性」,支持多种组合,优先级:AutomationId > Name > ClassName > Index。
(1)直接定位(已知父控件)
如果知道控件的父级(如窗口→按钮),直接通过父控件调用子控件类型:
# 父窗口 → 子按钮(已知 Name 和 ClassName) button = 父控件.ButtonControl(Name="确定", ClassName="Button") # 父窗口 → 输入框(已知 AutomationId,最稳定) edit = 父控件.EditControl(AutomationId="txtUsername")
(2)通过索引定位(同类型多个控件)
如果同一父控件下有多个相同类型的控件(如多个输入框),用 Index 区分(从 0 开始):
# 定位第 2 个 Edit 控件(Index=1) second_edit = 父控件.EditControl(Index=1)
(3)全局搜索定位(未知父控件)
如果不知道父控件,用 FindFirst 全局搜索(需指定控件类型和筛选条件):
# 全局搜索「百度一下」按钮(ControlType=Button,Name="百度一下")
baidu_button = auto.FindFirst(
auto.PatternMatch.ControlType(auto.ControlType.Button),
auto.PatternMatch.Name("百度一下")
)
2. 常用控件类型及操作
uiautomation 为不同类型控件提供了专属方法,以下是最常用的控件及核心操作:
| 控件类型 | 用途 | 核心操作 | 示例代码 |
|---|---|---|---|
WindowControl |
应用窗口 | 激活、关闭、最大化、获取标题 | window.SetActive() window.Close() |
ButtonControl |
按钮 | 点击、获取文本 | button.Click() print(button.Name) |
EditControl |
输入框 | 输入文本、获取文本、清空 | edit.SendKeys("内容") edit.GetValue() |
MenuItemControl |
菜单选项 | 点击、展开子菜单 | menu.Click() submenu = menu.MenuItemControl() |
CheckBoxControl |
复选框 | 勾选、取消勾选、判断是否勾选 | checkbox.SetCheck(True) checkbox.IsChecked() |
ComboBoxControl |
下拉框 | 展开、选择选项 | combo.Expand() combo.SelectItem("选项1") |
3. 关键辅助操作
(1)模拟键盘快捷键
用 auto.SendKeys() 模拟全局快捷键(如 Ctrl+C、Ctrl+V),支持的特殊键:
{Ctrl} {Shift} {Alt} {Enter} {Backspace} {Tab} 等
# 模拟 Ctrl+S 保存
auto.SendKeys("{Ctrl}s")
# 模拟 Ctrl+A 全选 + Ctrl+C 复制
auto.SendKeys("{Ctrl}a")
auto.SendKeys("{Ctrl}c")
(2)等待控件出现(避免定位失败)
用 WaitForExist() 等待控件加载,超时抛出异常(比 time.sleep() 更灵活):
# 等待按钮出现,超时 5 秒(True 表示找到返回控件,False 表示超时)
button = 父控件.ButtonControl(Name="确定").WaitForExist(timeout=5)
if button:
button.Click()
else:
print("控件未找到!")
(3)获取控件属性
通过控件对象的属性获取信息(如文本、是否可见):
# 获取按钮文本 print(button.Name) # 获取输入框内容 print(edit.GetValue()) # 判断控件是否可见 print(control.IsVisible()) # 获取控件位置和大小 print(control.BoundingRectangle) # 返回 (x1, y1, x2, y2)
五、常见问题与解决方案
1. 控件定位失败
原因 1:控件属性错误(如 Name 拼写错误、ClassName 不对)→ 用 Inspect 重新确认属性。
原因 2:控件未加载完成 → 用 WaitForExist(timeout=5) 替代 time.sleep()。
原因 3:应用需要管理员权限 → 以管理员身份运行 Python 脚本。
原因 4:控件在后台窗口 → 先调用 窗口.SetActive() 激活窗口。
2. 输入框无法输入
确保输入框已获取焦点:edit.SetFocus() 后再 SendKeys()。
避免特殊字符转义:路径用原始字符串 r"C:\path",特殊键用 {} 包裹(如 {Enter})。
3. 菜单无法点击
菜单需要先展开父菜单:点击「文件」后,需等待子菜单显示(time.sleep(0.5))再点击子菜单。
六、扩展示例:操控 Chrome 浏览器
目标:打开 Chrome → 访问百度 → 输入关键词 → 点击搜索。
前提条件
Chrome 安装路径默认:C:\Program Files\Google\Chrome\Application\chrome.exe。
用 Inspect 确认 Chrome 控件属性(地址栏 Name="地址和搜索栏",搜索按钮 Name="百度一下")。
代码示例
import uiautomation as auto
import subprocess
import time
# 1. 启动 Chrome 并访问百度
chrome_path = r"C:\Program Files\Google\Chrome\Application\chrome.exe"
subprocess.Popen([chrome_path, "https://www.baidu.com"])
time.sleep(3) # Chrome 启动较慢,延长等待时间
# 2. 定位 Chrome 窗口(标题包含「百度一下」)
chrome_window = auto.WindowControl(Name_re=".*百度一下.*", ClassName="Chrome_WidgetWin_1")
chrome_window.SetActive()
time.sleep(1)
# 3. 定位地址栏并输入关键词(百度首页地址栏 Name="地址和搜索栏")
address_bar = chrome_window.EditControl(Name="地址和搜索栏")
address_bar.SetFocus()
address_bar.SendKeys("uiautomation 教程{Enter}") # 输入后回车搜索
# 4. 保持窗口打开 5 秒
time.sleep(5)
七、总结
uiautomation 库的核心是「精准定位控件 + 调用专属操作」,新手入门关键:
熟练使用 Inspect 工具获取控件的 Name、AutomationId、ClassName。
优先用 AutomationId 定位(最稳定),其次是 Name 和 ClassName。
操作前确保控件加载完成(WaitForExist)和窗口激活(SetActive)。
后续可学习:控件遍历(Control.GetChildren())、弹窗处理、异常捕获、复杂应用(如 Excel、Qt 程序)自动化等。如果需要特定应用的详细教程,可以补充说明场景!