From 6d3c353967c601096e8ddc342e92cbddd088a97b Mon Sep 17 00:00:00 2001 From: chendelian <116870791@qq.com> Date: Sun, 2 Aug 2026 09:28:36 +0800 Subject: [PATCH] fix(desktop-wake): only OBJID_CLIENT DuiLib path to stop UIA core crash (1.2.5) Skip UiaRoot MSAA spoofing, sync GETOBJECT, and SPI screen-reader for n2-wake. Co-authored-by: Cursor --- pyproject.toml | 2 +- src/jiangchang_desktop_wake/ACCEPTANCE.md | 6 +-- src/jiangchang_desktop_wake/README.md | 4 +- .../native/desktop-wake.exe | Bin 18432 -> 18432 bytes .../native/wecom_wake.dll | Bin 118784 -> 118272 bytes .../native_src/DesktopWake/Program.cs | 5 ++- .../native_src/N2/payload/wecom_wake.cpp | 41 +++++++++--------- 7 files changed, 29 insertions(+), 29 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d0d5904..22cef46 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "jiangchang-platform-kit" -version = "1.2.4" +version = "1.2.5" description = "匠厂平台共享组件:Skill 实体 SDK + 桌面应用自动化 SDK + 桌面 UIA 暖树" readme = "README.md" requires-python = ">=3.10" diff --git a/src/jiangchang_desktop_wake/ACCEPTANCE.md b/src/jiangchang_desktop_wake/ACCEPTANCE.md index 0149b6d..e048937 100644 --- a/src/jiangchang_desktop_wake/ACCEPTANCE.md +++ b/src/jiangchang_desktop_wake/ACCEPTANCE.md @@ -1,7 +1,7 @@ -# jiangchang_desktop_wake 验收(ensure 主路径,1.2.4+) +# jiangchang_desktop_wake 验收(ensure 主路径,1.2.5+) 正式对外路径是 **`ensure`**(内部:`activate` → `desktop-wake --mode n2-wake` → `probe`)。 -`n2-wake` **不再**在企微进程内跑 UIAutomation FindAll(防 `uiautomationcore.dll` 崩溃);判暖只看进程外 probe。 +`n2-wake`:**仅 OBJID_CLIENT** 走 DuiLib;不做进程内 FindAll、不同步 GETOBJECT、不 SPI 读屏;判暖只看进程外 probe。 `c2` / `inject` 仅诊断用。 ## 0. 编译(企微先完全退出,含托盘) @@ -57,7 +57,7 @@ python -m jiangchang_desktop_wake probe --profile wecom | `probe_after.findall_count` | **≥ 80**(常见 300+) | | markers | 含 `con_op`、`searchedit` | | 企微 UI | 可点,无「未响应」 | -| provider | `done=1` `subclass=1` `dui=1` `no_inproc_uia=1`;`lr_client≠0` 更佳 | +| provider | `done=1` `subclass=1` `dui=1` `client_only=1` `no_inproc_uia=1` | | subclass | `method=SetWindowLongPtr`,`ok=1`,`userdata≠0` | | 企微进程 | **不崩**、无「错误报告」对话框 | diff --git a/src/jiangchang_desktop_wake/README.md b/src/jiangchang_desktop_wake/README.md index ee8f910..20a6717 100644 --- a/src/jiangchang_desktop_wake/README.md +++ b/src/jiangchang_desktop_wake/README.md @@ -2,8 +2,8 @@ 桌面 UIA Provider **暖树**(与 `jiangchang_skill_core` / `jiangchang_desktop_sdk` 平级)。 -企微主路径:注入 `wecom_wake.dll`,对主窗 `SetWindowLongPtr` 后走 DuiLib -`GetAccessible` / `OnGetObject`;**不在进程内 FindAll**(1.2.4+,避免 uiautomationcore 崩溃)。 +企微主路径:注入 `wecom_wake.dll`,对主窗 `SetWindowLongPtr` 后仅对 +`OBJID_CLIENT` 走 DuiLib `GetAccessible`(1.2.5+;避免 UiaRoot/MSAA 混用崩 uiautomationcore)。 可整目录删除:`src/jiangchang_desktop_wake` + `tests/desktop_wake`。 diff --git a/src/jiangchang_desktop_wake/native/desktop-wake.exe b/src/jiangchang_desktop_wake/native/desktop-wake.exe index 81a4f6b34b793f64725c3f10850118f1d9cb2895..591b3051748e8d9987fdeac4dfcdaa53c98b0b96 100644 GIT binary patch delta 467 zcmXxh&nv@W90&0C=Xo|8*4Q|#t;V;|Vhky2$S4#mNz~=45c%a*<#%X#&(c`#_@#vA^}W5 z)(r4!Gqf^OqiL!#*D2+J{u==OaxvJEH$AL}9Of7kG-?*|4b$ZN&f5@li2IrQpc$DUVW;OZ6V>FLFOHNyy7LaXGnb)S%GVYXoe%B*bWFU3}s}-dW zvE0aJ>)PN+Zhpnpn=KN)=n;26$shSIw{Bi{`WbXXD;IB_E)wppPdlsZ5T4!_G8!E} D^Acaw delta 465 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

