Python调用WinAppDriver切换已运行应用的实现方法
WinAppDriver 实现跨应用(MS Store/Chrome)窗口切换方案
问题原因说明
你遇到的window_handles返回空值问题,本质是三个原因导致的:
- 旧版C#示例里的窗口枚举逻辑是C#客户端专属实现,Python环境下的Appium/Selenium绑定没有做对应适配,直接照搬代码必然失效
- Root桌面会话初始化时缺少必要的能力参数,加上新版Selenium 4.x+已经废弃了旧版纯字典传参的模式,部分接口调用会出现无返回的异常
window_handles接口本身设计是给单应用多窗口场景用的,Root桌面会话下调用这个接口本来就不会返回所有顶层应用窗口的句柄,和你本地代码写法无关。
前置依赖要求
先确认本地安装的依赖版本符合要求,版本不匹配是大部分适配问题的根源:
- WinAppDriver 版本 ≥ 1.2.1(建议安装1.2.99最新正式版)
- Appium-Python-Client 版本 ≥ 2.6.0
- Selenium 版本 ≥ 4.10.0,不要使用3.x及以下的老旧版本
正确实现步骤
1. 初始化稳定的Root桌面会话
不要用旧版的desired_caps字典直接传参,新版客户端用WindowsOptions对象传参兼容性更好:
from appium import webdriver from appium.options.windows import WindowsOptions import time root_options = WindowsOptions() root_options.app = "Root" root_options.platform_name = "Windows" root_options.device_name = "WindowsPC" # 初始化Root会话,这个会话用来查找所有顶层桌面窗口 root_session = webdriver.Remote( command_executor="http://127.0.0.1:4723", options=root_options )
2. 定位目标应用窗口获取原生句柄
不要尝试用window_handles枚举窗口,直接通过Root会话查找目标应用的顶层窗口元素,提取原生窗口句柄即可:
# 提前启动Chrome和MS Store应用 # 定位Chrome主窗口,若标题动态变化可以替换为class name定位:find_element("class name", "Chrome_WidgetWin_1") chrome_win = root_session.find_element("name", "Google Chrome") chrome_handle = chrome_win.get_attribute("NativeWindowHandle") # 定位MS Store主窗口,类名定位写法:find_element("class name", "ApplicationFrameWindow") ms_store_win = root_session.find_element("name", "Microsoft Store") store_handle = ms_store_win.get_attribute("NativeWindowHandle")
3. 封装窗口切换方法
WinAppDriver切换顶层应用窗口的核心逻辑是:拿到目标窗口的原生句柄后,直接attach到对应句柄创建新的应用会话即可,不需要在同一个会话里做切换:
def attach_to_window(native_window_handle): win_options = WindowsOptions() win_options.app = "topLevelWindow" win_options.app_top_level_window = native_window_handle win_options.platform_name = "Windows" win_options.device_name = "WindowsPC" return webdriver.Remote( command_executor="http://127.0.0.1:4723", options=win_options ) # 切换到Chrome窗口操作 chrome_session = attach_to_window(chrome_handle) print(f"当前已切换到Chrome,窗口标题:{chrome_session.title}") time.sleep(2) # 切换到MS Store窗口操作 store_session = attach_to_window(store_handle) print(f"当前已切换到MS Store,窗口标题:{store_session.title}")
注意事项
如果遇到定位窗口匹配到弹窗、子窗口的问题,可以结合
processId属性做过滤:拿到窗口元素后先取processId属性,和目标应用的进程ID做比对,确认是主窗口后再做attach操作。
操作完不用的会话记得调用quit()方法释放,避免WinAppDriver连接数占满导致后续调用失败。
内容的提问来源于stack exchange,提问作者Md Sajid
相关产品推荐
相关产品推荐

