AirtestProject Windows 技巧:轻松连接多进程窗口之一

fishfish-yu · 2024年05月30日 · 1598 次阅读

此文章来源于项目官方公众号:“AirtestProject”\
版权声明:允许转载,但转载必须保留原链接;请勿用作商业或者非法用途

一、前言

在连接windows窗口的时候,有些同学会遇到一个应用但是打开了几个不同的进程窗口,但是在 AirtestIDE 搜索窗口只有一个或寻找窗口名称都是统一名称的时候,又应该如何处理呢?那么今天我们一起来探讨下这个问题吧~

二、获取 windows 应用进程相关信息方式

在需要获取windows应用进程的相关信息,我们需要确保我们的python环境中含有下面几种库,建议在本地的python环境中进行修改,并将AirtestIDEpython环境更换为本地的python环境。

pip install psutil
pip install pywinauto

2.1 获取 windows 所有进程

可以获取本地计算机上所有正在运行的进程的类实例,并返回一个迭代器,我们可以将我们需要查询的指定参数传入括号内,会以字典的形式去创建一份进程表。

for proc in psutil.process_iter(['pid', 'name', 'create_time']):
    print(proc.info)

2.2 获取进程异常类

有三种不同的获取进程的异常类,我们可以通过异常处理进行跳过或输出报错等。

# 当在当前进程列表中找不到具有给定 pid 的进程时,或者当进程不再存在时,由类方法引发。
psutil.NoSuchProcess(pid, name=None, msg=None)

# 当由于权限不足而拒绝执行操作的权限时, 由类方法引发。
psutil.AccessDenied(pid=None, name=None, msg=None)

# 如果超时并且进程仍然存在,则通过方法引发。
psutil.TimeoutExpired(seconds, pid=None, name=None, msg=None)

2.3 判断进程是否有界面

可以通过使用pywinauto库下的 findwindows.find_window(process=pid)获取窗口句柄去进行判断,当获取的窗口句柄长度大于 0 时,则证明该进程有界面。

def has_gui(pid):
    try:
        windows = findwindows.find_windows(process=pid)
        return len(windows) > 0
    except Exception as e:
        return False

2.4 使用进程pid去连接特定进程

我们可以通过在连接设备时传入pid号进行连接特定的进程窗口,就算有多个进程窗口,我们也可以根据不同窗口的进程pid去进行连接测试。

dev = connect_device(f"Windows:///?process=pid")

当然,我们除了这个也还有其他连接窗口的句柄,可以根据自己的需求去实现连接,更多的Windows小技巧也可以查看我们教程文档:

https://airtest.doc.io.netease.com/IDEdocs/3.2device_connection/5_windows_connection/

# 连接一个 Windows 窗口,窗口句柄为 123456
dev = connect_device("Windows:///123456")
# 连接一个 Windows 窗口,窗口名称匹配某个正则表达式
dev = connect_device("Windows:///?title_re=Unity.*")
# 连接 windows 桌面,不指定任何窗口,对应 IDE 的桌面模式
dev = connect_device("Windows:///")

三、使用案例

上面提供了一些获取应用进程的方式,以及查询选择pid的方法,那么我们实际运用起来的效果会是怎么样的呢?

可以看到,我们可以先通过应用的进程名,去全局搜索本地是否已开启该应用,然后通过找到的进程,逐一排查有窗口界面的应用进程pid,再连接上对应的应用窗口并调出来,并进行测试操作。

参考代码如下:

# -*- encoding=utf8 -*-
__author__ = "Airtest"

import psutil
from pywinauto import findwindows
from airtest.core.api import *

# 获取所有进程信息
def get_process_info(process_name):
    process_info_list = []

    # 获取本地目前所有的进程并查找我们需要连接的进程
    for proc in psutil.process_iter(['pid', 'name', 'create_time']):
        #将需要搜索的进程信息加入到列表里,并在搜索结束后返回列表
        try:
            if process_name.lower() in proc.info['name'].lower():
                process_info_list.append(proc.info)
    #当出现异常时,直接跳过
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
            pass
    return process_info_list

# 判断进程是否有界面
def has_gui(pid):
    try:
        #利用pid去获取窗口句柄,当窗口句柄大于0时,则证明该进程有窗口界面
        windows = findwindows.find_windows(process=pid)
        return len(windows) > 0
    except Exception as e:
        return False

# 选择特定进程
def select_process(process_info_list):
    for proc_info in process_info_list:
        # 判断进程是否有界面
        if has_gui(proc_info['pid']):
            return proc_info['pid']
    return None

# 连接到特定进程并进行操作
def connect_and_operate(process_info):
    if process_info:
        try:
            # 连接到特定进程窗口
            dev = connect_device(f"Windows:///?process={process_info}")
            print("Target process found.")

            # 连接后可以进行自动化操作,例如点击、输入等,这里仅做截图操作
            sleep(3.0)
            snapshot(msg="当前界面截图", quality=90)

        #遇到异常后,将异常信息抛出
        except Exception as e:
            print(f"Error during connecting or operating: {e}")
    else:
        print("No target process found.")

if __name__ == "__main__":
    process_name = "有道云笔记.exe"  # 示例应用程序名称

    # 获取所有目标应用的进程信息
    process_info_list = get_process_info(process_name)
    print(f"Found processes: {process_info_list}")

    # 选择特定进程(通过动态获取对应进程的pid,进行连接)
    selected_process = select_process(process_info_list)
    print(f"Selected process: {selected_process}")

    # 连接到特定进程并进行操作
    connect_and_operate(selected_process)

四、小结

我们今天介绍了几个在windows上有关获取进程相关信息的方法,分别是:

1、获取所有进程

2、获取进程异常类

3、判断进程是否有界面

4、使用进程pid去连接特定进程

通过上述方法,我们可以通过应用进程的相关信息,去实现更多的 windows 窗口连接方式,如果你有更好的连接窗口的小技巧,也欢迎在评论区或私信告诉我们。如果在测试的过程中,遇到了问题,或者有任何想要深入了解的知识点,欢迎在官方交流群里告诉我们或者提交 issue,也欢迎大家投稿其他不同的使用小技巧。


AirtestIDE 下载:airtest.netease.com/\
Airtest 教程官网:airtest.doc.io.netease.com/\
搭建企业私有云服务:airlab.163.com/b2b

官方答疑 Q 群:526033840

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册