Windows应用自动化新手必备:Pywinauto与元素定位工具入门

2025-11-27 21:03:04 / 礼包兑换

前言

- Pywinauto工具简介 pywinauto 是一个 Python 库,专门用于自动化 Windows GUI。它允许开发者通过编程控制和操作 Windows 应用程序的界面,包括点击按钮、输入文本、获取控件信息等。pywinauto 支持传统的窗口应用(Win32应用)以及现代的桌面应用程序(例如 WPF 或 UWP)。它的核心优势在于简化了自动化测试和操作过程,尤其适用于需要重复操作的 Windows 程序。

- Windows元素定位工具:Inspect Inspect 是一个由 Microsoft 提供的工具,专门用于检查 Windows 应用程序的 UI 元素。它可以让开发者查看和获取界面中每个控件的详细信息,包括控件的属性(如名称、类型、状态)及其在界面中的位置。开发者可以利用这些信息,帮助 pywinauto 定位和操作目标控件。Inspect 主要用于辅助开发人员识别元素,特别是在测试和自动化脚本中非常实用。

- Windows元素定位工具:Spy++ Spy++ 是 Microsoft Visual Studio 附带的工具,用于捕获和显示 Windows 应用程序的消息和元素。它能够实时跟踪应用程序中的窗口和控件,并提供详细的消息传递和元素层次结构。与 Inspect 类似,Spy++ 也帮助开发者分析和调试应用界面,找出元素的 ID、类名等信息。它特别适合于需要深入了解应用程序消息和控件结构的开发者。

- 演示程序:Xshell 6

CSDN下载链接: https://download.csdn.net/download/qq_45664055/90839608

Pywinauto中文文档: https://www.kancloud.cn/gnefnuy/pywinauto_doc/1193035

一、Pywinauto基础

安装指定版本或最新版本:pip3 install pywinauto==0.6.8

1、启动程序方法

from pywinauto.application import Application

# 启动应用程序,并使用 UI 自动化的 UIAutomation(uia)后端

# Application(backend="uia") 通过指定 backend 参数来选择使用哪种后端进行 UI 控件的操作。

# backend 参数可以设置为以下几种方法:

# 1. "win32" - 使用经典的 Win32 后端,适用于传统的 Windows 应用程序

# 2. "uia" - 使用 UIAutomation 后端,适用于支持 UIAutomation 的现代 Windows 应用程序

app = Application(backend="uia").start(r"C:\Install\Xshell7\Xshell.exe")

2、获取应用程序窗口名称

方法一:获取当前所有打开的应用窗口名称

from time import sleep

from pywinauto.application import Application

from pywinauto import Desktop

app = Application(backend="uia").start(r"C:\Install\Xshell7\Xshell.exe")

# 等待软件启动

sleep(5)

# 获取当前桌面上的所有窗口

windows = Desktop(backend="uia").windows()

# 打印每个窗口的名称

for window in windows:

print(window.window_text())

方法二:通过 Inspect 查看

3、连接到已运行的应用程序

如果应用程序已经在运行中,可以使用 connect() 方法来连接到它

app = Application(backend="uia").connect(title="Xshell 6 (Free for Home/School)")

二、元素定位与控件操作

1、查看程序所有控件参数

from pywinauto.application import Application

app = Application(backend="uia").start(r"C:\Install\Xshell7\Xshell.exe")

# 获取标题为 "Xshell 6 (Free for Home/School)" 的窗口实例,用于后续操作

window = app.window(title="Xshell 6 (Free for Home/School)")

# 两种方法:

# 打印窗口控件的标识符,并返回控件层级结构

# 参数:

# depth: 控件层级的深度,None 表示无限深度,限制深度可以帮助缩小搜索范围。

# filename: 将控件标识符输出到指定的文件,None 表示不输出到文件,直接打印到控制台。

window.print_control_identifiers(depth=None, filename="control_identifiers.txt")

# 打印窗口控件的树形结构,并返回控件层级信息

window.dump_tree(depth=2, filename=None)

# 总结:print_control_identifiers 侧重于控件的标识符,dump_tree 侧重于控件的层级关系

2、获取指定控件相关信息

from pywinauto.application import Application

app = Application(backend="uia").start(r"C:\Install\Xshell7\Xshell.exe")

window = app.window(title="Xshell 6 (Free for Home/School)")

button = window.child_window(title="新建", control_type="Button")

button.click()

edit = window.child_window(title="名称(N):", auto_id="1028", control_type="Edit")

print("控件名称:", edit.element_info.name)

print("控件类名:", edit.element_info.class_name)

print("控件类型:", edit.element_info.control_type)

print("控件自动化ID:", edit.element_info.automation_id)

print("控件是否启用:", edit.is_enabled())

print("控件的父控件:", edit.parent())

3、元素定位

通过 Inspect 和 print_control_identifiers 组合获取控件信息,先通过 Inspect 定位到你想要操作的控件,然后通过 print_control_identifiers 获取所有控件 ,再 control_identifiers.txt 中查找控件

1、启用红框中的按钮,然后鼠标拖到 新建 控件上

2、通过 print_control_identifiers 获取所有控件,在 control_identifiers.txt 查找 新建 控件(如果有多个 新建 控件,就在 Inspect 中查找相关的参数,去定位到指定位置)

3、通过child_window(title=“新建”, control_type=“Button”) 定位元素

