Pywinauto使用方法,Pywinauto自动化入门指南

Pywinauto 是一个用于自动化 Windows GUI 应用程序的库。它可以帮助你模拟鼠标点击、键盘输入等操作,从而实现对 Windows 应用程序的自动化测试或自动化操作。

快速上手

Github:https://github.com/pywinauto/pywinauto

1.导入库

from pywinauto.application import Application

导入 Application 类,它用于启动和连接到应用程序。

2.应用程序

# 启动一个应用程序
app = Application().start("notepad.exe")  # 启动记事本

# 等待窗口出现
app.window(title="无标题 - 记事本").wait("visible", timeout=10)  # 等待窗口可见
  • Application 是 Pywinauto 的核心类,用于与应用程序交互。
  • backend="uia" 指定了后端类型为 UI Automation,这是 Pywinauto 支持的后端之一,适用于大多数现代 Windows 应用程序。
  • start 方法:用于启动应用程序,参数是应用程序的路径或可执行文件名。
  • wait 方法:用于等待窗口出现,确保应用程序已经启动并且窗口可见。

如果应用程序已经运行,可以通过 Desktop 类获取已打开的窗口。

from pywinauto import Desktop

# 获取所有窗口
windows = Desktop(backend="uia").windows()

# 查找特定窗口
for win in windows:
    if "记事本" in win.window_text():
        app = win.application()
        break

# 操作窗口
app.window(title="无标题 - 记事本").set_focus()  # 将焦点设置到记事本窗口
  • Desktop 类:用于获取当前桌面的所有窗口。
  • windows 方法:返回一个窗口列表,可以通过窗口标题等属性来查找特定窗口。
  • application 方法:获取窗口所属的应用程序对象。

如果应用程序已经运行,也可以通过 Application 类的 connect 方法连接到它。

from pywinauto.application import Application

# 连接到已运行的应用程序
app = Application().connect(title="无标题 - 记事本", timeout=10)  # 通过窗口标题连接

# 操作窗口
app.window(title="无标题 - 记事本").set_focus()  # 将焦点设置到记事本窗口

如果已知应用程序的进程 ID,也可以通过进程 ID 连接到应用程序。

from pywinauto.application import Application

# 假设已知进程 ID
pid = 1234  # 替换为实际的进程 ID

# 连接到应用程序
app = Application().connect(process=pid)

# 操作窗口
app.window(title="无标题 - 记事本").set_focus()  # 将焦点设置到记事本窗口

3.获取窗口

获取应用程序窗口是进行自动化操作的关键步骤,常用的方式之一,通过窗口的标题来获取窗口对象。

from pywinauto.application import Application

# 启动应用程序
app = Application().start("notepad.exe")

# title可以作为关键词进行匹配
window = app.window(title="无标题 - 记事本")

# 通过正则表达式匹配窗口标题
window = app.window(title_re=".*记事本.*")window.wait("visible", timeout=10)  # 等待窗口可见

# 操作窗口
window.set_focus()  # 将焦点设置到窗口
  • window 方法:通过窗口标题获取窗口对象。
  • wait 方法:确保窗口已经可见。

有些窗口可以通过类名来获取,类名是窗口的内部标识。

from pywinauto.application import Application

# 启动应用程序
app = Application().start("notepad.exe")

# 通过窗口类名获取窗口
window = app.window(class_name="Notepad")
window.wait("visible", timeout=10)  # 等待窗口可见

# 操作窗口
window.set_focus()  # 将焦点设置到窗口

如果应用程序只有一个顶层窗口,可以使用 top_window 方法直接获取。

from pywinauto.application import Application

# 启动应用程序
app = Application().start("notepad.exe")

# 获取顶层窗口
window = app.top_window()
window.wait("visible", timeout=10)  # 等待窗口可见

# 操作窗口
window.set_focus()  # 将焦点设置到窗口

