Files
jiangchang-platform-kit/src/jiangchang_desktop_wake/__main__.py
chendelian 71091e38a9
All checks were successful
Publish Python Package to Gitea / publish (push) Successful in 29s
feat(desktop-wake): add WeCom UIA warm-tree and ship n2-wake in 1.2.3
Expose ensure_ui_ready via DuiLib GetAccessible inject path; package x86 native helpers for host/skill consumers.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-02 08:42:38 +08:00

157 lines
4.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""CLI:python -m jiangchang_desktop_wake <probe|inject|wake|ensure|profiles>"""
from __future__ import annotations
import argparse
import json
import sys
def _print_json(obj) -> None:
print(json.dumps(obj, ensure_ascii=False, indent=2))
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(
prog="python -m jiangchang_desktop_wake",
description="桌面 UIA Provider 暖树(probe / inject / wake / ensure)",
)
sub = parser.add_subparsers(dest="cmd", required=True)
p_profiles = sub.add_parser("profiles", help="列出内置 profile")
p_profiles.set_defaults(func=_cmd_profiles)
p_probe = sub.add_parser("probe", help="探测冷/暖")
p_probe.add_argument("--profile", default="wecom")
p_probe.add_argument("--hwnd", type=lambda s: int(s, 0), default=None)
p_probe.set_defaults(func=_cmd_probe)
p_inject = sub.add_parser(
"inject",
help="阶段 B:安全注入探针(不挂钩;成功看 inject_ok + ui_responsive)",
)
p_inject.add_argument("--profile", default="wecom")
p_inject.add_argument("--hwnd", type=lambda s: int(s, 0), default=None)
p_inject.set_defaults(func=_cmd_inject)
p_c2 = sub.add_parser(
"c2",
help="阶段 C2:SPI + 注入 + WakeProvider,再 probe(冲暖树)",
)
p_c2.add_argument("--profile", default="wecom")
p_c2.add_argument("--hwnd", type=lambda s: int(s, 0), default=None)
p_c2.set_defaults(func=_cmd_c2)
p_wake = sub.add_parser("wake", help="仅跑唤醒策略(不强制成功)")
p_wake.add_argument("--profile", default="wecom")
p_wake.add_argument("--hwnd", type=lambda s: int(s, 0), default=None)
p_wake.set_defaults(func=_cmd_wake)
p_ensure = sub.add_parser(
"ensure",
help="probe→wake→probe;wecom 主路径为 n2-wake(DuiLib 暖树)",
)
p_ensure.add_argument("--profile", default="wecom")
p_ensure.add_argument("--hwnd", type=lambda s: int(s, 0), default=None)
p_ensure.add_argument(
"--no-raise",
action="store_true",
help="仍冷也 exit 0,只打印 JSON",
)
p_ensure.set_defaults(func=_cmd_ensure)
args = parser.parse_args(argv)
try:
return int(args.func(args))
except Exception as exc:
print(str(exc), file=sys.stderr)
return 1
def _cmd_profiles(_args) -> int:
from .profiles import list_profiles, load_profile
out = []
for pid in list_profiles():
p = load_profile(pid)
out.append(
{
"id": p.id,
"description": p.description,
"window_class": p.window_class,
"warm_min_findall": p.warm_min_findall,
"warm_markers": p.warm_markers,
"wake_strategies": p.wake_strategies,
}
)
_print_json(out)
return 0
def _cmd_probe(args) -> int:
from .probe import probe
r = probe(args.profile, hwnd=args.hwnd)
_print_json(r.to_dict())
return 0 if r.warm else 2
def _cmd_inject(args) -> int:
from .inject import inject_probe
r = inject_probe(args.profile, hwnd=args.hwnd)
_print_json(r)
if r.get("inject_ok") and r.get("ui_responsive"):
return 0
if r.get("inject_ok") and not r.get("ui_responsive"):
return 6
return 5
def _cmd_c2(args) -> int:
from .c2 import wake_c2
r = wake_c2(args.profile, hwnd=args.hwnd)
_print_json(r)
if r.get("warm"):
return 0
if r.get("ui_responsive") is False:
return 6
return 4
def _cmd_wake(args) -> int:
from .probe import probe
from .wake import wake
steps = wake(args.profile, hwnd=args.hwnd)
after = probe(args.profile, hwnd=args.hwnd)
_print_json(
{
"steps": [s.to_dict() for s in steps],
"probe_after": after.to_dict(),
}
)
return 0 if after.warm else 2
def _cmd_ensure(args) -> int:
from .ensure import ensure_ui_ready
from .errors import DesktopWakeError
try:
r = ensure_ui_ready(
args.profile,
hwnd=args.hwnd,
raise_on_cold=not args.no_raise,
)
except DesktopWakeError as exc:
print(str(exc), file=sys.stderr)
return 1
_print_json(r.to_dict())
return 0 if r.warm else 2
if __name__ == "__main__":
raise SystemExit(main())