Files
notify/docs/interop.md
T
chuan 5ce2c8a982 feat: Claude Code 原生 Windows 通知(C# / .NET 10 + Avalonia 12)
为 Claude Code 提供原生 Windows toast 通知:点击跳回原窗口、切回 Windows
Terminal 标签、跨虚拟桌面、调用方图标、非阻塞投递;NativeAOT 单文件分发。
2026-06-22 18:05:15 +08:00

2.9 KiB
Raw Blame History

原生互操作与 AOT

所有 Win32 / COM 互操作都为 NativeAOT 准备:用 LibraryImport(源生成 P/Invoke)和 [GeneratedComInterface](源生成 COM),不用 System.Drawing、经典 [ComImport]、反射式封送(它们在 AOT 下不可用)。

文件 职责 关键点
Win32.cs 基础 P/Invoke GetForegroundWindowGetClassName、工具窗口样式等
WindowActivator.cs 抢前台激活 ALT 模拟 + AttachThreadInput + 多 API 组合,绕过防焦点抢占
WinTerminalTabs.cs WT 切标签 源生成 COM 调 UIAutomation,按 RuntimeId 定位标签
VirtualDesktopPinner.cs 跨虚拟桌面 未公开 COM IVirtualDesktopPinnedApps.PinView
ProcessTree.cs 进程树上溯 Toolhelp 快照,跳过 shell/运行时找调用方 App
AppIcon.cs 取图标 ExtractIconEx + GDI 读 BGRA 像素 → Avalonia 位图
Sound.cs 提示音 winmm PlaySound 从内存异步播放

窗口激活(WindowActivator

Windows 限制后台进程抢焦点。组合技:还原最小化 → 模拟一次 ALT 抬起 → AttachThreadInput 把当前线程与前台/目标线程输入队列挂接 → AllowSetForegroundWindow + SetWindowPos/BringWindowToTop/SwitchToThisWindow/SetForegroundWindow 多管齐下 → 解除挂接。

Windows Terminal 切标签(WinTerminalTabs

  • save 时:检测前台窗口类是否 CASCADIA_HOSTING_WINDOW_CLASS;是则用 UIAutomation 找当前选中的 TabItem,取其 RuntimeId(一串 intSAFEARRAY)存入状态。
  • 点击时:激活 WT 窗口后,枚举标签找到 RuntimeId 匹配的,调 SelectionItemPattern.Select()
  • AOT 要点:接口用 [GeneratedComInterface];未用到的 vtable 槽用占位方法按 SDK 头文件顺序补齐(顺序 / GUID 均取自 UIAutomationClient.h);IApplicationView 以裸 IntPtr 传递。

跨虚拟桌面(VirtualDesktopPinner

  • CoCreateInstanceCLSCTX_LOCAL_SERVER)拿 ImmersiveShell → IApplicationViewCollection.GetViewForHwndIVirtualDesktopPinnedApps.PinView
  • GUID 取自 Win11 24H2;整段 try/catch,失败自动退回"仅当前桌面"。
  • 窗口刚打开时 view 可能尚未就绪,短间隔重试直到成功。

取图标(AppIcon

ExtractIconEx 拿 HICON → GetIconInfo 取彩色位图 → GetDIBits 以 32bpp 自上而下读出 BGRA → 构造 Avalonia.Media.Imaging.Bitmap。老图标无 alpha(全 0)时补成不透明,避免整块透明。取不到则回退默认 Claude 图标。

AOT

  • csprojIsAotCompatiblePublishAot 条件块 + TrimmerRootAssemblyUrsa / Semi 整体保留)+ CoreUtils.*.Static 静态链接 Skia / HarfBuzz / ANGLE。
  • 原生链接需要 MSVC 工具链(从 "Developer Command Prompt for VS" 跑,或用配好 vcvars 的脚本)。
  • 源生成 COM / UIAutomation 与静态渲染需在真机运行验证。