# 桌面应用其实是网页:想通这点,操作它就不再是"桌面自动化"

第一次用 chrome-use 连上 Slack 桌面版、`snapshot` 出来一堆带名字的按钮时,我愣了一下:这跟操作一个网页没任何区别。后来想通了,因为 Slack 桌面版本来就是个网页。

Electron 应用是一个 Chromium 渲染引擎加一层 Node.js 外壳。你以为在用"桌面软件"的 Slack、VS Code、Discord、Figma、Notion,它们的界面全是 Chromium 渲染出来的 HTML,只是外面套了个原生窗口的壳。这个事实一旦接受,一件本来很难的事就塌方式变简单:操作桌面应用,退化成了操作网页。

![Slack/VS Code 等 Electron 应用外壳掀开,里面其实是 Chromium 网页;chrome-use 通过 CDP 远程调试口连上,按钮用 @e1/@e2 元素引用定位而非截图点坐标](https://img.leeguoo.com/media/7f410f6e-6dff-45ec-961b-883a60d54520/electron-hero.webp)

## 桌面自动化本来有多别扭

先说没有这条路的时候,让程序操作一个桌面应用有多难。

一条路是截图、找按钮的像素坐标、点过去。分辨率一变、主题一换、窗口一挪,坐标全错;而且程序"看不懂"界面上是什么,它只看到一张图。另一条路是系统辅助功能 API(macOS 的 Accessibility、Windows 的 UIAutomation),能拿到控件树,但每个平台一套 API,而且 Electron 应用暴露给这套 API 的信息还经常残缺,因为它的"控件"其实是 div,不是原生控件。

两条路都累,而且都绕开了一个事实:这个应用内部明明有一棵结构清晰、带语义的 DOM,你却在外面隔着像素、或者隔着一层转译,去够它。

## Chromium 自带一扇门

因为渲染引擎是 Chromium,Electron 应用天然会说 Chrome DevTools Protocol。启动时带上 `--remote-debugging-port`,它就开一个 CDP 端口,把内部那棵 DOM 直接露出来:

```bash
open -a "Slack" --args --remote-debugging-port=9222
chrome-use connect 9222
chrome-use snapshot -i
```

(每个应用分个不冲突的端口就行,全平台的启动命令文档站有,这里不铺开。)

`snapshot` 拿回来的,是那棵 DOM 的无障碍视图:每个按钮、输入框都是带名字的元素,用 `@ref` 定位。你不是在猜"发送按钮大概在右下角那块像素",你拿到的是那个 `button "Send"` 本身。窗口挪了、主题换了都不影响,因为绑的是元素,不是坐标。对 agent 来说这差别是本质的:它现在能读懂这个桌面应用长什么样,而不是对着一张截图瞎点。

## 一个必须知道的取舍

这里有个和浏览器场景不一样的地方,值得单独说,因为很容易想当然。

操作你日常那个 Chrome 时,chrome-use 走的是浏览器扩展加 native messaging,不碰调试端口,所以没有"是否允许远程调试"的弹窗,也没有 `Runtime.enable` 那类协议层痕迹。但 Electron 应用装不了 Chrome 应用商店的扩展,所以这条路只能走 `--remote-debugging-port`。换句话说,浏览器场景下那些"零痕迹"的优势,到 Electron 这儿是拿不到的,前提就是你自己开一个调试端口连进去。

对自动化 Slack、VS Code 这种"你自己的应用"来说,这完全不是问题:你不是要骗过谁,是要自动化你自己已经登录的工具。但如果脑子里装着浏览器那套"不可检测"的预期跑来操作 Electron,得先把预期调过来:这是"连进自己的应用",不是"隐身操作别人的网站"。

## 一个有意思的细节:应用里还能套应用

Electron 应用内部经常再嵌 `<webview>`,比如 Slack 里打开的某个第三方应用面板,本质是又一个独立网页。这些在 CDP 里是独立的 target。连上后先 `chrome-use tab` 列一下,你会看到主窗口、设置窗口、还有那些 webview 各自是一个 target,可以分别切进去操作。

所以一个 Electron 应用不是"一个网页",是"一叠网页套在一个原生壳里"。想清楚这点,多窗口、嵌套面板这些本来挠头的场景,就都变成了"切到对的那个 target"而已。

## 边界

这套只对 Chromium 内核的应用成立。用 Swift/AppKit 写的纯原生应用没有 CDP 口,连不上,那种还得回到系统辅助功能,或者换别的工具(操作 iPhone 上的原生 app 我用的是另一套)。判断也简单:Slack、VS Code、Discord、Figma、Notion、Spotify 这类"一套代码跑多平台"的桌面应用,基本都是 Electron。

想通"桌面应用其实是网页"之后,我现在看到一个桌面工具,第一反应是先确认它是不是 Electron。是的话,操作它就不再是"桌面自动化"这个我一直觉得很脏的活,而是我已经很熟的那套开网页的办法。

相关文档：[chrome-use · Electron 桌面应用](https://chrome-use.leeguoo.com/electron.html)、[安装](https://chrome-use.leeguoo.com/install.html)。
