PC自动化之pywinauto

官方文档: https://pywinauto.readthedocs.io/en/latest/contents.html

 

[安装]

pip install pywinauto

 

[使用]

from pywinauto import application

# 创建应用程序对象并打开应用程序
app = application.Application()
app.start('your_application.exe')

# 连接到应用程序窗口
app.connect(title='Window Title')

# 获取窗口对象
window = app.window(title='Window Title')

# 获取子控件
child = window.child_window(class_name='UIAutomationClassName')

# 获取子控件的UI元素信息
element_info = child.uia_element_info

# 打印UI元素信息
print(element_info)

 

 

1.其中的点击事件,需要使用click_input代替click(无法正常使用)

2.其中涉及的鼠标和键盘的相关事件,推荐使用单独包

from pywinauto import mouse, keyboard

3.元素的操作对象是一个dialog, 所以应用需要指定

app.window(title='', class_name='')
可以指定名称或类名称

4.查找元素

win.child_window(title='', control_type='',found_index=0)
注: 如果存在多个元素, 则可以通过索引指定:found_index

指定名称和控件类型

常见控件类型:

Window: 窗口
ToolBar: 导航
Button: 按钮
ListItem: 聊天列表
Text:聊天内容

5.查询所有Windows下的窗口元素

# 查询当前内置浏览器窗格信息
    wins = pywinauto.findwindows.find_elements(backend='uia')
    print('所有窗口:', wins)
# 查找指定窗口的进程,类名,窗口名称(任务栏中展示的名称)等情况
    pid = 0
    for win in wins:
        print('=======================')
        print(dir(win))
        print(win.name)  # 窗口名称
        # print(win.control_id)  # 都是0
        # print(win.process_id)
        # print(win.automation_id)
        print(win.class_name)  # 类名
        # print(win.control_id)  # 都是0
        print(win.runtime_id)  # (id, 进程ID)
        if win.class_name == 'Chrome_WidgetWin_0':
            pid = win.runtime_id[1]
# 使用handle的方式链接窗口并执行操作
    app2 = Application(backend='uia').connect(handle=pid)
    # print(app2.window().print_control_identifiers())

    app2.window().child_window(title='关闭', control_type='Button', found_index=0).click_input()
 

 

 

 

 

使用实例:

1)自动打开微信链接

import random
import time

from pywinauto import mouse, keyboard
import pywinauto.findwindows
from pywinauto.application import Application
import pyautogui

# 连接方式1)
# app = Application(backend='uia').connect(process=19004)

# 连接方式2)
app = Application(backend='uia').connect(path=r'D:\software\WeChat\WeChat.exe')

# 该窗口中的对话框, 方便查看当前的窗口或窗格情况
# print(app.windows())
# Chrome_WidgetWin_0


# 打开
# app = Application(backend='uia').start('D:\software\WeChat\WeChat.exe')
# time.sleep(5)
# 拿到微信主窗口
win_main_dialog = app.window(title='微信', class_name='WeChatMainWndForPC')

# 判断是否未dialog, 一个微信就是一个dialog -->窗口
# print(win_main_dialog.is_dialog)


# print(win_main_dialog.wrapper_object())


# 给空间画一个红色框便于看出
win_main_dialog.draw_outline(colour='red')

# 打印当前所有空间和属性
# win_main_dialog.print_control_identifiers(depth=None, filename=None)

time.sleep(1)

def get_element_position(ele):
    """获取元素的中心点位置"""
    element_position = ele.rectangle()
    # 算出中心点位置
    center_position = (int((element_position.left + element_position.right) / 2),
                       int((element_position.top + element_position.bottom) / 2))
    return center_position




def send_msg():
    # 找到文件传输助手
    file_helper_ele = win_main_dialog.child_window(title="文件传输助手已置顶", control_type="ListItem")
    mouse.click(button='left', coords=get_element_position(file_helper_ele))

    # 获取输入框元素, 并模拟输入
    edit_ele = win_main_dialog.child_window(title="文件传输助手", control_type="Edit")
    time.sleep(2)
    edit_ele.type_keys("hello")
    keyboard.send_keys("{ENTER}")


