From 24384d70ba5118d2462ba668954a6e1155d2e6b1 Mon Sep 17 00:00:00 2001 From: chendelian <116870791@qq.com> Date: Sun, 2 Aug 2026 21:32:23 +0800 Subject: [PATCH] fix(desktop-wake): never inject SearchResultWindow2 (1.2.9) Soft-wake search popup only; n2-wake on float crashed WeCom via wecom_wake.dll. Co-authored-by: Cursor --- pyproject.toml | 2 +- src/jiangchang_desktop_wake/ACCEPTANCE.md | 16 +++++------ src/jiangchang_desktop_wake/README.md | 2 +- .../native/desktop-wake.exe | Bin 18944 -> 18944 bytes .../native/wecom_wake.dll | Bin 118784 -> 120320 bytes .../native_src/DesktopWake/Program.cs | 26 ++++++++++++++++++ .../native_src/N2/payload/wecom_wake.cpp | 22 +++++++++++++++ src/jiangchang_desktop_wake/profiles.py | 6 ++-- .../profiles/wecom_search.json | 10 +++---- src/jiangchang_desktop_wake/types.py | 2 +- tests/desktop_wake/test_profiles_and_types.py | 7 +++-- 11 files changed, 69 insertions(+), 24 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index be12128..cbd0339 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "jiangchang-platform-kit" -version = "1.2.8" +version = "1.2.9" 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 3f0ceea..b9a8d2d 100644 --- a/src/jiangchang_desktop_wake/ACCEPTANCE.md +++ b/src/jiangchang_desktop_wake/ACCEPTANCE.md @@ -1,4 +1,4 @@ -# jiangchang_desktop_wake 验收(ensure 主路径,1.2.8+) +# jiangchang_desktop_wake 验收(ensure 主路径,1.2.9+) 正式对外路径是 **`ensure`**(内部:`activate` → `desktop-wake --mode n2-wake` → `probe`)。 `n2-wake`:**仅 OBJID_CLIENT** 走 DuiLib;不做进程内 FindAll、不同步 GETOBJECT、不 SPI 读屏;判暖只看进程外 probe。 @@ -7,7 +7,7 @@ | profile | 窗 | 说明 | |---|---|---| | `wecom` | `WeWorkWindow` | 主窗(原有) | -| `wecom_search` | `SearchResultWindow2` | 搜索浮层;**不对浮层 Maximize**;n2-wake **子类化浮层本身**(DLL 支持多窗;主窗已暖后仍可再装浮层) | +| `wecom_search` | `SearchResultWindow2` | 搜索浮层;**不对浮层 Maximize / 不注入**(1.2.9+ 仅软唤醒;注入会崩企微) | ## 0. 编译(企微先完全退出,含托盘) @@ -77,11 +77,11 @@ python -m jiangchang_desktop_wake probe --profile wecom --- -## C. 搜索浮层 wecom_search(1.2.8+) +## C. 搜索浮层 wecom_search(1.2.9+) 1. **建议先** `ensure --profile wecom` 暖主窗(可与浮层分步)。 2. 在搜索框输入联系人,**保持搜索结果浮层打开**(类名 `SearchResultWindow2`)。 -3. 验收: +3. 验收(**禁止**对浮层 n2-wake/注入;profile 仅 `wm_getobject` + `msaa`): ```powershell cd D:\OpenClaw\client-jiangchang\jiangchang-platform-kit @@ -93,10 +93,10 @@ python -m jiangchang_desktop_wake probe --profile wecom_search | 期望 | 说明 | |---|---| -| ensure 退出码 `0` | 浮层已暖 | -| `warm=true` | markers 含 `search_result` / `user_item`(或 findall 足够) | -| `%TEMP%\jiangchang_desktop_wake_subclass.txt` | 含浮层 hwnd,`ok=1`(主窗已暖后再 ensure 浮层也会再写一条) | -| 企微 UI | 浮层**不**被 Maximize 撑满、**不白屏**、不无故关闭 | +| ensure **不**崩企微 | 故障模块不应再是 `wecom_wake.dll` | +| `warm=true`(或 soft poke 后 findall≫2) | markers 含 `search_result` / `user_item` | +| 企微 UI | 浮层保持打开、**不** Maximize、不白屏 | +| 若手动对浮层跑 `desktop-wake … n2-wake` | exe/DLL 应走 `popup_soft_only` / `popup_nudge_only`,**不**子类化浮层 | | `WINDOW_NOT_FOUND` | 浮层未打开——先展开搜索结果再测 | --- diff --git a/src/jiangchang_desktop_wake/README.md b/src/jiangchang_desktop_wake/README.md index 6e5c9d0..8c9ed6a 100644 --- a/src/jiangchang_desktop_wake/README.md +++ b/src/jiangchang_desktop_wake/README.md @@ -42,7 +42,7 @@ print(rs.warm, rs.probe_after.findall_count, rs.probe_after.markers_found) | profile | 窗 | 说明 | |---|---|---| | `wecom` | `WeWorkWindow` | 主窗;markers=`con_op`,`searchedit` | -| `wecom_search` | `SearchResultWindow2` | 搜索浮层;markers=`search_result`,`user_item`;不 Maximize;**n2-wake 对浮层子类化**(1.2.8+ 支持主窗+浮层多窗) | +| `wecom_search` | `SearchResultWindow2` | 搜索浮层;markers=`search_result`,`user_item`;**禁止注入/n2-wake**(1.2.9+ 仅进程外软唤醒) | | CLI | 退出码 | |---|---| diff --git a/src/jiangchang_desktop_wake/native/desktop-wake.exe b/src/jiangchang_desktop_wake/native/desktop-wake.exe index 97545974ca560b96ccc2ded10595eefb83058dd5..6a19f594f4202dd553ec0987f2be1739f188994e 100644 GIT binary patch delta 4499 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 delta 4244 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 /// 主窗可 Maximize;SearchResultWindow2 等浮层禁止 Maximize(会撑爆/关掉浮层)。 /// 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 12f3ae3..d80ea40 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 @@ -12,6 +12,7 @@ * - 不做进程内 UIAutomation FindAll;不做同步 SendMessage(GETOBJECT) * - 重入守卫;判暖交给进程外 probe * 1.2.8:支持多 HWND 子类化(主窗 + SearchResultWindow2),禁止「全局只装一次」。 + * 1.2.9:SearchResultWindow2 禁止子类化/DuiLib thiscall(会崩企微);浮层只异步 nudge。 */ #define WIN32_LEAN_AND_MEAN #include @@ -139,6 +140,14 @@ static void NudgeWinEvents(HWND hwnd) PostMessageW(hwnd, WM_NULL, 0, 0); } +static bool IsSearchResultPopup(HWND hwnd) +{ + wchar_t cls[256]; + if (!hwnd || !GetClassNameW(hwnd, cls, 256)) + return false; + return _wcsicmp(cls, L"SearchResultWindow2") == 0; +} + static bool ResolveDuiLib() { if (g_fnGetAccessible && g_fnOnGetObject) return true; @@ -322,6 +331,19 @@ static void DoSafeWake(HWND hwnd) int subclass_ok = 0; int dui_ok = 0; + /* 浮层:DuiLib thiscall / 换 WndProc 在宿主环境会直接崩企微(fault=wecom_wake.dll) */ + if (IsSearchResultPopup(hwnd)) { + NudgeWinEvents(hwnd); + NudgeWinEvents(hwnd); + sprintf_s(line, + "hwnd=%p sta_tid=%lu popup_nudge_only=1 subclass=0 dui=0 " + "dui_hits=%ld getobject_hits=%ld done=1\r\n", + hwnd, GetCurrentThreadId(), + (long)g_duiHits, (long)g_getobjectHits); + WriteMarker("jiangchang_desktop_wake_provider.txt", line); + return; + } + ResolveDuiLib(); dui_ok = (g_fnGetAccessible || g_fnOnGetObject) ? 1 : 0; subclass_ok = InstallDuiSubclass(hwnd) ? 1 : 0; diff --git a/src/jiangchang_desktop_wake/profiles.py b/src/jiangchang_desktop_wake/profiles.py index dd4144c..f90ac09 100644 --- a/src/jiangchang_desktop_wake/profiles.py +++ b/src/jiangchang_desktop_wake/profiles.py @@ -44,14 +44,12 @@ _BUILTIN = { }, "wecom_search": { "id": "wecom_search", - "description": "企业微信搜索结果浮层 SearchResultWindow2(n2-wake 对浮层子类化,1.2.8+)", + "description": "企业微信搜索结果浮层 SearchResultWindow2;仅进程外软唤醒(禁止注入,1.2.9+)", "window_class": "SearchResultWindow2", "warm_min_findall": 20, "warm_markers": ["search_result", "user_item"], "activate_maximize": False, - "wake_strategies": ["activate", "native_helper"], - "native_helper": "desktop-wake.exe", - "native_args": ["wecom", "0x{hwnd_hex}", "--mode", "n2-wake"], + "wake_strategies": ["wm_getobject", "msaa_from_window"], }, } diff --git a/src/jiangchang_desktop_wake/profiles/wecom_search.json b/src/jiangchang_desktop_wake/profiles/wecom_search.json index 35dd482..0bbb1b2 100644 --- a/src/jiangchang_desktop_wake/profiles/wecom_search.json +++ b/src/jiangchang_desktop_wake/profiles/wecom_search.json @@ -1,14 +1,12 @@ { "id": "wecom_search", - "description": "企业微信搜索结果浮层 SearchResultWindow2(联系人列表 user_item);n2-wake 对浮层本身子类化(1.2.8+ 支持多窗),禁止 Maximize", + "description": "企业微信搜索结果浮层 SearchResultWindow2;仅进程外软唤醒(禁止 n2-wake/注入,1.2.9+)", "window_class": "SearchResultWindow2", "warm_min_findall": 20, "warm_markers": ["search_result", "user_item"], "activate_maximize": false, "wake_strategies": [ - "activate", - "native_helper" - ], - "native_helper": "desktop-wake.exe", - "native_args": ["wecom", "0x{hwnd_hex}", "--mode", "n2-wake"] + "wm_getobject", + "msaa_from_window" + ] } diff --git a/src/jiangchang_desktop_wake/types.py b/src/jiangchang_desktop_wake/types.py index 3b2b306..69fbd5e 100644 --- a/src/jiangchang_desktop_wake/types.py +++ b/src/jiangchang_desktop_wake/types.py @@ -30,7 +30,7 @@ class Profile: # 浮层窗(如搜索结果)禁止 Maximize,避免打乱搜索态 activate_maximize: bool = True # native_helper / n2-wake 目标窗 class;空则用 probe 窗本身。 - # 1.2.8+ wecom_search 留空(对浮层子类化);若需改注其它窗可再设。 + # wecom_search 留空;1.2.9+ 浮层禁止 native 注入,勿再设为浮层自身。 native_hwnd_class: Optional[str] = None @classmethod diff --git a/tests/desktop_wake/test_profiles_and_types.py b/tests/desktop_wake/test_profiles_and_types.py index 794a09d..123edbe 100644 --- a/tests/desktop_wake/test_profiles_and_types.py +++ b/tests/desktop_wake/test_profiles_and_types.py @@ -34,10 +34,11 @@ class ProfileTests(unittest.TestCase): self.assertIn("search_result", p.warm_markers) self.assertIn("user_item", p.warm_markers) self.assertFalse(p.activate_maximize) - # 1.2.8+:对浮层本身 n2-wake(多窗子类化);不再改注主窗 + # 1.2.9+:浮层禁止 n2-wake/注入(会崩企微);仅进程外软唤醒 self.assertFalse((p.native_hwnd_class or "").strip()) - self.assertIn("native_helper", p.wake_strategies) - self.assertIn("n2-wake", p.native_args or []) + self.assertNotIn("native_helper", p.wake_strategies) + self.assertIn("wm_getobject", p.wake_strategies) + self.assertIn("msaa_from_window", p.wake_strategies) def test_resolve_native_hwnd_fallback_without_class(self): from jiangchang_desktop_wake.wake import resolve_native_hwnd