基于pywinauto的自动化

概要

pywinauto是一组python模块,用于自动化Microsoft Windows GUI。最简单的是,它允许您将鼠标和键盘操作发送到窗口对话框和控件,但它支持更复杂的操作,如获取文本数据。
后台支持的技术:Win32 API(后端=“Win32”;默认情况下使用)、MS UI自动化(后台=“uia”)。用户输入模拟模块鼠标和键盘可以在Windows和Linux上工作。

安装

pip install -U pywinauto

setup

Example

import os
import random
import sys
import time
import datetime
from openpyxl import Workbook
from random import randint
from random import randrange, randint, sample
from time import sleep
from math import sqrt
from abc import ABCMeta, abstractmethod
import tkinter
import tkinter.messagebox
import time, socket
from pywinauto.application import Application
from pywinauto.timings import wait_until

if __name__ == '__main__':
	app = Application(backend="uia").start(r"C:\Program Files (x86)\Lenovo\LenovoNow\x86\LenovoNow.exe")
    time.sleep(10)
    dlg = app.window(title='Lenovo Now')
    Pin = dlg.child_window(auto_id="checkbox-welcome-battery-widget-input")
    #Pin.click_input()
    print(Pin.get_toggle_state())

连接

connect()用于连接已经启动的程序。连接一个已经运行的程序有以下几种方法:

1.process:进程id

def get_pid_by_name(name):
    pid = -1
    ps = psutil.process_iter()
    for p in ps:
        if p.name() == name:
            pid = p.pid
            break
if __name__ == '__main__':
	pid = get_pid_by_name('LenovoNow.exe')
	app = Application().connect(process=pid)

2.handle:应用程序的窗口句柄

h = win32gui.FindWindow(None, 'Lenovo Now')
app = Application('uia').connect(handle=h)

3.path:进程的执行路径(GetModuleFileNameEx 模块会查找进程的每一个路径并与我们传入的路径去做比较)

app = Application('uia').connect(path=r"C:\Program Files (x86)\Lenovo\LenovoNow\x86\LenovoNow.exe")

4.参数组合(传递给pywinauto.findwindows.find_elements()这个函数)

app = Application('uia').connect(title_re=".*Notepad", class_name="Notepad")

注:应用程序必须先准备就绪,才能使用connect(),当应用程序start()后没有超时和重连的机制。在pywinauto外再启动应用程序,需要sleep,等程序start.

注:如果打开了好几个相同的app,可以使用index来遍历

app=application.Application(backend='uia').connect(title="ADWorkbench",found_index=i)
app.kill(soft=False) # 强制关闭
app.cpu_usage() # 返回指定秒数期间的CPU使用率百分比
app.wait_cpu_usage_lower(threshold=2.5, timeout=None, usage_interval=None) # 等待进程CPU使用率百分比小于指定的阈值threshold
app.is64bit() # 如果操作的进程是64-bit,返回True

元素定位工具介绍

1.Backend判断

我目前项目是uia的

Pywinauto中backend有两种:win32和uia,默认为win32。可使用spy++和Inspect工具判断backend适合写哪种。
例如:如果使用Inspect的UIA模式,可见的控件和属性更多的话,backend可选uia,反之,backend可选win32。

常用元素定位接口

1.常用定位控件接口(重要)

# 通过层级查找控件相关方法
window(**kwargs) # 用于窗口的查找
child_window(**kwargs) # 可以无视层级的找后代中某个符合条件的元素===>【最常用】
parent() # 返回此元素的父元素,没有参数
children(**kwargs) # 返回符合条件的子元素列表,支持索引,是BaseWrapper对象(或子类)
iter_children(**kwargs) # 返回子元素的迭代器,是BaseWrapper对象(或子类)
descendants(**kwargs) # 返回符合条件的所有后代元素列表,是BaseWrapper对象(或子类)
iter_children(**kwargs) # 符合条件后代元素迭代器,是BaseWrapper对象(或子类)---> 存疑,是iter_descendants?

2.常用属性(重要)

# 常用的
class_name=None, # 类名
class_name_re=None, # 正则匹配类名
title=None, # 控件的标题文字,对应inspect中Name字段
title_re=None, # 正则匹配文字
control_type=None, # 控件类型,inspect界面LocalizedControlType字段的英文名
best_match=None, # 模糊匹配类似的title
auto_id=None, # inspect界面AutomationId字段,但是很多控件没有这个属性

