一. pywinauto知识点总结

官方英文版文档网址:https://pywinauto.readthedocs.io/en/latest/index.html

1.1pywinauto的安装与配置

<1>相关库文件的下载地址

pywin32下载地址:https://sourceforge.net/projects/pywin32/files/pywin32/Build%20220/

comtypes下载地址:https://github.com/enthought/comtypes/releases

six下载地址:https://pypi.org/project/six/

Pillow下载地址:https://pypi.org/project/Pillow/2.7.0/

<2>安装相关库

法1.直接通过命令行安装

(安装pywin32,直接安装比在官网下载速度慢,但是如果大家python3和python2同时安装了,那么直接下载再安装,会报错:找不到符合要求的python版本)

安装pywin32,E:\soft\python3.6\Scripts>pip3 install pywin32

法2.通过setup.py文件安装(安装包放中文路径下,可能安装出错)

如安装comtypes, (如果是unpack的下载包,)安装方法,进入下载的安装包路径,用命令行python3 setup.py install安装

1.2 pywinauto的基本操作

<1>一个小练习快速上手pywinauto基本操作

#_*_coding=utf-8_*_

importpywinautofrom pywinauto.mouse import *

from pywinauto.keyboard import *

importtime#1.运行记事本程序

app = pywinauto.Application().start('notepad.exe')#2.窗体选择

title_notepad = u'无标题-记事本'

#3.选择一个菜单项

app[title_notepad].menu_select('帮助->关于记事本')

time.sleep(3)#4.点击新弹出窗体的确定按钮

out_note=u'关于记事本'button_name_ok='确定'app[out_note][button_name_ok].click()#5.查看一个窗体含有的控件,子窗体,菜单

print(app[title_notepad].print_control_identifiers())#-------------------无标题记事本的含有的控件,子窗体,菜单-----------------#Control Identifiers:#

#Notepad - '无标题 - 记事本' (L8, T439, R892, B815)#['无标题 - 记事本Notepad', 'Notepad', '无标题 - 记事本']#child_window(title="无标题 - 记事本", class_name="Notepad")#|#| Edit - '' (L16, T490, R884, B807)#| ['无标题 - 记事本Edit', 'Edit']#| child_window(class_name="Edit")#|#| StatusBar - '' (L16, T785, R884, B807)#| ['StatusBar', '无标题 - 记事本StatusBar', 'StatusBar 第 1 行,第 1 列']#| child_window(class_name="msctls_statusbar32")#None

#6.在记事本中输入一些文本#[tips-> ctrl+点击鼠标左键快速查看被调用函数]

app.title_notepad.Edit.type_keys('pywinauto works!\n',with_spaces=True,with_newlines=True)

app.title_notepad.Edit.type_keys('hello word !\n',with_spaces=True,with_newlines=True)#7.选择编辑菜单->编辑时间/日期#app[title_notepad].menu_select('编辑->时间/日期(&d)')#8.连接已运行程序#如连接微信 借助spy++找到运行程序的handle

app1=pywinauto.Application(backend='uia').connect(handle=0x00320830)#9.查看运行窗口窗体名称

print(app1.window())print(app1['Dialog'].print_control_identifiers())#Dialog - '微信' (L968, T269, R1678, B903)#['微信Dialog', 'Dialog', '微信']#child_window(title="微信", control_type="Window")#|#| Pane - 'ChatContactMenu' (L-10000, T-10000, R-9999, B-9999)#| ['ChatContactMenu', 'ChatContactMenuPane', 'Pane', 'Pane0', 'Pane1']#| child_window(title="ChatContactMenu", control_type="Pane")#| |#| | Pane - '' (L-10019, T-10019, R-9980, B-9980)#| | ['', 'Pane2', '0', '1']#|#| Pane - '' (L948, T249, R1698, B923)#| ['2', 'Pane3']#None#10.通过路径去打开一个已有程序#11.鼠标控制

x=0

y=0for i in range(20):

step_x= i*8step_y= i*5move(coords=(step_x,step_y ))

time.sleep(1)#12.键盘控制#键盘对应的ascii http://www.baike.com/wiki/ASCII#发送键盘指令,打开命令行,输入一条命令for /l %i in (1,1,100) do tree

