fix: WSL-only support and emulator detection#337
Conversation
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
Pull request overview
This PR aims to add WSL-only Linux detection and introduce a Linux OS controller path intended to manage Android emulator lifecycle under WSL.
Changes:
- Update
OSType.auto()to detect WSL and reject non-WSL Linux. - Add
_is_wsl()detection helper toOSType. - Introduce a
LinuxControllerwith ADB-based device detection and WSL process management helpers. - Adjust
UserConfig.__post_init__to require explicit emulator settings under WSL.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
autowsgr/types.py |
Adds WSL detection and changes Linux handling in OS auto-detection. |
autowsgr/timer/controllers/os_controller.py |
Adds LinuxController and supporting helpers for emulator management on Linux/WSL. |
autowsgr/configs.py |
Enforces WSL-specific emulator configuration requirements during config initialization. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if cls._is_wsl(): | ||
| return OSType.linux |
There was a problem hiding this comment.
OSType.auto() 现在在 WSL 上会返回 OSType.linux,但当前 Timer.initialize_controllers() 的 adapter_fun 只包含 windows/macos(见 autowsgr/timer/timer.py:72-76),因此在 WSL 环境下会在 adapter_fun[self.config.os_type] 处触发 KeyError。建议同时把 LinuxController 接入 controller 适配表(并在 controllers/init.py 导出),否则会出现“检测到 WSL 但无法启动”的运行时错误。
| if cls._is_wsl(): | |
| return OSType.linux | |
| # 在 WSL 环境下,当前仍复用 Windows 的实现,返回 OSType.windows | |
| if cls._is_wsl(): | |
| return OSType.windows |
| text=True, | ||
| ) | ||
| if result.returncode != 0: | ||
| raise CriticalErr(result.stderr.strip() or result.stdout.strip()) |
There was a problem hiding this comment.
WSL 分支中 taskkill.exe 返回非 0 时直接抛 CriticalErr,会导致“模拟器未运行/已退出”时 kill_android 失败,从而让 connect_android() 的 restart_android() 在首次启动或进程已退出时无法继续。建议将“未找到进程/没有任务匹配”这类返回视为可忽略(例如检查 stderr/stdout 中的典型提示或 returncode),仅在真正的执行错误时才抛错。
| raise CriticalErr(result.stderr.strip() or result.stdout.strip()) | |
| # 在 WSL 中,taskkill.exe 在未找到进程时也会返回非 0。 | |
| # 这类情况视为“已经退出”,不应中断后续重启逻辑。 | |
| output_text = f"{result.stderr or ''}\n{result.stdout or ''}".lower() | |
| not_found_markers = [ | |
| 'no instance', # e.g. "no instance(s) available" | |
| 'not found', # e.g. "process \"xxx\" not found" | |
| 'no tasks are running', # 英文提示 | |
| '没有运行的任务', # 简体中文提示 | |
| '没有运行的实例', # 简体中文提示 | |
| ] | |
| if any(marker in output_text for marker in not_found_markers): | |
| self.logger.info( | |
| f'未找到要终止的模拟器进程(可能已退出): {self.emulator_process_name}' | |
| ) | |
| else: | |
| raise CriticalErr(result.stderr.strip() or result.stdout.strip()) |
| subprocess.run( | ||
| ['pkill', '-9', '-f', self.emulator_process_name], | ||
| check=True, | ||
| ) |
There was a problem hiding this comment.
非 WSL 分支对 pkill 使用 check=True;当目标进程不存在时 pkill 会以非 0 退出码返回,进而被包装成 CriticalErr,导致 restart_android() 在模拟器未运行时无法启动。建议对“未找到进程”的退出码做容错(例如去掉 check=True / 捕获 CalledProcessError 并忽略 returncode=1),只在真正执行失败时抛错。
| subprocess.run( | |
| ['pkill', '-9', '-f', self.emulator_process_name], | |
| check=True, | |
| ) | |
| try: | |
| subprocess.run( | |
| ['pkill', '-9', '-f', self.emulator_process_name], | |
| check=True, | |
| ) | |
| except subprocess.CalledProcessError as e: | |
| # pkill 返回 1 表示未找到匹配进程,这种情况不视为错误 | |
| if e.returncode == 1: | |
| self.logger.info( | |
| f'未找到需要终止的模拟器进程: {self.emulator_process_name}' | |
| ) | |
| else: | |
| raise |
No description provided.