修复_ensure_hwnd UIA挂死导致整条while循环卡住\n\n1. _ensure_hwnd 调用包装 ThreadPoolExecutor + 12s 超时\n 防止 QQ TXGuiFoundation 枚举或微信窗口检测无限阻塞\n 超时后日志警告 + 跳过本轮,while 循环继续跑\n\n2. _run_loop 首轮加 '进入 while 循环' 日志\n 快速确认循环启动\n\n3. 新增 concurrent.futures 导入\n\n根因:UIA COM 调用可挂死不返回(如遍历所有顶层窗口时\n某进程无响应),整个 _poll 卡住 → while 循环停转\n→ 无心跳 → 无任何输出

This commit is contained in:
youpaishidifu
2026-07-26 15:13:09 +08:00
parent 5492cdf81b
commit 6d0974ea8f
+13 -2
View File
@@ -16,6 +16,7 @@ import ctypes
import difflib import difflib
import os import os
from datetime import datetime from datetime import datetime
from concurrent.futures import ThreadPoolExecutor, TimeoutError as FuturesTimeout
from PIL import ImageGrab from PIL import ImageGrab
from winrt.windows.media.ocr import OcrEngine from winrt.windows.media.ocr import OcrEngine
from winrt.windows.globalization import Language from winrt.windows.globalization import Language
@@ -123,6 +124,7 @@ class MessageMonitor:
except Exception: except Exception:
pass pass
heartbeat = 0 heartbeat = 0
logger.debug("_run_loop 进入 while 循环")
while self._running: while self._running:
try: try:
if self._wechat_enabled and not self._sending_event.is_set(): if self._wechat_enabled and not self._sending_event.is_set():
@@ -1408,8 +1410,17 @@ class MessageMonitor:
counter = self._poll_count.get(platform, 0) + 1 counter = self._poll_count.get(platform, 0) + 1
self._poll_count[platform] = counter self._poll_count[platform] = counter
# 1. 确保窗口句柄 # 1. 确保窗口句柄(带超时保护,防止 UIA COM 调用挂死不返回)
hwnd = self._ensure_hwnd(platform) hwnd = None
_ex = ThreadPoolExecutor(max_workers=1)
try:
hwnd = _ex.submit(self._ensure_hwnd, platform).result(timeout=12.0)
except FuturesTimeout:
logger.warning(f"[{platform}] _ensure_hwnd 超时(12s),跳过本轮")
except Exception as e:
logger.warning(f"[{platform}] _ensure_hwnd 异常: {e}")
finally:
_ex.shutdown(wait=False)
if not hwnd: if not hwnd:
if counter % 10 == 0: if counter % 10 == 0:
logger.debug(f"[{platform}] 窗口未找到") logger.debug(f"[{platform}] 窗口未找到")