SendKeys('{VK_LWIN}')

SendKeys('cmd')

SendKeys('{VK_RETURN}')

time.sleep(3)

SendKeys('for /L +5i in +9 1,1,100+0 do tree {VK_RETURN}',with_spaces=True)

View Code

1.3 pywinauto的使用

1.3.1 pywinauto支持的windows应用

<1>Win32 API (backend="win32")(程序默认) :支持MFC、VB6、VCL、以及一些使用winforms的老应用<2>MS UI Automation (backend="uia"):支持WinForms, WPF, Store apps, Qt5, browsers<3>不支持Java AWT/Swing, GTK+, Tkinter.1.3.2 判断程序的backend法1:使用工具spy++如果是GUI的程序,用spy++这个微软的小工具来看,从类名前缀能看出是什么编写的程序。a、afx__开头的:mfc写的;b、t_开头的:一般是delphi,少部分是c++builder;比如主窗体一般是tMainForm;c、thunder_开头的:一般是VB6写的;d、windows__开发头的,一般都是.net写的;e、awt__或者swing__开头的,一般都是java写的;f、其他的直接以win32api gui控件开头的,一般都是c++或者VC++写的。法2:使用工具inspect点击inspect左上角的下拉列表,切换到“UI Automation”,然后鼠标点一下你需要测试的程序窗体,inspect就会显示相关信息。inspect中显示了程序的有关信息,说明backend为uia,inspect中显示拒绝访问,说明程序的backend应该是win321.3.3 自动化入口这里主要是限制自动化控制进程的范围。如一个程序有多个实例,自动化控制一个实例,而保证其他实例(进程)不受影响。主要有两种对象可以建立这种入口点Application() ,Desktop()。Application的作用范围是一个进程,如一般的桌面应用程序都为此类。Desktop的作用范围可以跨进程。主要用于像win10的计算器这样包含多个进程的程序。这种目前比较少见。

<1>通过对象Application()运行一个现有的程序app = Application().start(r"c:\path\to\your\application -a -n -y --arguments")

from pywinauto.application importApplication

app= Application(backend="uia").start('notepad.exe')#describe the window inside Notepad.exe process,注意如果窗体名称是中文,不能直接app.窗体名选择窗体,如下面不能直接使用app.untitled_notepad ,这样会报错

untitled_notepad = u'无标题-记事本'dlg_spec=app[untitled_notepad]#wait till the window is really open

actionable_dlg = dlg_spec.wait('visible')

通过Application()对象运行记事本程序

<2>通过对象Application()连接到一个已经运行的程序

#注意用connect方法关联应用程序时,应用程序必须是处于运行状态,可以通过程序的path,process,handle参数或组合参数连接程序

from pywinauto.application importApplication

app=Application()#1.通过应用程序路径#app.connect(path = r"C:\Windows\System32\notepad.exe")#2.通过进程pid#app.connect(process = 2341)#3.通过窗口句柄#app.connect(handle = 0x010f0c)#4.通过组合参数#app = Application().connect(title_re=".*Notepad", class_name="Notepad")

通过connect连接到一个已运行程序

<3>通过对象Desktop()运行一个程序

from subprocess importPopenfrom pywinauto importDesktop

Popen('calc.exe', shell=True)

dlg= Desktop(backend="uia").Calculator

dlg.wait('visible')

通过Desktop()对象运行计算器

1.3.4  确定想操作的窗体

<1> 确定想操作的窗体

#创建一个 WindowSpecification实例

app=pywinauto.Application(backend='uia').start('notepad.exe')#1.通过窗体名确定窗体

window_title=['无标题-记事本']print(app[window_title])#

dlg_spec = app.window(title='无标题-记事本')print(dlg_spec)#2.wrapper_object()方法返回实际存在的窗口/控件,或者引发ElementNotFoundError.

app[window_title].wrapper_object()#uiawrapper.UIAWrapper - '无标题 - 记事本', Dialog#3. 通过多层次的描述指定一个窗口,如(a),或使用组合参数指定一个窗体如(b),下面两条语句确定的是同一个窗体

