pywinauto是一个用于自动化Python 模块,适合Windows系统的软件(GUI),可以通过Pywinauto遍历窗口(对话框)和窗口里的控件,也可以控制鼠标和键盘输入,所以它能做的事情比之前介绍的pysimplegui更多
一般使用pip安装就行了
pip install pywinauto
官网文档:https://pywinauto.readthedocs.io/en/latest/
我们要控制软件的第一件事就是启动一个Windows软件,每一个软件(进程)都是一个Application对象
实例化Application对象的时候可以传入一个backend参数,可选值为win32(默认)和 uia ,
win32对应的框架:MFC、VB6、VCL、简单的 WinForms 控件和大多数旧的遗留应用程序
uia对应的框架:WinForms、WPF、商店应用程序、Qt5、浏览器
如果无法知道要测试的软件是属于哪种框架,可以使用 Inspect(对应uia) 和 Spy++(对应win32) 看看,你看哪个显示得更全就选哪个。Inspect和Spy++需要自己安装一下
下面是Application对象的主要方法
| 方法 | 常用参数 | 说明 |
|---|
| start() | cmd_line、timeout、retry_interval | 通过cmd命令启动一个软件(进程) |
| connect() | process、handle、path、timeout | 连接一个进程,一般是使用进程号(任务管理器可以看到) |
| top_window() | / | 获取应用的顶层窗口 |
| window() | title、title_re、class_name、best_match | 获取单个窗口(WindowSpecification) |
| windows() | title、title_re、class_name | 获取多个窗口(UIAWrapper) |
| is64bit() | / | 是否64位应用 |
| cpu_usage | interval | CPU占用率 |
| wait_cpu_usage_lower() | threshold、timeout | 等待CPU占率小于某个阈值 |
| active()() | / | 搜索返回一个激活的窗口 |
| kill() | soft | 结束进程 |
| wait_for_process_exit() | timeout、retry_interval | 等待进程结束 |
举例,启动一个微信应用,通过进程号连接,进程号就是在任务管理器里详细信息看到的PID

from pywinauto import Application
app = Application(backend="uia")
app.connect(process=6556)
print("is64bit:", app.is64bit())
print("cpu_usage:", app.cpu_usage())
app.wait_cpu_usage_lower()
print("kill:", app.kill())
print("wait_for_process_exit:", app.wait_for_process_exit())
我们要获取窗口,一个窗口都是一个WindowSpecification对象,可以通过Application对象的window()方法获取,参数可以是title、classname或者best_match等,这都可以在inspect.exe上看到,不过需要注意的是inspect看到的Name其实对应的是window()的title参数

