window GUI 自动化
window GUI (Graphical User Interface) 图形用户界面
自动化 通过自动化脚本代码 实现对GUI程序 的功能进行测试 或者 任务脚本编写。
基于python 自动化 (windows platform)
-
安装对应的包 terminal 输入command pywinauto 0.6.8 (版本选择)
pip install pywinauto -i https://pypi.tuna.tsinghua.edu.cn/simple -
terminal 查看版本信息
pip list | findstr pywinauto -
结果
windowauto 辅助工具
github 上相关window inspect tools
查看方式
UI Automation 方式下 可以看到更多的控件元素信息
insights 工具
所有工具大同小异 都是辅助工具内容 对于相关的内容进行处理操作 主要关注点
title 、class_name、 handle_id、 process_id
灵活使用 pywinauto 中的窗口打印属性知识
from pywinauto import Application
app = Application(backend="uia").start("calc.exe")
dlg = Desktop(backend="uia")["计算器"]
dlg.type_keys("2*3=")
dlg.print_control_identifiers(filename="calculator.ini")
导出的calculator.ini
- 编码格式 window GBK
- 导出形式为树形结构内容
Control Identifiers:
Dialog - '计算器' (L6, T61, R342, B602)
['Dialog', '计算器', '计算器Dialog', 'Dialog0', 'Dialog1', '计算器0', '计算器1', '计算器Dialog0', '计算器Dialog1']
child_window(title="计算器", control_type="Window")
|
| Dialog - '计算器' (L14, T62, R334, B94)
| ['Dialog2', '计算器2', '计算器Dialog2']
| child_window(title="计算器", auto_id="TitleBar", control_type="Window")
| |
| | Menu - '系统' (L0, T0, R0, B0)
| | ['系统', 'Menu', '系统Menu', '系统0', '系统1']
| | child_window(title="系统", auto_id="SystemMenuBar", control_type="MenuBar")
| | |
| | | MenuItem - '系统' (L0, T0, R0, B0)
| | | ['MenuItem', '系统2', '系统MenuItem']
| | | child_window(title="系统", control_type="MenuItem")
| |
| | Button - '最小化 计算器' (L196, T62, R242, B94)
| | ['Button', '最小化 计算器', '最小化 计算器Button', 'Button0', 'Button1']
| | child_window(title="最小化 计算器", auto_id="Minimize", control_type="Button")
| |
| | Button - '使 计算器 最大化' (L242, T62, R288, B94)
| | ['Button2', '使 计算器 最大化', '使 计算器 最大化Button']
| | child_window(title="使 计算器 最大化", auto_id="Maximize", control_type="Button")
| |
| | Button - '关闭 计算器' (L288, T62, R334, B94)
| | ['Button3', '关闭 计算器Button', '关闭 计算器']
| | child_window(title="关闭 计算器", auto_id="Close", control_type="Button")
|
| Dialog - '计算器' (L14, T62, R334, B594)
| ['Dialog3', '计算器3', '计算器Dialog3']
| child_window(title="计算器", control_type="Window")
| |
| | Static - '计算器' (L26, T70, R62, B86)
| | ['Static', '计算器Static', '计算器4', 'Static0', 'Static1']
| | child_window(title="计算器", auto_id="AppName", control_type="Text")
| |
| | Button - '打开导航' (L14, T94, R54, B134)
| | ['Button4', '打开导航Button', '打开导航']
| | child_window(title="打开导航", auto_id="TogglePaneButton", control_type="Button")
| |
| | Static - '标准' (L66, T100, R106, B127)
| | ['Static2', '标准', '标准Static']
| | child_window(title="标准", auto_id="Header", control_type="Text")
| |
| | GroupBox - '' (L14, T94, R334, B590)
| | ['GroupBox', '计算器GroupBox', 'GroupBox0', 'GroupBox1']
| | |
| | | Static - '显示为 0' (L14, T155, R334, B232)
| | | ['Static3', '显示为 0', '显示为 0Static']
| | | child_window(title="显示为 0", auto_id="CalculatorResults", control_type="Text")
| | |
| | | Static - '表达式为 ' (L0, T0, R0, B0)
| | | ['Static4', '表达式为 Static', '表达式为 ']
| | | child_window(title="表达式为 ", auto_id="CalculatorExpression", control_type="Text")
| | |
| | | Button - '打开历史记录浮出控件' (L294, T94, R334, B134)
| | | ['Button5', '打开历史记录浮出控件', '打开历史记录浮出控件Button']
| | | child_window(title="打开历史记录浮出控件", auto_id="HistoryButton", control_type="Button")
| | |
| | | GroupBox - '内存控件' (L18, T233, R330, B265)
| | | ['GroupBox2', '内存控件GroupBox', '内存控件']
| | | child_window(title="内存控件", auto_id="MemoryPanel", control_type="Group")
| | | |
| | | | Button - '清除所有内存' (L18, T233, R68, B265)
| | | | ['Button6', '清除所有内存Button', '清除所有内存']
| | | | child_window(title="清除所有内存", auto_id="ClearMemoryButton", control_type="Button")
| | | |
| | | | Button - '内存重新调用' (L70, T233, R120, B265)
| | | | ['Button7', '内存重新调用', '内存重新调用Button']
| | | | child_window(title="内存重新调用", auto_id="MemRecall", control_type="Button")
| | | |
| | | | Button - '内存添加' (L122, T233, R172, B265)
| | | | ['Button8', '内存添加Button', '内存添加']
| | | | child_window(title="内存添加", auto_id="MemPlus", control_type="Button")
| | | |
| | | | Button - '内存减少' (L174, T233, R224, B265)
| | | | ['Button9', '内存减少', '内存减少Button']
| | | | child_window(title="内存减少", auto_id="MemMinus", control_type="Button")
| | | |
| | | | Button - '内存存储' (L226, T233, R277, B265)
| | | | ['Button10', '内存存储Button', '内存存储']
| | | | child_window(title="内存存储", auto_id="memButton", control_type="Button")
| | | |
| | | | Button - '打开内存浮出控件' (L280, T233, R330, B265)
| | | | ['Button11', '打开内存浮出控件Button', '打开内存浮出控件']
| | | | child_window(title="打开内存浮出控件", auto_id="MemoryButton", control_type="Button")
| | |
| | | GroupBox - '标准函数' (L18, T267, R330, B319)
| | | ['GroupBox3', '标准函数GroupBox', '标准函数']
| | | child_window(title="标准函数", auto_id="StandardFunctions", control_type="Group")
| | | |
| | | | Button - '百分比' (L18, T267, R94, B319)
| | | | ['Button12', '百分比Button', '百分比']
| | | | child_window(title="百分比", auto_id="percentButton", control_type="Button")
| | | |
| | | | Button - '平方根' (L96, T267, R172, B319)
| | | | ['Button13', '平方根Button', '平方根']
| | | | child_window(title="平方根", auto_id="squareRootButton", control_type="Button")
| | | |
| | | | Button - '平方' (L175, T267, R251, B319)
| | | | ['Button14', '平方Button', '平方']
| | | | child_window(title="平方", auto_id="xpower2Button", control_type="Button")
| | | |
| | | | Button - '倒数' (L253, T267, R329, B319)
| | | | ['Button15', '倒数', '倒数Button']
| | | | child_window(title="倒数", auto_id="invertButton", control_type="Button")
| | |
| | | GroupBox - '标准运算符' (L253, T321, R329, B589)
| | | ['GroupBox4', '标准运算符GroupBox', '标准运算符']
| | | child_window(title="标准运算符", auto_id="StandardOperators", control_type="Group")
| | | |
| | | | Button - '除以' (L253, T321, R329, B373)
| | | | ['Button16', '除以', '除以Button']
| | | | child_window(title="除以", auto_id="divideButton", control_type="Button")
| | | |
| | | | Button - '乘以' (L253, T375, R329, B427)
| | | | ['Button17', '乘以Button', '乘以']
| | | | child_window(title="乘以", auto_id="multiplyButton", control_type="Button")
| | | |
| | | | Button - '减' (L253, T429, R329, B481)
| | | | ['Button18', '减', '减Button']
| | | | child_window(title="减", auto_id="minusButton", control_type="Button")
| | | |
| | | | Button - '加' (L253, T483, R329, B535)
| | | | ['Button19', '加', '加Button']
| | | | child_window(title="加", auto_id="plusButton", control_type="Button")
| | | |
| | | | Button - '等于' (L253, T537, R329, B589)
| | | | ['Button20', '等于Button', '等于']
| | | | child_window(title="等于", auto_id="equalButton", control_type="Button")
| | |
| | | GroupBox - '显示控件' (L18, T321, R251, B373)
| | | ['GroupBox5', '显示控件GroupBox', '显示控件']
| | | child_window(title="显示控件", auto_id="DisplayControls", control_type="Group")
| | | |
| | | | Button - '清除条目' (L18, T321, R94, B373)
| | | | ['Button21', '清除条目', '清除条目Button']
| | | | child_window(title="清除条目", auto_id="clearEntryButton", control_type="Button")
| | | |
| | | | Button - '清除' (L96, T321, R172, B373)
| | | | ['Button22', '清除Button', '清除']
| | | | child_window(title="清除", auto_id="clearButton", control_type="Button")
| | | |
| | | | Button - 'Backspace' (L175, T321, R251, B373)
| | | | ['Button23', 'BackspaceButton', 'Backspace']
| | | | child_window(title="Backspace", auto_id="backSpaceButton", control_type="Button")
| | |
| | | GroupBox - '数字键盘' (L18, T375, R251, B589)
| | | ['数字键盘GroupBox', 'GroupBox6', '数字键盘']
| | | child_window(title="数字键盘", auto_id="NumberPad", control_type="Group")
| | | |
| | | | Button - '零' (L96, T537, R172, B589)
| | | | ['Button24', '零', '零Button']
| | | | child_window(title="零", auto_id="num0Button", control_type="Button")
| | | |
| | | | Button - '一' (L18, T483, R94, B535)
| | | | ['Button25', '一Button', '一']
| | | | child_window(title="一", auto_id="num1Button", control_type="Button")
| | | |
| | | | Button - '二' (L96, T483, R172, B535)
| | | | ['Button26', '二', '二Button']
| | | | child_window(title="二", auto_id="num2Button", control_type="Button")
| | | |
| | | | Button - '三' (L175, T483, R251, B535)
| | | | ['Button27', '三', '三Button']
| | | | child_window(title="三", auto_id="num3Button", control_type="Button")
| | | |
| | | | Button - '四' (L18, T429, R94, B481)
| | | | ['Button28', '四Button', '四']
| | | | child_window(title="四", auto_id="num4Button", control_type="Button")
| | | |
| | | | Button - '五' (L96, T429, R172, B481)
| | | | ['Button29', '五', '五Button']
| | | | child_window(title="五", auto_id="num5Button", control_type="Button")
| | | |
| | | | Button - '六' (L175, T429, R251, B481)
| | | | ['Button30', '六', '六Button']
| | | | child_window(title="六", auto_id="num6Button", control_type="Button")
| | | |
| | | | Button - '七' (L18, T375, R94, B427)
| | | | ['Button31', '七Button', '七']
| | | | child_window(title="七", auto_id="num7Button", control_type="Button")
| | | |
| | | | Button - '八' (L96, T375, R172, B427)
| | | | ['Button32', '八Button', '八']
| | | | child_window(title="八", auto_id="num8Button", control_type="Button")
| | | |
| | | | Button - '九' (L175, T375, R251, B427)
| | | | ['Button33', '九Button', '九']
| | | | child_window(title="九", auto_id="num9Button", control_type="Button")
| | | |
| | | | Button - '小数分隔符' (L175, T537, R251, B589)
| | | | ['Button34', '小数分隔符', '小数分隔符Button']
| | | | child_window(title="小数分隔符", auto_id="decimalSeparatorButton", control_type="Button")
| | |
| | | Button - '正,负' (L18, T537, R94, B589)
| | | ['Button35', '正,负Button', '正,负']
| | | child_window(title="正,负", auto_id="negateButton", control_type="Button")
|
| Pane - '' (L14, T94, R334, B594)
| ['Pane', '计算器Pane']
基础线性代码
实现一个notepad(记事本)操作的内容 主要包括
- 打开替换窗口 关闭
- 编辑内容并另存为 桌面文件(修改路径)
import time
from pywinauto.application import Application
app = Application()
# 实例化一个Application()
app.start("Notepad.exe")
# main_window
main_window = app["无标题 - 记事本"]
print(main_window.get_properties())
diaologs = app.windows()
print(diaologs)
main_window.draw_outline()
# main_window.maximize()
main_window.print_control_identifiers(filename="note.ini")
main_window.menu_select("编辑(E)->替换(R)")
# print(app.top_window().get_properties())
app["替换"].print_control_identifiers(filename="replace.ini")
time.sleep(2)
app["替换"]["取消"].click()
time.sleep(2)
# app.Replace.Cancel.click()
main_window.Edit.type_keys("Hi from python interactive prompt %s " % str(dir()),with_newlines=True,with_spaces=True)
time.sleep(2)
app["记事本"].print_control_identifiers(filename="note_exit.ini")
main_window.menu_select("文件(F)->保存(S)")
time.sleep(2)
app["另存为"].print_control_identifiers(filename="note_save.ini")
diaologs = app.windows()
print(diaologs)
app["另存为"]["文件名:Edit"].type_keys(r"C:\Users\PC\Desktop\1.txt")
# 修改路径地址
time.sleep(2)
app["另存为"]["保存(S)"].click()
# app.Notepad.DontSave.click()
if app["确认另存为"]["是(Y)"]:
app["确认另存为"]["是(Y)"].click()
注意事项
- 中文控件只能通过 app[control1][control2]方式访问
- 路径地址的变换
- 确认电脑有记事本软件 一般在 system32 下面的 notepad.exe ,同样通过 cmd 中 notepad 可以唤醒(路径配置在环境变量中)
结果显示