(a)app.window(title_re='.* - 记事本$').window(class_name='edit')

(b)app.window(title_re='.* - 记事本$',class_name='edit')#4.pywinauto.findwindows.find_elements()返回所有的已运行程序的win32_element_info.HwndElementInfo

View Code

注意Unicode编码的字符和特殊符号使用时以类似字典的方式进行访问,比如中文字符

app['无标题-记事本']#is the same as

app.window(best_match='无标题-记事本')

View Code

dlg = app.top_window()该方法返回应用程序最顶层的窗口

importtime#app = application.Application().start("Notepad.exe")#winTitle = u'无标题-记事本'#app[winTitle].draw_outline()#time.sleep(3)#app[winTitle].menu_select('编辑->替换(&R)...')#childWindow='替换'#cancel_botton='取消'#app[childWindow].print_control_identifiers()#time.sleep(3)#app[childWindow][cancel_botton].click()#app[winTitle].Edit.type_keys("Hi from Python interactive prompt %s" % str(dir()), with_spaces = True)#app[winTitle].menu_select('文件->退出')#childWindow1='记事本'#app[childWindow1].Button2.click()#------------------------------------------------------------

app = Application().start('notepad.exe')

time.sleep(1)

app['无标题 - 记事本'].menu_select("编辑(&E) -> 替换(&R)..")

time.sleep(1)

app['替换'].取消.click()#没有with_spaces 参数空格将不会被键入。请参阅SendKeys的这个方法的文档,因为它是SendKeys周围的薄包装。

app['无标题 - 记事本'].Edit.type_keys("Hi from Python interactive prompt %s" % str(dir()), with_spaces =True)

app['无标题 - 记事本'].menu_select('文件(&F) -> 退出(&X)')#在这时候不清楚“不保存”的按钮名就对app['记事本'] 使用print_control_identifiers()

app['记事本'].Button2.click()

一个小练习

1.3.5 在窗体中指定控件

对于常见的窗口程序,需要操作的控件有输入框(Edit)、按钮(Button)、复选框(CheckBox)、单选框(RadioButton)、下拉列表(ComboBox)。有很多方法可以指定这些控件,最简单的是:

app.dlg.control

app['dlg']['control']

对于非英文的环境,需要传递unicode字符,则有

app[u'your dlg title'][u'your control title']

代码根据如下内容为每个控件建立多个标识符:

a.标题   b.相关类    c.标题+相关类

如果控件的标题文本为空(去除非字符字符后),这些标题文件就不能被使用。因而,我们会去寻找最接近文本标题的控件,并附加其相关类,所以此时列表为:

a.相关类         b.最接近的文本+相关类

一旦对话框中所以控件创建了一组标识符,我们就能区别他们。

方法 WindowsSpecification.print_control_identifiers()返回窗体内所以控件及其标识符列表,注意,此方法打印的标识符已通过使标识符唯一的进程运行。如果窗体内有两个编辑框,他们都会在其中列出。实际中,第一个编辑框被称为“Edit”, “Edit0”, “Edit1”,第二个应该被称为‘Edit2’

1.3.6 如何在非英文环境中使用pywinauto

因为Python不支持代码中的Unicode标识符,所以此时不能使用属性访问方式引用控件,您将不得不使用类字典的方式进行访问,或者使用Windows()方法进行显式调用。

将原调用方式app.dialog_ident.control_ident.click()改为app['dialog_ident']['control_ident'].click(),或使用app.window(title_re="NonAsciiCharacters").window(title="MoreNonAsciiCharacters").click()

1.3.7 如何处理不按照预期进行响应的控件(例如自主绘制的控件)

一些控件不按照预期的方式响应事件。例如,如果你查看任何HLP文件,然后转到索引选项卡(单击‘搜索’按钮),你将会看见一个列表框。运行 Spy++ 或者 inspector 工具查看控件,你会发现它确实是一个列表框,但它是自主绘制的列表框,这意味着开发人员已经告诉windows,他们覆盖了项目的显示方式。在这种情况下,这样的一些字符无法被检索。

