Windows技巧:輕鬆連線多程序視窗之一

AirtestProject發表於2024-05-30

此文章來源於專案官方公眾號:“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

相關文章