import queue
import threading
import time
from enum import Enum
from uiautomation import uiautomation
classControlName(Enum):
Intel_Graphics_Command_Center =['AMD显卡',"Intel® Graphics Command Center","设备管理器","Home"]deffind_window_by_uiautomation(names:list, control=uiautomation.WindowControl):deffind_thread(_name:str):nonlocal control
time.sleep(1)with uiautomation.UIAutomationInitializerInThread(debug=False):
item_control = control(Name=_name)whileTrue:try:if item_control.Exists(maxSearchSeconds=5):# 搜索时间
q.put(_name)break# break在if外面是为了确保在遇到未知问题时,至少找一次except Exception as e:print(e)
q = queue.Queue()
_list =[]for name in names:
t = threading.Thread(target=find_thread, args=(name,))
t.daemon =True
t.start()
_list.append(t)for _ in names:try:
_res = q.get(timeout=5)if _res:return _res
except queue.Empty:returnFalseif __name__ =='__main__':
start = time.time()
res = find_window_by_uiautomation(names=ControlName.Intel_Graphics_Command_Center.value,
control=uiautomation.WindowControl)print("USE:", time.time()- start, res)
2.形式二
该方法利用多线程线程池进行搜索,主线程在等待所有子线程返回结果后才会继续执行。
优势:主线程继续执行时不会产生额外的子线程开销。
劣势:至少要等到maxSearchSeconds后,主线程才会继续执行。
import concurrent.futures
import time
from enum import Enum
from uiautomation import uiautomation, UninitializeUIAutomationInCurrentThread, InitializeUIAutomationInCurrentThread
classControlName(Enum):
Intel_Graphics_Command_Center =['1121','1121',"Intel® Graphics Command Center"]deffind_window_by_uiautomation(control, names=None):# 定义一个准备作为线程任务的函数deffind_thread(_name):nonlocal control
# Uninitialize UIAutomation in a new thread after calling InitializeUIAutomationInCurrentThread.# You must call this function when the new thread exits if you have called InitializeUIAutomationInCurrentThread in the same thread.
UninitializeUIAutomationInCurrentThread()# Initialize UIAutomation in a new thread.# If you want to use functionalities related to Controls and Patterns in a new thread.# You must call this function first in the new thread.# But you can't use a Control or a Pattern created in a different thread.# So you can't create a Control or a Pattern in main thread and then pass it to a new thread and use it.
InitializeUIAutomationInCurrentThread()
item_control = control(Name=_name)if item_control.Exists(maxSearchSeconds=3):return item_control
else:returnFalseif names isNone:returnFalseifnotisinstance(names,list):
names =[names]# 创建一个包含n条线程的线程池with concurrent.futures.ThreadPoolExecutor(max_workers=len(names))as pool:
futures =[pool.submit(find_thread, _)for _ in names]# 通过as_completed函数获取第一个完成的任务for future in concurrent.futures.as_completed(futures):
result = future.result()
pool.shutdown()return result
if __name__ =='__main__':
start = time.time()
a = find_window_by_uiautomation(names=ControlName.Intel_Graphics_Command_Center.value,
control=uiautomation.WindowControl)print("USE:", time.time()- start, a)