feat(desktop-wake): add WeCom UIA warm-tree and ship n2-wake in 1.2.3
All checks were successful
Publish Python Package to Gitea / publish (push) Successful in 29s

Expose ensure_ui_ready via DuiLib GetAccessible inject path; package x86 native helpers for host/skill consumers.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-02 08:42:38 +08:00
parent 3dc46b0555
commit 71091e38a9
29 changed files with 3088 additions and 3 deletions

View File

@@ -0,0 +1,68 @@
"""阶段 C2:安全注入 + WakeProvider 进程内暖树尝试。"""
from __future__ import annotations
import json
import os
import subprocess
import time
from pathlib import Path
from typing import Any, Optional
from .errors import DesktopWakeError, ERR_WAKE_FAILED
from .probe import probe
from .profiles import load_profile
from .wake import native_helper_path
from .window import find_hwnd_for_profile, require_windows
def wake_c2(
profile: str = "wecom",
*,
hwnd: Optional[int] = None,
) -> dict[str, Any]:
"""跑 desktop-wake --mode n2-wake,再 probe。
成功暖树:返回里 ``warm=true``(与 probe 一致)。
"""
require_windows()
prof = load_profile(profile)
h = find_hwnd_for_profile(prof, hwnd=hwnd)
before = probe(prof, hwnd=h)
helper = native_helper_path(prof.native_helper or "desktop-wake.exe")
if helper is None:
raise DesktopWakeError(ERR_WAKE_FAILED, "desktop-wake.exe 缺失,请先 build.ps1")
cmd = [str(helper), prof.id, "0x" + format(int(h), "x"), "--mode", "n2-wake"]
try:
proc = subprocess.run(cmd, capture_output=True, text=True, timeout=60, check=False)
except subprocess.TimeoutExpired as exc:
raise DesktopWakeError(ERR_WAKE_FAILED, "n2-wake timeout") from exc
out = (proc.stdout or "").strip()
native: dict[str, Any] = {"rc": proc.returncode, "stderr": (proc.stderr or "")[:300]}
if out:
try:
native.update(json.loads(out.splitlines()[-1].strip()))
except json.JSONDecodeError:
native["raw"] = out[:500]
# 进程内 UIA 客户端保持存活后,给外层树一点沉降时间
time.sleep(1.0)
after = probe(prof, hwnd=h)
tdir = Path(os.environ.get("TEMP") or os.environ.get("TMP") or ".")
provider = tdir / "jiangchang_desktop_wake_provider.txt"
return {
"hwnd": h,
"profile_id": prof.id,
"cmd": cmd,
"native": native,
"probe_before": before.to_dict(),
"probe_after": after.to_dict(),
"warm": after.warm,
"ui_responsive": bool(native.get("ui_responsive", True)),
"provider_text": provider.read_text(encoding="utf-8", errors="replace")
if provider.is_file()
else "",
}