"""冷/暖探测。""" from __future__ import annotations from typing import Optional, Union from .errors import DesktopWakeError, ERR_UIA_UNAVAILABLE from .profiles import load_profile from .types import ProbeResult, Profile from . import uia_backend from .window import ( find_hwnd_for_profile, get_window_class, get_window_title, require_windows, ) def probe( profile: Union[str, Profile] = "wecom", *, hwnd: Optional[int] = None, require_uia: bool = False, ) -> ProbeResult: """探测目标窗 UIA 是否已暖。 warm 判定:findall >= warm_min_findall,且 warm_markers 全部找到(若配置了 markers)。 """ require_windows() prof = load_profile(profile) if isinstance(profile, str) else profile h = find_hwnd_for_profile(prof, hwnd=hwnd) title = get_window_title(h) cls = get_window_class(h) notes: list[str] = [] available = uia_backend.uia_available() if require_uia and not available: raise DesktopWakeError( ERR_UIA_UNAVAILABLE, "未安装 uiautomation,请在共享 Python 环境中: pip install uiautomation", ) findall_count = 0 names: list[str] = [] if available: findall_count, names = uia_backend.count_findall(h) if findall_count == 0 and not names: notes.append("uia_timeout_or_empty") markers_found, markers_missing = uia_backend.find_markers_on_hwnd( h, list(prof.warm_markers) ) # 若 Exists 未命中,用 Name 列表兜底 if markers_missing and names: fb_found, fb_missing = uia_backend.markers_present(names, markers_missing) markers_found = list(dict.fromkeys(markers_found + fb_found)) markers_missing = fb_missing else: notes.append("uiautomation_not_installed") markers_found, markers_missing = [], list(prof.warm_markers) density_ok = findall_count >= int(prof.warm_min_findall) markers_ok = not prof.warm_markers or not markers_missing warm = bool(available and density_ok and markers_ok) if available and not density_ok: notes.append(f"sparse_findall={findall_count}<{prof.warm_min_findall}") if available and prof.warm_markers and markers_missing: notes.append(f"missing_markers={','.join(markers_missing)}") return ProbeResult( hwnd=h, profile_id=prof.id, findall_count=findall_count, markers_found=markers_found, markers_missing=markers_missing, warm=warm, window_title=title, window_class=cls, uia_available=available, notes=notes, )