# 不常用
parent=None,
process=None,# 这个基本不用,每次启动进程都会变化
top_level_only=True,
visible_only=True,
enabled_only=False,
handle=None,
ctrl_index=None,
found_index=None,
predicate_func=None,
active_only=False,
control_id=None,
framework_id=None,
backend=None,

3.控件可用的方法属性(重要)

# 以下几个只支持窗口模式的控件
dlg.close() # 关闭界面
dlg.minimize() # 最小化界面
dlg.maximize() # 最大化界面
dlg.restore() # 将窗口恢复为正常大小,比如最小化的让他正常显示在桌面
dlg.get_show_state() # 正常0,最大化1,最小化2
dlg.menu_select() # 菜单栏,eg:app.window.menu_select(Edit -> Replace)
dlg.exists(timeout=None, retry_interval=None) # 判断是否存在
        #timeout:等待时间,一般默认5s
        #retry_interval:timeout内重试时间
dlg.wait(wait_for, timeout=None, retry_interval=None) # 等待窗口处于特定状态
dlg.wait_not(wait_for_not, timeout=None, retry_interval=None) # 等待窗口不处于特定状态,即等待消失
        # wait_for/wait_for_not:
            # * 'exists' means that the window is a valid handle
            # * 'visible' means that the window is not hidden
            # * 'enabled' means that the window is not disabled
            # * 'ready' means that the window is visible and enabled
            # * 'active' means that the window is active
        # timeout:等待多久
        # retry_interval:timeout内重试时间
        # eg: dlg.wait('ready')

# 鼠标键盘操作,只列举了常用形式,他们有很多默认参数但不常用,可以在源码中查看
ctrl.click_input() # 最常用的点击方法,一切点击操作的基本方法(底层调用只是参数不同),左键单击,使用时一般都使用默认不需要带参数
ctrl.right_click_input() # 鼠标右键单击
ctrl.type_keys(keys, pause = None, with_spaces = False,) # 键盘输入,底层还是调用keyboard.send_keys
        # keys:要输入的文字内容
        # pause:每输入一个字符后等待时间,默认0.01就行
        # with_spaces:是否保留keys中的所有空格,默认去除0
ctrl.double_click_input(button ="left", coords = (None, None)) # 左键双击
ctrl.press_mouse_input(coords = (None, None)) # 指定坐标按下左键,不传坐标默认左上角
ctrl.release_mouse_input(coords = (None, None)) # 指定坐标释放左键,不传坐标默认左上角
ctrl.move_mouse_input(coords=(0, 0)) # 将鼠标移动到指定坐标,不传坐标默认左上角
ctrl.drag_mouse_input(dst=(0, 0)) # 将ctrl拖动到dst,是press-move-release操作集合

# 控件的常用属性
ctrl.children_texts() # 所有子控件的文字列表,对应inspect中Name字段
ctrl.window_text() # 控件的标题文字,对应inspect中Name字段
# ctrl.element_info.name
ctrl.class_name() # 控件的类名,对应inspect中ClassName字段,有些控件没有类名
# ctrl.element_info.class_name
ctrl.element_info.control_type # 控件类型,inspect界面LocalizedControlType字段的英文名
ctrl.is_child(parent) # ctrl是否是parent的子控件
ctrl.legacy_properties().get('Value') # 可以获取inspect界面LegacyIAccessible开头的一系列字段,在源码uiawraper.py中找到了这个方法,非常有用

# 控件常用操作
ctrl.draw_outline(colour='green') # 空间外围画框,便于查看,支持'red', 'green', 'blue'
ctrl.print_control_identifiers(depth=None, filename=None) # 以树形结构打印其包含的元素,详见打印元素
        # depth:打印的深度,缺省时打印最大深度。
        # filename:将返回的标识存成文件(生成的文件与当前运行的脚本在同一个路径下)
ctrl.scroll(direction, amount, count=1,) # 滚动
        # direction :"up", "down", "left", "right"
        # amount:"line" or "page"
        # count:int 滚动次数
ctrl.capture_as_image() # 返回控件的 PIL image对象,可继续使用其方法如下:
        # eg: ctrl.capture_as_image().save(img_path)
ret = ctrl.rectangle() # 控件上下左右坐标,(L430, T177, R1490, B941),可输出上下左右
        # eg: ret.top=177
            # ret.bottom=941
            # ret.left=430
            # ret.right=1490

参考文献

PC端windows自动化:pywinauto(一)安装和打开程序
Github
腾讯云自媒体
什么是Pywinauto

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值