如果不确定窗口的标题或类名,可以通过 Desktop 类获取所有窗口,然后通过条件筛选。

from pywinauto import Desktop

# 获取所有窗口
windows = Desktop(backend="uia").windows()

# 筛选特定窗口
for win in windows:
    if "记事本" in win.window_text():
        window = win
        break

# 操作窗口
window.set_focus()  # 将焦点设置到窗口

4.获取控件

某些控件可能有唯一的自动化 ID,可以通过这个 ID 来获取控件。

from pywinauto.application import Application

# 启动应用程序
app = Application().start("notepad.exe")

# 通过窗口标题获取窗口
window = app.window(title="无标题 - 记事本")
window.wait("visible", timeout=10)  # 等待窗口可见

# 通过自动化 ID 获取控件
edit_box = window.child_window(auto_id="15", control_type="Edit")

# 操作控件
edit_box.set_text("Hello, pywinauto!")  # 在编辑框中输入文本
  • auto_id 参数:通过控件的自动化 ID 获取控件对象。

如果窗口中有多个相同类型的控件,可以通过索引来区分它们。

from pywinauto.application import Application

# 启动应用程序
app = Application().start("notepad.exe")

# 通过窗口标题获取窗口
window = app.window(title="无标题 - 记事本")
window.wait("visible", timeout=10)  # 等待窗口可见

# 通过索引获取控件
edit_box = window.child_window(control_type="Edit", found_index=0)

# 操作控件
edit_box.set_text("Hello, pywinauto!")  # 在编辑框中输入文本
  • found_index 参数:通过索引获取控件对象。found_index=0 表示获取第一个匹配的控件。

如果窗口中有多个相同类名的控件,可以通过类名和索引的组合来获取特定的控件。

from pywinauto.application import Application

# 启动应用程序
app = Application().start("notepad.exe")

# 通过窗口标题获取窗口
window = app.window(title="无标题 - 记事本")
window.wait("visible", timeout=10)  # 等待窗口可见

# 通过类名和索引组合获取控件
edit_box = window.child_window(class_name="Edit", found_index=0)

# 操作控件
edit_box.set_text("Hello, pywinauto!")  # 在编辑框中输入文本

如果控件标题较长或不确定,可以使用正则表达式来匹配。

from pywinauto.application import Application

# 启动应用程序
app = Application().start("notepad.exe")

# 通过窗口标题获取窗口
window = app.window(title="无标题 - 记事本")
window.wait("visible", timeout=10)  # 等待窗口可见

# 通过正则表达式匹配控件标题
edit_box = window.child_window(title_re=".*编辑.*", control_type="Edit")

# 操作控件
edit_box.set_text("Hello, pywinauto!")  # 在编辑框中输入文本
  • title_re 参数:通过正则表达式匹配控件标题。

如果需要更灵活的筛选方式,可以通过 wrapper_object 方法获取所有子控件,然后根据条件筛选。

from pywinauto.application import Application

# 启动应用程序
app = Application().start("notepad.exe")

# 通过窗口标题获取窗口
window = app.window(title="无标题 - 记事本")
window.wait("visible", timeout=10)  # 等待窗口可见

# 获取所有子控件
children = window.wrapper_object().children()

# 筛选特定控件
for child in children:
    if child.class_name() == "Edit":
        edit_box = child
        break

# 操作控件
edit_box.set_text("Hello, pywinauto!")  # 在编辑框中输入文本
  • wrapper_object 方法:获取窗口的包装对象。
  • children 方法:获取所有子控件。
  • class_name 方法:获取控件的类名。

如果知道控件的类型,可以通过 control_type 参数来获取控件。

from pywinauto.application import Application

# 启动应用程序
app = Application().start("notepad.exe")

# 通过窗口标题获取窗口
window = app.window(title="无标题 - 记事本")
window.wait("visible", timeout=10)  # 等待窗口可见

