此文章來源於專案官方公眾號:“AirtestProject”
版權宣告:允許轉載,但轉載必須保留原連結;請勿用作商業或者非法用途
一、前言
在連線windows
視窗的時候,有些同學會遇到一個應用但是開啟了幾個不同的程序視窗,但是在AirtestIDE搜尋視窗只有一個或尋找視窗名稱都是統一名稱的時候,又應該如何處理呢?那麼今天我們一起來探討下這個問題吧~
二、獲取windows應用程序相關資訊方式
在需要獲取windows
應用程序的相關資訊,我們需要確保我們的python
環境中含有下面幾種庫,建議在本地的python
環境中進行修改,並將AirtestIDE
的python
環境更換為本地的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