WindowSpecification对象常用的方法如下
| 方法 | 常用参数 | 说明 |
|---|
| maximize() | / | 最大化窗口 |
| minimize() | / | 最小化窗口 |
| restore() | / | 恢复窗口 |
| close() | / | 关闭窗口 |
| get_show_state() | / | 获取窗口状态,0正常1最大化2最小化 |
| was_maximized() | / | 当前是否最大化 |
| draw_outline() | colour、thickness | 给窗口画个框以便定位 |
| print_control_identifiers() | / | 打印所有子窗口和子元素(会打印出对应的control_type) |
| child_window() | title、control_type | 获取子窗口 |
| exists() | timeout | 窗口是否存在 |
| wait() | wait_for, timeout | 等待窗口变成某个状态(exists、visible、enabled、ready、active) |
| wait_not() | wait_for_not, timeout | 等待窗口不处于某个状态(exists、visible、enabled、ready、active) |
dlg = app.window(class_name="WeChatMainWndForPC")
print("get_show_state:", dlg.get_show_state())
print("was_maximized:", dlg.was_maximized())
dlg.print_control_identifiers()
dlg.draw_outline()
dlg.maximize()
dlg.restore()
dlg.minimize()
dlg.close()
一个窗口里一般都会有各种各样的元素,比如说按钮 (Button)、编辑栏(Edit)、树状视图(Tree View)、复选框(CheckBox)、对话框(Dialog)、工具栏(Toolbar)、状态栏(StatusBar)、列表框(ListBox)、窗格(Pane)、菜单(Menu)、菜单栏(MenuItem)、静态内容(Static)、工具提示(ToolTips)、列表控件(ListView)、单选框(RadioButton)、组合框(ComboBox)、选项卡控件(TabControl)、组框 (GroupBox)、弹出菜单(PopupMenu)、头部(Header)等
因为控件类型太多了不能一个一个学习,但是它们都有一个 element_info 的属性,访问之后会返回一个继承于ElementInfo的对象(UIAElementInfo或HwndElementInfo),比较重要的属性或方法如下
| 方法或属性 | 常用参数 | 说明 |
|---|
| name | / | 元素的真实名(一般是title) |
| visible | / | 元素是否可见 |
| rich_text | / | 元素的全名 |
| rectangle | / | 返回元素的位置以及宽高 |
| class_name | / | 类名 |
| enabled | / | 元素是否处于可用状态 |
| parent | / | 返回父元素 |
| children() | title、title_re、class_name、best_match | 返回符合要求的子元素(列表) |
| iter_children() | title、title_re、class_name、best_match | 迭代符合要求的子元素(生成器) |
这些元素除了有element_info可以获取一些元素的主要信息,它们还都被包装成一个Wrapper,所以也可以学一下BaseWrapper的常用方法和属性。其实BaseWrapper的方法基本上都是对ElementInfo进一步包装,我只列出部分方法,如下表
| 方法或属性 | 常用参数 | 说明 |
|---|
| element_info | / | 返回当前元素的ElementInfo对象 |
| from_point() | x、y | 通过坐标查找ElementInfo |
| class_name() | / | 类名,实际是调用element_info.class_name |
| friendly_class_name() | / | 友好的类名,同上 |
| window_text() | / | 元素的文本,实际是调用element_info.rich_text |
| is_visible() | / | 元素是否可见,实际是调用element_info.visible |
| is_enabled() | / | 元素是否可用,实际是调用element_info.enabled |
| rectangle() | / | 元素的位置和宽高,实际是调用element_info.rectangle |
| process_id() | / | 进程号,实际是调用element_info.process_id |
| draw_outline() | colour、thickness | 给当前元素画个框 |
| click_input() | button、coords、double | 鼠标操作,实际是调用mouse模块的_perform_click_input() |
| type_keys() | / | 键盘操作,实际是调用keyboard模块的send_keys() |
dlg = app.window(class_name="WeChatMainWndForPC")
list_data = dlg.child_window(title="会话", control_type="List")
for item in list_data:
print(type(item))
element_info = item.element_info
print(type(element_info))
print("window_text:", )
print("rich_text:", element_info.rich_text)
print("name:", element_info.name)
print("visible:", element_info.visible)
print("rectangle:", element_info.rectangle)
print("class_name:", element_info.class_name)
print("enabled:", element_info.enabled)
print("parent:", element_info.parent)
print("children:", element_info.children())
print("iter_children:", element_info.iter_children())
if item.window_text() == "文件传输助手":
item.click_input()
item.type_keys("冰冷的希望")
item.type_keys("{VK_RETURN}")
print()
说明一下,每个控件元素都有对应的Wrapper,所以上面的方法也不一定都用,需要根据实际情况进行测试区分。另外,比较有用的click_input()和type_keys()这两个方法分别用于操作鼠标和键盘(输入),下面我会单独拿出来说一下
鼠标点击肯定离不开点击的位置,桌面就是一个坐标,左上角为坐标原点,往右是X轴正向,往下是Y轴正向。pywinauto提供了一个mouse模块用于鼠标操作,最核心的方法是_perform_click_input(),不过它是一个私有方法,我们调用的是基于它的封装方法,如下表
| 方法 | 参数 | |
|---|
| click() | button、coords | 单击鼠标某个键 |
| double_click() | button、coords | 双击鼠标某个键 |
| right_click() | coords | 单击鼠标右键 |
| move() | coords | 移动鼠标 |
| press() | button、coords | 按下鼠标 |
| release() | button、coords | 放开鼠标 |
| scroll() | coords、wheel_dist | 滚动鼠标滚轮 |
| wheel_click() | coords | 单击鼠标滚轮 |
参数说明:
参数button的默认值都是“left”,即鼠标左键,可选值有left、right、middle、move、wheel、x
参数coords 的默认值都是元组(0, 0),元组里的两个整数分别是X、Y轴的值
参数wheel_dist表示滚动的距离,大于0是向上滚动,小于0是向下滑动
from pywinauto import Application, mouse
app = Application(backend="uia")
app.connect(process=4352)
dlg = app.window(class_name="WeChatMainWndForPC")
list_data = dlg.child_window(title="会话", control_type="List")
for item in list_data:
if item.window_text() == "文件传输助手":
rectangle = item.element_info.rectangle
x = int((rectangle.left + rectangle.right) / 2)
y = int((rectangle.top + rectangle.bottom) / 2)
mouse.click(button='left', coords=(x, y))
time.sleep(1)
mouse.click("right", (x, y))
time.sleep(1)
mouse.move((x - 50, y))
time.sleep(1)
mouse.click(coords=(x, y))
break
键盘操作主要是按下键盘上的按键,相关方法在keyboard模块,最最主要的是send_keys()方法,第一个参数keys就是我们需要按下的按键,其他参数比如说with_spaces、with_tabs、with_newlines、turn_off_numlock、set_foreground、vk_packet,一看就知道作用,而且都是布尔值,此处不进行举例
pywinauto支持的完整的按键可以在官方文档查看,https://pywinauto.readthedocs.io/en/latest/code/pywinauto.keyboard.html
下面我列举出的是一些比较常用的按键
| 按键 | 符号 | 说明 |
|---|
| Shift | VK_SHIFT | 上档键 |
| Ctrl | VK_CONTROL、VK_LCONTROL、VK_RCONTROL | Ctrl键、左右Ctrl键 |
| Alt | VK_MENU | Alt键 |
| Windows | VK_LWIN、VK_RWIN | 左右win键 |
| Space | VK_SPACE | 空格键 |
| backspace | BACKSPACE | 退格键 |
| enter | ENTER | 回车键 |
| esc | ESC | 退出键 |
| table | VK_TAB | 制表键 |
| left、right、up、down | VK_LEFT、VK_RIGHT、VK_UP、VK_DOWN | 上下左右方向键 |
| f1~f24 | VK_F1、VK_F2…VK_F24 | f1到f24 |
| capslock | CAPSLOCK | 大写键 |
说明:
1.使用按键时需要搭配大括号,比如说按下回车键是 '{ENTER}' (是字符串)
2.在Windows平台默认是发送虚拟按键的,以VK_开头的按键,都是指虚拟按钮,如果不想使用虚拟按钮可以把VK_前缀去掉,把send_keys()的vk_packet参数改为False即可
单个按键按下抬起还不够,往往需要组合键,这时候就需要修饰符了,在大括号里可以使用down、up控制按键什么时候按下和抬起,如果后面加上数字,表示按下多少次
list_data = dlg.child_window(title="会话", control_type="List")
for item in list_data:
if item.window_text() == "文件传输助手":
item.click_input()
send_keys(" ")
send_keys("{VK_CONTROL down} a {VK_CONTROL up}")
send_keys("{BACKSPACE}")
send_keys("{. 6}")
send_keys("冰冷的希望{ENTER}")
当然,很多时候使用down、up修饰感觉不够简洁,所以pywinauto还提供了简化写法,使用+代替{VK_SHIFT},使用^代替{VK_CONTROL},使用%代替{VK_MENU}
send_keys('^a^c')
send_keys('+{INS}')
send_keys('%{F4}')
如果不想按下按钮,纯属想要输入纯字符串,那就需要取消转义了,注意修饰符和按钮的写法是不一样的
send_keys('{^}a{^}c{%}')
send_keys('{{}ENTER{}}')
近期有部分小可爱在问PC端自动化怎么去做?对这个技术比较好奇,使用python可以不可以实现PC客户端自动化测试?答案当然是可以的,所以今天在这边专门整理了一遍文章,和大家一起聊聊如何使用python做PC端自动化!
Python pywinauto PC端自动化测试核心代码封装类以下是一个基于pywinauto的自动化测试核心代码封装类的完整代码实例,其中包含多个函数实例并加上中文注释。
pywinauto是一个基于Python的Windows应用程序自动化控制库。它支持模拟鼠标和键盘操作,实现对Windows应用程序的自动化控制。通过使用pywinauto,你可以轻松实现自动登录Windows系统、自动打开和关闭应用程序、自动填写表单等操作。pywinauto作为Python自动化控制库的一员,具有简单易用、功能强大的特点。通过本文的介绍,相信你已经对pywinauto有了一定的了解和认识。在未来的学习和工作中,充分发挥pywinauto的优势,提高工作效率,实现更高级别的自动化控制。
pywinauto
(仅作为个人笔记,如有雷同,请联系删除。。)
==Pywinauto==是基于Python开发的,用于自动化测试的脚本模块,主要操作于Windows标准图形界面。它可以允许你很容易的发送鼠标、键盘动作给Windows的对话框和控件。
参考:https://www.cnblogs.com/xp1315458571/p/13892205.html
1、安装方式:
命令行安装:pip install pywinauto,简单,方便,直接。
手动安装:【解压缩后执行 python set
pywinauto的学习记录安装使用须知确定app的可访问技术启动应用程序辅助工具详细使用开启app功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入
第一次尝试这种方法记录自己学过的一些东西,后续会将一些重要的知识点慢慢记录进来,h
pywinauto是一个用于自动化Python模块,适合Windows系统的软件(GUI),可以通过Pywinauto遍历窗口(对话框)和窗口里的控件,也可以控制鼠标和键盘输入,所以它能做的事情比之前介绍的pysimplegui更多
键盘操作主要是按下键盘上的按键,相关方法在keyboard模块,最最主要的是send_keys()方法,第一个参数keys就是我们需要按下的按键,其他参数比如说with_spaces、with_tabs、with_newlines、turn_off_numlock、set_foreground、vk_packet,一看就知道作用,而且都是布尔值,此处不进行举例。鼠标点击肯定离不开点击的位置,桌面就是一个坐标,左上角为坐标原点,往右是X轴正向,往下是Y轴正向。Inspect和Spy++需要自己安装一下。
https://www.likecs.com/default/index/show?id=99439
pywinauto是一个用纯Python编写的GUI自动化库,并为Windows GUI精心开发。最简单的是,它允许您将鼠标和键盘操作发送到Windows和Linux上的对话框和控件,而到目前为止,仅Windows才支持更复杂的基于文本的操作(正在开发Linux AT-SPI支持)。
pywinauto是一组用于自动化Microsoft Windows GUI的python模块。 最简单的是,它允许您将
pywinauto是一个用于自动化Python模块,适合Windows系统的软件(GUI),可以通过Pywinauto遍历窗口(对话框)和窗口里的控件,也可以控制鼠标和键盘输入,所以它能做的事情比之前介绍的pysimplegui更多一般使用pip安装就行了官网文档:https://pywinauto.readthedocs.io/en/latest/我们要控制软件的第一件事就是启动一个Windows软件,每一个软件(进程)都是一个Application对象。
pywinauto是一个用于自动化Python模块,适合Windows系统的软件(GUI),可以通过Pywinauto遍历窗口(对话框)和窗口里的控件,也可以控制鼠标和键盘输入,所以它能做的事情比之前介绍的更多一般使用pip安装就行了官网文档:https://pywinauto.readthedocs.io/en/latest/我们要控制软件的第一件事就是启动一个Windows软件,每一个软件(进程)都是一个Application对象。
UI Automation是微软从Windows Vista开始引入的核心技术,旨在为所有UI元素提供一致的编程接口,无论这些元素是由何种技术(如Win32、WPF、UWP等)实现的。这为自动化测试提供了更广泛的支持,尤其是在处理现代Windows应用(尤其是使用WPF和UWP技术构建的应用)时更为有效。使用UI Automation后端,开发者可以更容易地定位和操作UI元素,如获取元素的属性、模拟鼠标和键盘操作、监听UI事件等,这对于创建复杂的自动化测试场景尤其有用。
一旦你安装了pywinauto - 你怎么样?第一个必要的事情是确定哪种可访问性技术(pywinauto的backend)可以用于您的应用程序。) - 现在的默认backend注意: Chrome在启动之前需要cmd标志。由于comtypes Python库限制,不支持自定义属性和控件。到目前为止,Linux上的AT SPI和Apple Accessibility API都是长期计划。