4、常见的 control_type 类型

control_type 是 pywinauto 中用来识别和区分 UI 元素类型的属性。每个控件都有一个唯一的 control_type,可以用来帮助你在自动化操作中找到并与特定的 UI 元素进行交互

--------------------------------

Button - 按钮控件

--------------------------------

TextBox - 文本框控件

--------------------------------

ComboBox - 下拉框控件

--------------------------------

Edit - 编辑控件(例如,文本输入框)

--------------------------------

CheckBox - 复选框控件

--------------------------------

RadioButton - 单选按钮控件

--------------------------------

List - 列表控件

--------------------------------

Window - 窗口控件

--------------------------------

Pane - 面板控件

--------------------------------

Image - 图片控件

--------------------------------

Menu - 菜单控件

--------------------------------

MenuItem - 菜单项控件

--------------------------------

Tab - 标签控件

--------------------------------

三、常用操作方法

1、点击操作

from pywinauto.application import Application

app = Application(backend="uia").start(r"C:\Install\Xshell7\Xshell.exe")

window = app.window(title="Xshell 6 (Free for Home/School)")

# click() 标准的点击方法; click_input() 模拟更为真实的用户点击输入行为,适合处理更复杂的点击场景

button = window.child_window(title="新建", control_type="Button")

button.click()

# 以上点击方法报错时,使用以下方法

# button.click_input()

2、输入操作

edit = window.child_window(title="名称(N):", auto_id="1028", control_type="Edit")

edit.type_keys("软件测试服务器")

3、清空操作

edit_1 = window.child_window(title="名称(N):", auto_id="1028", control_type="Edit")

edit_1.set_text('')

4、关闭应用窗口

app.kill() # 强制关闭应用

5、下拉框选择(示例一)

from pywinauto.application import Application

app = Application(backend="uia").start(r"C:\Install\Xshell7\Xshell.exe")

window = app.window(title="Xshell 6 (Free for Home/School)")

button = window.child_window(title="新建", control_type="Button")

button.click()

# 找到 ComboBox 下拉框,下拉框需要点击才会显示下拉列表数据

combo_box = window.child_window(title="协议(P):", auto_id="541", control_type="ComboBox")

# 图片一数据

# window.print_control_identifiers(depth=None, filename="control_identifiers.txt")

# 下拉列表数据不打开是无法获取到的,需要先点击下拉框,然后通过print_control_identifiers获取数据再定位

button_1 = combo_box.child_window(title="打开", auto_id="DropDown", control_type="Button")

button_1.click()

# 图片二数据

# window.print_control_identifiers(depth=None, filename="control_identifiers.txt")

# 定位到名为 "SFTP" 的 ListItem 控件

list_item = window.child_window(title="SFTP", control_type="ListItem")

# 点击该项, 这里点击只支持click_input()方法,click()方法会报错

list_item.click_input()

6、下拉框选择(示例二)

# 下拉框示例程序,直接运行或打包成EXE都可以

import tkinter as tk

# 创建主窗口

root = tk.Tk()

root.title("下拉列表选择框")

root.geometry("300x200+630+80")

# 下拉列表的选项数据

options = ["选项1", "选项2", "选项3", "选项4", "选项5"]

# 创建一个变量来保存选择的值

selected_option = tk.StringVar()

selected_option.set(options[0]) # 默认选中第一个选项

# 创建下拉列表(OptionMenu)

dropdown = tk.OptionMenu(root, selected_option, *options)

dropdown.pack(pady=20) # 添加到窗口并设置间距

# 启动主循环

root.mainloop()

# 操作下拉框程序

from pywinauto.application import Application

# import subprocess

# import time

# 启动 EXE 文件

# subprocess.Popen(["test1.exe"])

# time.sleep(3)

# 程序标题

app = Application(backend="uia").connect(title="下拉列表选择框")

window = app.window(title="下拉列表选择框")

# 第一次获取控件

# window.print_control_identifiers()

pane2 = window.child_window(best_match="Pane2", control_type="Pane")

pane2.click_input()

# 下拉列表数据窗口标题

list_data = Application(backend="uia").connect(title="上下文").window(title="上下文")

# 第二次获取控件

# list_data.print_control_identifiers()

menu_item = list_data.child_window(auto_id="2", control_type="MenuItem")

menu_item.click_input()

四、等待与同步

1、wait 方法

主要用法: 1. 等待控件可见或可操作 wait 方法会阻塞代码执行,直到满足给定的条件(如控件可见、可点击等)

2. 常见的等待条件: visible: 等待控件变得可见 exists: 等待控件存在 enabled: 等待控件可用 ready: 等待控件处于准备好进行交互的状态

from pywinauto.application import Application

app = Application(backend="uia").start(r"C:\Install\Xshell7\Xshell.exe")

window = app.window(title="Xshell 6 (Free for Home/School)")

button = window.child_window(title="新建", control_type="Button")

button.click()

# 通过这个勾选框模拟输入框是否可用

# check_box = window.child_window(title="连接异常关闭时自动重新连接(A) ", auto_id="1632", control_type="CheckBox")

# check_box.click()

# 处理超时异常

try:

# 输入框

edit = window.child_window(title="间隔(V): ", auto_id="1631", control_type="Edit")

edit.wait('enabled', timeout=5) # 等待5秒

edit.type_keys(2)

except Exception as e:

print(f"错误:{e}")