Files
notify/docs/interop.md
T
chuan 79992680c9 docs: 重写 README 并新增 docs 调用时序文档
- README 对齐当前 C# / Avalonia 架构与安装方式
- docs: architecture / sequences / hooks-and-cli / interop / build-and-install
2026-06-22 16:40:27 +08:00

3.2 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);IApplicationViewIntPtr 传递,绕开现代 .NET 不支持的 IInspectable 封送。

跨虚拟桌面(VirtualDesktopPinner

  • CoCreateInstance 拿 ImmersiveShell必须 CLSCTX_LOCAL_SERVER,否则 REGDB_E_CLASSNOTREG)→ IApplicationViewCollection.GetViewForHwndIVirtualDesktopPinnedApps.PinView
  • GUID 随 Windows 版本变化(这里用 24H2 一套,实测 26200 仍匹配);整段 try/catch,失败自动退回"仅当前桌面"。
  • 窗口刚打开时 shell 可能还没登记 view(TYPE_E_ELEMENTNOTFOUND),故短间隔重试。

取图标(AppIcon

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

AOT 状态

  • csproj 已开 IsAotCompatible(静态分析 0 警告);PublishAot 条件块 + TrimmerRootAssemblyUrsa/Semi 整体保留)。
  • AOT 发布的原生链接需要 MSVC 工具链(从 "Developer Command Prompt for VS" 跑,或用配好 vcvars 的脚本)。
  • ⚠️ build 通过 ≠ 能跑:源生成 COM / UIAutomation 必须真机运行验证(本项目踩过 CLSCTXIInspectable 封送两个坑,都是编译过但运行崩)。