如果存在不按照预期进行响应的控件,那么,这将会带来什么问题呢?

app.HelpTopics.ListBox.texts() # 1

app.HelpTopics.ListBox.select("ItemInList") # 2

此时运行语句1,将返回空字符串列表,这意味着pywinauto无法获取列表框中的字符串。

此时运行语句2,将返回IndexError。

下面的解决方法将对该类控件起作用

app.HelpTopics.ListBox.select(1),这将选择ListBox中的第二项,因为它不是通过字符串查找方法操作控件,因此它能工作正常。

不幸的是,这种方法不是任何时候都有效。开发人员可以使控件不响应标准事件,如SELECT,在这种情况下,选择列表框中的项的唯一方法是使用TypeKeys的键盘仿真

此时选择列表框第三个选项的方法为:

app.Helptopics.ListBox1.type_keys("{HOME}{DOWN 2}{ENTER}")

{HOME} 确保第一个选项被突出显示

{DOWN 2} 然后将高亮点向下移动两项

{ENTER} 选择突出显示的项目

如果你的应用程序广泛的使用类似的控件类型,那么你可以通过ListBox派生一个新类来简化使用。

1.3.8 等待长时间操作的方法

GUI应用程序行为通常是不稳定的,你的脚本需要等待直到出现新窗口或现有窗口被关闭/隐藏。Pywinauto可以隐式地等待对话框初始化(默认超时参数 timeout)。有几种方法可以使你的代码更容易更可靠。

<1>法1  wait_cpu_usage_lower (new in pywinauto 0.5.2, renamed in 0.6.0)

这种方法对于允许在另一个线程中进行延迟初始化的多线程接口非常有用,由于GUI是响应性的,并且他所有的控件已经存在并可用。所以等待一个窗口的存在/状态是无用的,在这种情况下,整个过程的CPU使用量指示任务计算尚未结束。

使用实例:app.wait_cpu_usage_lower(threshold=5) # wait until CPU usage is lower than 5%。

<2>法2WindowSpecification方法,所有控件都可以使用

wait

wait_not

一个WindowSpecification对象不一定与现有的窗口/控件有关。这只是一个描述,即搜索窗口的几个条件。wait方法(如果没有引发任何异常)可以保证目标控件存在,甚至可见,启用或活动。

<3> 法三:timings功能模块

对任何代码都有用的低级方法

wait_until

wait_until_passes

装饰器pywinauto.timings.always_wait_until()和pywinauto.timings.always_wait_until_passes()也可以被每个函数调用,进行时间控制。

#call ensure_text_changed(ctrl) every 2 sec until it's passed or timeout (4 sec) is expired

@always_wait_until_passes(4, 2)defensure_text_changed(ctrl):if previous_text ==ctrl.window_text():raise ValueError('The ctrl text remains the same while change is expected')

View Code

二 .  pywinauto控件的常用函数

下面的函数适用于所有控件

capture_as_image

click

click_input

close

close_click

debug_message

double_click

double_click_input

drag_mouse

draw_outline

get_focus

get_show_state

maximize

menu_select

minimize

move_mouse

move_window

notify_menu_select

notify_parent

press_mouse

press_mouse_input

release_mouse

release_mouse_input

restore

right_click

right_click_input

send_message

send_message_timeout

set_focus

set_window_text

type_keys

Children

Class

ClientRect

ClientRects

ContextHelpID

ControlID

ExStyle

Font

Fonts

FriendlyClassName

GetProperties

HasExStyle

HasStyle

IsChild

IsDialog

IsEnabled

IsUnicode

IsVisible

Menu

MenuItem

MenuItems

Owner

Parent

PopupWindow

ProcessID

Rectangle

Style

Texts

TopLevelParent

UserData

VerifyActionable

VerifyEnabled

VerifyVisible

WindowText

View Code

按钮,复选框,单选按钮,分组框

ButtonWrapper.Check

ButtonWrapper.GetCheckState

ButtonWrapper.SetCheckIndeterminate

ButtonWrapper.UnCheck

View Code

组合框

ComboBoxWrapper.DroppedRect

ComboBoxWrapper.ItemCount

