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
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:
68
src/jiangchang_desktop_wake/c2.py
Normal file
68
src/jiangchang_desktop_wake/c2.py
Normal 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 "",
|
||||
}
|
||||
Reference in New Issue
Block a user