Windows GUI自动化控制工具之python uiAutomation

对 Windows GUI进行自动化控制的工具有很多,比如pywinautopyautoguipywin32AutoitairtestUIAutomation等,UI Automation API是微软提供的自动化框架,可在支持 Windows Presentation Foundation (WPF) 的所有操作系统上使用,支持的应用类型更多。本文介绍封装了UI Automation API的Python uiautomation 模块的使用方法。

Python uiautomation 模块由yinkaisheng 开发,封装了微软 UI Automation API,支持自动化Win32,MFC,WPF,Modern UI(Metro UI), Qt, IE, Firefox, Chrome和基于Electron开发的应用程序。

环境准备

uiautomation安装

最新版uiautomation2.0只支持Python 3版本,但不要使用3.7.6和3.8.1这两个版本,因为comtypes包在这两个版本中不能正常工作。

pip安装uiautomation:

$ pip install uiautomation

检查是否安装成功:

$ pip list | findstr uiautomation
uiautomation       2.0.18

安装完成后,在Python的Scripts(我的路径为C:\Program Files\Python37\Scripts)目录中会有一个文件automation.py,是用来枚举控件树结构的一个脚本。

可运行 automation.py -h查看命令帮助:

$ python automation.py -h
UIAutomation 2.0.18 (Python 3.7.2, 64 bit)
usage
-h      show command help
-t      delay time, default 3 seconds, begin to enumerate after Value seconds, this must be an integer
        you can delay a few seconds and make a window active so automation can enumerate the active window
-d      enumerate tree depth, this must be an integer, if it is null, enumerate the whole tree
-r      enumerate from root:Desktop window, if it is null, enumerate from foreground window
-f      enumerate from focused control, if it is null, enumerate from foreground window
-c      enumerate the control under cursor, if depth is < 0, enumerate from its ancestor up to depth
-a      show ancestors of the control under cursor
-n      show control full name, if it is null, show first 30 characters of control's name in console,
        always show full name in log file @AutomationLog.txt
-p      show process id of controls

if UnicodeError or LookupError occurred when printing,
try to change the active code page of console window by using chcp or see the log file @AutomationLog.txt
chcp, get current active code page
chcp 936, set active code page to gbk
chcp 65001, set active code page to utf-8

examples:
automation.py -t3
automation.py -t3 -r -d1 -m -n
automation.py -c -t3

进程查看器

对 Windows GUI进行自动化控制需要使用进程查看器工具对GUI界面元素进行定位,定位工具有很多,这里推荐使用微软提供的inspect.exe 或者 Accessibility Insights 这两款工具。

inspect.exe

inspect.exe 是 Windows SDK 自带的一个进程查看器,可以用来查看系统正在运行的进程信息、模块、线程、堆栈跟踪等详细数据。

Windows SDK下载地址为:https://developer.microsoft.com/en-us/windows/downloads/sdk-archive/

建议直接到这里下载inspect.exe:https://github.com/yinkaisheng/Python-UIAutomation-for-Windows/tree/master/inspect

64位系统版本的inspect.exe也可以点击这里下载。

Accessibility Insights

Accessibility Insights 是微软开发的一款辅助功能测试工具。它可以帮助开发者测试 web 应用、Windows 桌面应用和 Android 应用的可访问性,确保这些应用程序符合无障碍标准。

Accessibility Insights获取的控件属性信息没有inspect.exe全面,使用起来更加流畅。下载为:https://accessibilityinsights.io/downloads/

控件对象模型

微软 UIAutomation API定义了支持的控件类型和对应的模型(Pattern),所有支持的控件类型可参考:https://learn.microsoft.com/en-us/windows/win32/winauto/uiauto-controlpatternmapping

控件类型必须支持的模型可选模型Does not support
ButtonNoneExpandCollapse, Invoke, Toggle, ValueNone
CalendarGrid, TableScroll, SelectionValue
CheckBoxToggleNoneNone
EditNoneRangeValue, Text, ValueNone
ListNoneGrid, MultipleView, Scroll, SelectionTable
ListItemSelectionItemCustomNavigation, ExpandCollapse, GridItem, Invoke, ScrollItem, Toggle, ValueNone
MenuNoneNoneNone
MenuBarNoneDock, ExpandCollapse, TransformNone
MenuItemNoneExpandCollapse, Invoke, SelectionItem, ToggleNone
RadioButtonSelectionItemNoneToggle
SplitButtonExpandCollapse, InvokeNoneNone
TabSelectionScrollNone
TabItemSelectionItemNoneInvoke
TableGrid, GridItem, Table, TableItemNoneNone
TextNoneGridItem, TableItem, TextValue
TitleBarNoneNoneNone
ToolBarNoneDock, ExpandCollapse, TransformNone

python uiautomation库对UIAutomation API定义的各个Control和Pattern进行了封装。

下面来看使用python uiautomation操作Windows自带计算器的例子。

uiautomation库示例

控制计算器

可以使用inspect.exe来定位计算器元素:

在这里插入图片描述

示例脚本如下:

import os
import uiautomation as auto
import subprocess