ComboBoxWrapper.ItemData

ComboBoxWrapper.ItemTexts

ComboBoxWrapper.Select

ComboBoxWrapper.SelectedIndex

View Code

对话框

DialogWrapper.ClientAreaRect

DialogWrapper.RunTests

DialogWrapper.WriteToXML

View Code

编辑框

EditWrapper.GetLine

EditWrapper.LineCount

EditWrapper.LineLength

EditWrapper.Select

EditWrapper.SelectionIndices

EditWrapper.SetEditText

EditWrapper.set_window_text

EditWrapper.TextBlock

View Code

HeaderWrapper.GetColumnRectangle

HeaderWrapper.GetColumnText

HeaderWrapper.ItemCount

View Code

列表框

ListBoxWrapper.GetItemFocus

ListBoxWrapper.ItemCount

ListBoxWrapper.ItemData

ListBoxWrapper.ItemTexts

ListBoxWrapper.Select

ListBoxWrapper.SelectedIndices

ListBoxWrapper.SetItemFocus

View Code

列表视图

ListViewWrapper.ColumnCount

ListViewWrapper.Columns

ListViewWrapper.ColumnWidths

ListViewWrapper.GetColumn

ListViewWrapper.GetHeaderControl

ListViewWrapper.GetItem

ListViewWrapper.GetSelectedCount

ListViewWrapper.IsChecked

ListViewWrapper.IsFocused

ListViewWrapper.IsSelected

ListViewWrapper.ItemCount

ListViewWrapper.Items

ListViewWrapper.Select

ListViewWrapper.Deselect

ListViewWrapper.UnCheck

View Code

状态栏

StatusBarWrapper.BorderWidths

StatusBarWrapper.GetPartRect

StatusBarWrapper.GetPartText

StatusBarWrapper.PartCount

StatusBarWrapper.PartRightEdges

View Code

选项卡控件

TabControlWrapper.GetSelectedTab

TabControlWrapper.GetTabRect

TabControlWrapper.GetTabState

TabControlWrapper.GetTabText

TabControlWrapper.RowCount

TabControlWrapper.Select

TabControlWrapper.TabCount

TabControlWrapper.TabStates

View Code

工具栏

ToolbarWrapper.Button

ToolbarWrapper.ButtonCount

ToolbarWrapper.GetButton

ToolbarWrapper.GetButtonRect

ToolbarWrapper.GetToolTipsControl

ToolbarWrapper.PressButton

View Code

ToolbarButton (returned by Button())

ToolbarButton.Rectangle

ToolbarButton.Style

ToolbarButton.click_input

ToolbarButton.Click

ToolbarButton.IsCheckable

ToolbarButton.IsChecked

ToolbarButton.IsEnabled

ToolbarButton.IsPressable

ToolbarButton.IsPressed

ToolbarButton.State

View Code

三 . pywinauto.py与automation.py的搭配使用

当UI界面的控件、控件的值或状态无法用pywinauto进行识别时,可以用开源库automation识别

运行待测程序,并准备好待测界面,运行cmd,cd到automation工具的目录,输入python3 automation.py -t3回车,然后3秒内切换到待测界面,cmd窗口中就显示了当前待测窗口中的控件信息,依据控件信息便能方便的找到相应控件,进行相应操作

>>>>>>待续