def click_buttons():
    '''分别进行点击'''
    win_main_dialog.child_window(title="聊天", control_type="Button").click_input()
    time.sleep(2)
    win_main_dialog.child_window(title="通讯录", control_type="Button").click_input()
    time.sleep(2)
    win_main_dialog.child_window(title="朋友圈", control_type="Button").click_input()
    time.sleep(2)

def gui():
    # 使用pyautogui方式是比较固定(坐标)的方式
    pyautogui.click(x=622, y=183, clicks=1, interval=0.1)
    time.sleep(random.randint(3, 5))
    pyautogui.click(x=756, y=78, clicks=1, interval=0.1)



'''
depth: 打印深度, 缺省最大深度
filenmae: 返回的标识存成文件, 可以指定 eg:a.txt
'''

# 查找主窗口下的某个窗口
# chat_list = win_main_dialog.child_window(control_type='List', title='会话')
# first = chat_list.items()[0]  # 第一个聊天项, 支持循环, 索引
# chat_list.scroll(direction='down', amount='page')  # 向下滚动一页

# first.focus()

def main():
    # 找到聊天框
    chat_list_ele = win_main_dialog.child_window(title="聊天", control_type="Button")
    mouse.click(button='left', coords=get_element_position(chat_list_ele))
    time.sleep(1)
    # 找到指定聊天人
    ln = win_main_dialog.child_window(title="Learning已置顶", control_type="ListItem")
    mouse.click(button='left', coords=get_element_position(ln))

    time.sleep(1)
    # 找到指定链接并点击
    lk = win_main_dialog.child_window(title=r"https://www.cnblogs.com/xingxia", control_type="ListItem")
    mouse.click(button='left', coords=get_element_position(lk))

    time.sleep(random.randint(3, 5))
    # 关闭内置浏览器

    # 1) 查询当前内置浏览器窗格信息
    wins = pywinauto.findwindows.find_elements(backend='uia')
    print('所有窗口:', wins)
    pid = 0
    for win in wins:
        print('=======================')
        print(dir(win))
        print(win.name)  # 窗口名称
        # print(win.control_id)  # 都是0
        # print(win.process_id)
        # print(win.automation_id)
        print(win.class_name)  # 类名
        # print(win.control_id)  # 都是0
        print(win.runtime_id)  # (id, 进程ID)
        if win.class_name == 'Chrome_WidgetWin_0':
            pid = win.runtime_id[1]

    app2 = Application(backend='uia').connect(handle=pid)
    # print(app2.window().print_control_identifiers())

    app2.window().child_window(title='关闭', control_type='Button', found_index=0).click_input()


if __name__ == '__main__':
    main()  # 自动化主流程
    # send_msg()  # 发送消息
    # click_buttons()
    # gui()

说明:

1.其中元素定位软件需要借助: inspect.exe 或者 UISpy

 这里推荐使用UISpy,但是不能通过点选方式获取元素信息,需要一级一级查找,有些不太友好

inspect.exe虽然可以通过点选方式查找元素,但是具体的元素信息展示的不正确

PC端的自动化, 除了可以使用pywinauto之外,还有其他的工具可以选择, 例如:uiautomation

 

对比PyWinAuto和uiautomation

PyWinAuto和uiautomation都是自动化测试工具,它们都可以模拟用户的操作来测试应用程序的功能。但是PyWinAuto是一个Python库,可以跨平台使用,而uiautomation是一个Windows平台的测试工具。除此之外,PyWinAuto提供更多的GUI操作函数和更好的文档支持,而uiautomation则更加适合对Windows应用程序进行测试。

安装

pip install uiautomation

 

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

 

常见问题:

1. 

pywinauto.findwindows.ElementNotFoundError

进程没加载完成,就执行查找工作,通过time.sleep()就可以解决

app = pywinauto.Application(backend='uia').start(r"D:\Program Files\PremiumSoft\Navicat for MySQL\navicat.exe")
# 方式一
# 使用雷鸣选择窗口,打印窗口所有控件
time.sleep(5)
dlg = app['TNavicatMainForm']
dlg.print_control_identifiers()

  

 

posted @ 2024-07-29 15:48  X-Wolf  阅读(588)  评论(0)    收藏  举报