xWc&nG@-u~)qD>!}g3LbquQl&C zx1g92mI`bkM=Uq7?c$eqC{V%U=Tbd_x*PA^}mzE=@-KlLEBPF`tyx>7t=C@BirSyGaac5^db57Nel!-Kt5|*vm@mnu4AXK`f$3S(F!KkN zkFmAL=Kv^6!+RRYz0}s^ha%jjECA0<}Z?q4qOv zh%Qd|tnQvJUT@W})<2^^tRHFIZ+yde!g$^IqwyExi`Y^Jno(*Te)I^0a%ortJXFI} zMzm#vidP*|3Ek&NsHaRFEX?|l2*Umrk~F(gSEZ}gU9q%VIxI{ko^^3}xea%|%Sz=k zd9Yl<$+&PXl8fS^xfm{%V>uTQl zRh6qMRohin!tV2Ay1}T9Qzzj3m#ns`>o8~ymgAO2oSIrJtvENiE6|Cd6fL(c_!Ww4 zwrMff;@AXXkM2!{1yC9I5%VQI~hSt~n_&0{;2j7qACR>i0iR7t8VEV`wxhS$+i zRJE$QRlO=Nb*!3owSAsCQ=L5mD^xztDV6Gd>Vw$Rq#Buq)o3+wnq+JUg_=4|t8n=u X87sBoNL#M2)F0H>=>@M#r1$>;mR?() delta 18962 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 Zs&uvdxi&JUPnyy0jn;VOApV5h{XY@SWuO26 diff --git a/src/jiangchang_desktop_wake/native_src/DesktopWake/Program.cs b/src/jiangchang_desktop_wake/native_src/DesktopWake/Program.cs index e0cfc83..3f909a3 100644 --- a/src/jiangchang_desktop_wake/native_src/DesktopWake/Program.cs +++ b/src/jiangchang_desktop_wake/native_src/DesktopWake/Program.cs @@ -152,8 +152,6 @@ namespace JiangchangDesktopWake try { Activate(hwnd); - EnableScreenReaderFlag(); // 进程外 SPI:部分 App 见“读屏器”会挂树 - // n1/auto:进程外 UIA // n2:仅注入探针 // n2-wake:注入 + 远程 WakeProvider(C2,无钩子) @@ -163,6 +161,9 @@ namespace JiangchangDesktopWake bool doWakeProvider = (mode == "n2-wake") && profile == "wecom"; // n2-wake:不在 exe 内做 UIA 深扫(易跟着目标进程一起挂);暖树由 Python probe 判定 bool doN1 = (mode == "n1" || mode == "auto" || mode == "n2-hook"); + // n2-wake 不再 SPI_SETSCREENREADER:会触发 UiaRoot 查询,测试机曾崩 uiautomationcore + if (!doWakeProvider) + EnableScreenReaderFlag(); if (doN2) { diff --git a/src/jiangchang_desktop_wake/native_src/N2/payload/wecom_wake.cpp b/src/jiangchang_desktop_wake/native_src/N2/payload/wecom_wake.cpp index 94389c5..3178c09 100644 --- a/src/jiangchang_desktop_wake/native_src/N2/payload/wecom_wake.cpp +++ b/src/jiangchang_desktop_wake/native_src/N2/payload/wecom_wake.cpp @@ -6,10 +6,11 @@ * WakeTarget — 旧子类化(危险,仅 n2-hook) * JcCallWndProc — 旧钩子(危险,仅 n2-hook) * - * 1.2.4 主路径(防 uiautomationcore 崩): - * - SetWindowLongPtr 子类化,WM_GETOBJECT → DuiLib GetAccessible/OnGetObject - * - 重入守卫:处理 GETOBJECT 时不再二次进 DuiLib - * - 不做进程内 UIAutomation FindAll / AccessibleObjectFromWindow(判暖交给进程外 probe) + * 1.2.5 主路径(防 uiautomationcore 崩): + * - SetWindowLongPtr 子类化;仅 OBJID_CLIENT 走 DuiLib GetAccessible + * - UiaRootObjectId 等原样交给旧 WndProc(禁止用 MSAA Lresult 冒充 UIA root) + * - 不做进程内 UIAutomation FindAll;不做同步 SendMessage(GETOBJECT) + * - 重入守卫;判暖交给进程外 probe */ #define WIN32_LEAN_AND_MEAN #include @@ -122,11 +123,9 @@ static HWND ReadTargetHwnd() static void NudgeWinEvents(HWND hwnd) { + /* 只异步点 CLIENT,绝不 Post UiaRootObjectId(易进 uiautomationcore 崩) */ NotifyWinEvent(EVENT_OBJECT_FOCUS, hwnd, OBJID_CLIENT, CHILDID_SELF); - NotifyWinEvent(EVENT_SYSTEM_ALERT, hwnd, OBJID_CLIENT, CHILDID_SELF); PostMessageW(hwnd, WM_GETOBJECT, 0, (LPARAM)OBJID_CLIENT); - PostMessageW(hwnd, WM_GETOBJECT, 0, (LPARAM)OBJID_WINDOW); - PostMessageW(hwnd, WM_GETOBJECT, 0, (LPARAM)UiaRootObjectId); PostMessageW(hwnd, WM_NULL, 0, 0); } @@ -144,8 +143,16 @@ static bool ResolveDuiLib() return g_fnGetAccessible != NULL || g_fnOnGetObject != NULL; } +static bool IsClientObjectId(LPARAM lParam) +{ + return (LONG)lParam == (LONG)OBJID_CLIENT; +} + static LRESULT TryDuiLibGetObject(HWND hwnd, WPARAM wParam, LPARAM lParam) { + /* 只服务 MSAA CLIENT。UiaRootObjectId 用 LresultFromObject(IAccessible) 会搞崩 UIA core */ + if (!IsClientObjectId(lParam)) + return 0; if (!ResolveDuiLib()) return 0; @@ -194,7 +201,8 @@ static LRESULT HandleGetObject( else if (oldProc) r = CallWindowProcW(oldProc, hwnd, WM_GETOBJECT, wParam, lParam); - if (r == 0) + /* 非 CLIENT(含 UiaRootObjectId):绝不伪造返回值 */ + if (r == 0 && IsClientObjectId(lParam)) r = TryDuiLibGetObject(hwnd, wParam, lParam); t_inGetObject = 0; @@ -263,11 +271,10 @@ static bool InstallDuiSubclass(HWND hwnd) return true; } -/* 只装子类化 + 异步 nudge;可选一次短超时 GETOBJECT 看 lr(无进程内 UIA) */ +/* 只装子类化 + 异步 nudge;禁止同步 SendMessage(GETOBJECT) */ static void DoSafeWake(HWND hwnd) { char line[512]; - LRESULT lrClient = 0; int subclass_ok = 0; int dui_ok = 0; @@ -276,21 +283,13 @@ static void DoSafeWake(HWND hwnd) subclass_ok = InstallDuiSubclass(hwnd) ? 1 : 0; NudgeWinEvents(hwnd); - - DWORD_PTR smResult = 0; - if (SendMessageTimeoutW( - hwnd, WM_GETOBJECT, 0, (LPARAM)OBJID_CLIENT, - SMTO_ABORTIFHUNG, 2000, &smResult)) { - lrClient = (LRESULT)smResult; - } - NudgeWinEvents(hwnd); sprintf_s(line, - "hwnd=%p sta_tid=%lu lr_client=%ld subclass=%d dui=%d " + "hwnd=%p sta_tid=%lu subclass=%d dui=%d " "dui_hits=%ld getobject_hits=%ld reenter_skip=%ld " - "no_inproc_uia=1 done=1\r\n", - hwnd, GetCurrentThreadId(), (long)lrClient, subclass_ok, dui_ok, + "client_only=1 no_sync_getobject=1 no_inproc_uia=1 done=1\r\n", + hwnd, GetCurrentThreadId(), subclass_ok, dui_ok, (long)g_duiHits, (long)g_getobjectHits, (long)g_reenterSkip); WriteMarker("jiangchang_desktop_wake_provider.txt", line); }