python windows程序自动化_Windows GUI程序自动化之pywinauto相关推荐

  1. python gui 自动化_python GUI测试自动化

    #! /usr/bin/env python #coding=GB18030 ''' GUI测试自动化 语言:python 模块:pywinauto 环境:windows7中文.python-2.6_ ...

  2. putty和Xming server 结合完美在windows下显示linux GUI程序

    因为linux的x是c/s架构,顾直接putty访问执行不了图形程序,因为windows下缺少x server.当然可以用收费的xmanger的xshell来做,但是免费的Xming server也很 ...

  3. python windows窗口开发_Windows 平台做 Python 开发的最佳组合

    选自机器之心 作者:Jon Fincher 在 Windows 上怎样做 Python 开发?是像大神那样使用纯文本编辑器,还是用更加完善的 IDE?到底是用自带的命令行工具,还是需要装新的 Term ...

  4. pythongui程序,python第一个GUI程序

    第一个GUI程序 截止目前,我们的python基本语法就已经讲完了,但是python的应用确实无比之广,不同的应用领域需要学习不同的Python库,比如爬虫的urllib模块,科学计算numpy模块, ...

  5. python编程快速上手 让繁琐工作自动化 豆瓣_2019年,这些豆瓣评分9.0以上的8本程序员好书你都知道吗?...

    豆瓣这些9.0以上的高评分程序员好书你都知道有哪些吗?小编去豆瓣看了一下,推荐这8本最适用的程序员好书给你. 1.UNIX环境高级编程(第3版)(豆瓣评分9.6)UNIX编程圣经 与Linux相结合的 ...

  6. python 自动化微信小程序_干货 | 微信小程序自动化测试最佳实践(附 Python 源码)...

    原标题:干货 | 微信小程序自动化测试最佳实践(附 Python 源码) 本文为霍格沃兹测试学院测试大咖公开课<微信小程序自动化测试>图文整理精华版. 随着微信小程序的功能和生态日益完善, ...

  7. Python实现简单自动升级exe程序版本并自动运行,适合Python自动化运维。

    Python自动升级exe程序版本并自动运行,Python自动更新脚本,适合Python自动化运维. 一.此教程是使用bat脚本+NFS实现自动更新.(也可以使用FTP或者使用html实现自动更新) ...

  8. 几行命令实现日常任务的自动化执行,包括解析html、扫描二维码、语音转换、pdf编辑、程序员问题搜索、自动化手机、监控cpu、上传机器人、视频水印等

    几行命令实现日常任务的自动化执行,包括解析html.扫描二维码.语音转换.pdf编辑.程序员问题搜索.自动化手机.监控cpu.上传机器人.视频水印等. 01.解析和提取 HTML 02.二维码扫描仪 ...

  9. 自学Python+windows API自动化操作桌面功能

    目    录 一.windows API 1.官方文档 2.pywin32 3.win32api 4.win32gui 5.win32clipboard 二.windows API的另一种键鼠输入 1 ...

最新文章

  1. 高精度模板 c++/类封装
  2. 阿里云产品搭建web应用梳理
  3. python中以下关于列表描述错误的_10. 以下关于列表操作的描述,错误的是:_学小易找答案...
  4. 大白话Pyramid Vision Transformer
  5. csv python 图片 存_Python读取CSV文件并存储到MySQL
  6. 小米投资偏爱智能与芯片 雷军:有3家科创板上市
  7. html 监听后端变化_SpringBoot2.0整合WebSocket,实现后端数据实时推送!
  8. 英语学习app源码_无纸化英语学习APP击败%89英语学习者
  9. HDU 1286 找新朋友 (欧拉函数)
  10. 【电脑帮助】解决Wind10系统桌面没有“我的电脑”图标的问题
  11. vim配置之目录结构
  12. hihoCoder - 1079 - 离散化 (线段树 + 离散化)
  13. STM32 USB Host 鼠标和键盘驱动 -- 原创
  14. echarts合并地图,把中国各个省份分成华北,东北,华东,华中,华南,西南,西北七个大区...
  15. 开源的轻量级JSON存储Kinto介绍
  16. 4 HQL操作之 -- DDL命令
  17. Xcode自定义代码块
  18. Spark Streaming 图片处理案例介绍
  19. 做题两大解题思想 by zyz on 2021/4/11
  20. android使用ContentProvider初始化sdk,初始化时机

热门文章

  1. "熊猫烧香"隐患未消 "小不点"将再掀风浪
  2. 求闰年 LeapYear.java
  3. 一些应该有所了解的常识
  4. 【转载】计算机科研路线规划及投稿方法
  5. 教你怎么玩indexedDB浏览器数据库,执行流程以及常见错误等等
  6. 阅读随记:场景理解篇
  7. 第4讲 李群与李代数 - Sophus库安装
  8. x11vnc安装及使用
  9. JavaScript基础——BOM浏览器对象模型
  10. .NET Framework 工程Target framework配置问题