# 通过控件类型获取控件
edit_box = window.child_window(control_type="Edit")

# 操作控件
edit_box.set_text("Hello, pywinauto!")  # 在编辑框中输入文本
  • control_type 参数:通过控件类型获取控件对象。

5.控件结构

print_control_identifiers 方法可以打印出窗口中所有控件的标识符,包括它们的标题、类名、自动化 ID 等信息。

from pywinauto.application import Application

# 启动应用程序
app = Application().start("notepad.exe")

# 通过窗口标题获取窗口
window = app.window(title="无标题 - 记事本")
window.wait("visible", timeout=10)  # 等待窗口可见

# 打印窗口中所有控件的标识符
window.print_control_identifiers()

如果需要获取某个控件的子控件,可以使用 wrapper_object 方法获取控件的包装对象,然后通过 children 方法获取其子控件。

from pywinauto.application import Application

# 启动应用程序
app = Application().start("notepad.exe")

# 通过窗口标题获取窗口
window = app.window(title="无标题 - 记事本")
window.wait("visible", timeout=10)  # 等待窗口可见

# 获取某个控件(例如编辑框)
edit_box = window.child_window(control_type="Edit")

# 获取该控件的包装对象
edit_wrapper = edit_box.wrapper_object()

# 获取该控件的子控件
children = edit_wrapper.children()

# 打印子控件信息
for child in children:
    print(f"子控件标题: {child.window_text()}, 类名: {child.class_name()}, 自动化ID: {child.automation_id()}")

pywinauto 还提供了一个 dump_tree 方法,可以打印出窗口中控件的树形结构。这对于理解窗口的层次结构非常有帮助。

from pywinauto.application import Application

# 启动应用程序
app = Application().start("notepad.exe")

# 通过窗口标题获取窗口
window = app.window(title="无标题 - 记事本")
window.wait("visible", timeout=10)  # 等待窗口可见

# 打印窗口中控件的树形结构
window.dump_tree()

快速进阶

pywinauto 中操作应用程序、窗口和控件的常见方式 。

1.操作窗口

# 获取窗口
window = app.window(title="无标题 - 记事本")

# 最大化窗口
window.maximize()

# 最小化窗口
window.minimize()

# 恢复窗口
window.restore()

# 关闭窗口
window.close()

# 设置窗口焦点
window.set_focus()

# 等待窗口可见
window.wait("visible", timeout=10)

2.操作控件

# 获取编辑框控件
edit_box = window.child_window(control_type="Edit")
# 输入文本
edit_box.set_text("Hello, pywinauto!")

# 获取按钮控件
button = window.child_window(title="保存", control_type="Button")
# 点击按钮
button.click()

# 获取编辑框控件
edit_box = window.child_window(control_type="Edit")
# 获取控件的文本
text = edit_box.window_text()

# 获取编辑框控件
edit_box = window.child_window(control_type="Edit")
# 获取控件的属性
print(edit_box.class_name())  # 获取控件的类名
print(edit_box.control_id())  # 获取控件的控件 ID

# 获取编辑框控件
edit_box = window.child_window(control_type="Edit")
# 滚动控件
edit_box.scroll("down", "page")  # 向下滚动一页

3.高级操作

from pywinauto.keyboard import send_keys

# 获取窗口
window = app.window(title="无标题 - 记事本")
# 设置窗口焦点
window.set_focus()

# 模拟键盘输入
send_keys("Hello, {ENTER} pywinauto!")

# 获取按钮控件
button = window.child_window(title="保存", control_type="Button")
# 获取按钮的位置
x, y = button.rectangle().mid_point()
# 模拟鼠标点击
click(coords=(x, y))

# 等待控件出现
edit_box = window.child_window(control_type="Edit").wait("visible", timeout=10)

# 检查控件是否存在
if window.child_window(control_type="Edit").exists():
    print("编辑框存在")
else:
    print("编辑框不存在")