class uiautoCalc(Loggers):
    """uiautomation控制计算器
    """
    def __init__(self):
        super().__init__()
        self.logger = Loggers().myLogger()
        auto.uiautomation.DEBUG_SEARCH_TIME =True 
        auto.uiautomation.SetGlobalSearchTimeout(2) # 设置全局搜索超时时间
        self.calcWindow = auto.WindowControl(searchDepth=1, Name='计算器', desc='计算器窗口') # 计算器窗口
        if not self.calcWindow.Exists(0,0):
            subprocess.Popen('calc')# 设置窗口前置
            self.calcWindow = auto.WindowControl(
            searchDepth=1, Name='计算器', desc='计算器窗口')
        self.calcWindow.SetActive() # 激活窗口
        self.calcWindow.SetTopmost(True) # 设置为顶层

    def gotoScientific(self):
        self.calcWindow.ButtonControl(AutomationId='TogglePaneButton', desc='打开导航').Click(waitTime=0.01)        
        self.calcWindow.ListItemControl(AutomationId='Scientific', desc='选择科学计算器').Click(waitTime=0.01)
        clearButton = self.calcWindow.ButtonControl(AutomationId='clearEntryButton', desc='点击CE清空输入')
        if clearButton.Exists(0,0):
            clearButton.Click(waitTime=0)
        else:
            self.calcWindow.ButtonControl(AutomationId='clearButton', desc='点击C清空输入').Click(waitTime=0.01)

    def getKeyControl(self):
        automationId2key ={'num0Button':'0','num1Button':'1','num2Button':'2','num3Button':'3','num4Button':'4','num5Button':'5','num6Button':'6','num7Button':'7','num8Button':'8','num9Button':'9','decimalSeparatorButton':'.','plusButton':'+','minusButton':'-','multiplyButton':'*','divideButton':'/','equalButton':'=','openParenthesisButton':'(','closeParenthesisButton':')'}        
        calckeys = self.calcWindow.GroupControl(ClassName='LandmarkTarget')
        keyControl ={}
        for control, depth in auto.WalkControl(calckeys, maxDepth=3):
            if control.AutomationId in automationId2key:
                self.logger.info(control.AutomationId)
                keyControl[automationId2key[control.AutomationId]]= control
        return keyControl

    def calculate(self, expression, keyControl):
        expression =''.join(expression.split())
        if not expression.endswith('='):
            expression +='='
            for char in expression:
                keyControl[char].Click(waitTime=0)
        self.calcWindow.SendKeys('{Ctrl}c', waitTime=0.1)
        return auto.GetClipboardText()

    def calc_demo(self):
        """计算器示例
        :return : 
        """        
        self.gotoScientific() # 选择科学计算器        
        keyControl = self.getKeyControl() # 获取按键控件
        result     = self.calculate('(1 + 2 - 3) * 4 / 5.6 - 7', keyControl)
        print('(1 + 2 - 3) * 4 / 5.6 - 7 =', result)
        self.calcWindow.CaptureToImage('calc.png', x=7, y=0, width=-14, height=-7) # 截图
        self.calcWindow.GetWindowPattern().Close() # 关闭计算机

if __name__ == "__main__":
    ui = uiautoCalc()
    ui.calc_demo()

脚本执行动图:

在这里插入图片描述

参考文档

  1. https://github.com/pywinauto/pywinauto

  2. https://cloud.tencent.com/developer/article/2213048

  3. https://github.com/yinkaisheng/Python-UIAutomation-for-Windows

  4. Python UIAutomation文档:https://github.com/yinkaisheng/Python-UIAutomation-for-Windows/blob/master/readme_cn.md

  5. https://www.cnblogs.com/Yinkaisheng/p/3444132.html

  6. GitHub - jacexh/pyautoit: Python binding for AutoItX3.dll

  7. GitHub - mhammond/pywin32: Python for Windows (pywin32) Extensions

  8. Accessibility tools - Inspect - Win32 apps | Microsoft Learn

  9. Accessibility Insights

--THE END--
  • 10
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PythonUIAutomation库可以实现微信的自动回复功能。UIAutomation是一种自动化测试工具,可以模拟用户交互操作来进行自动化测试。具体实现步骤如下: 1. 安装UIAutomation库:在命令行中输入`pip install uiautomation`来安装UIAutomation库。 2. 导入所需的库:在Python脚本中导入UIAutomation库以及其他需要使用的库,比如`time`用于设置延时。 3. 启动微信并登录:使用UIAutomation库的`ShellExecute`函数来启动微信应用,并通过UIAutomation库提供的定位元素的方法找到微信的登录界面,输入用户名和密码进行登录。 4. 找到聊天窗口并获取消息:使用UIAutomation库提供的定位元素的方法找到微信的聊天窗口,并使用`GetValuePattern`方法获取聊天窗口的文本内容。 5. 判断是否有新消息:通过判断聊天窗口的文本内容是否有变化,即是否有新的消息到来,来确定是否需要进行自动回复。 6. 进行自动回复:使用UIAutomation库提供的定位元素和输入文本的方法来找到微信的输入框,并输入自动回复的内容。 7. 发送自动回复:模拟鼠标点击发送按钮,即可将自动回复的内容发送出去。 8. 循环检测并回复:使用一个无限循环,不停地检测是否有新消息,并根据需要进行自动回复,可以通过设置延时来控制检测的频率。 需要注意的是,由于微信客户端的更新可能会改变UI元素的布局或属性,导致自动化定位失败,所以在具体使用时可能需要根据微信客户端的实际情况对代码进行适当的调整和修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值