返回公众号历史文章目录

文章 / 公众号历史文章

烧了100美元Token、被AI"骗"了两天,我终于把浏览器插件的一键安装做成了

pro+版本烧完后,再升级Ultra版本, 连续三天,每天50美刀token用量 一个只有1M多的安装器,前面是我跑了无数弯路、被老旧AI知识带到沟里、试了Playwright被100M体积吓退,最后用UIA方案死磕出来的战绩。做AI编程Skill这件事,我玩真的。 一、前面的推文写出去,其实有个硬

pro+版本烧完后,再升级Ultra版本,

连续三天,每天50美刀token用量

公众号文章插图

公众号文章插图

一个只有1M多的安装器,前面是我跑了无数弯路、被老旧AI知识带到沟里、试了Playwright被100M体积吓退,最后用UIA方案死磕出来的战绩。做AI编程Skill这件事,我玩真的。


一、前面的推文写出去,其实有个硬伤

网页浏览器,才是离你最近的“超级开发平台”——一个Skill让零基础用户也能开发浏览器插件

上一次我写文章介绍浏览器插件Skill——读者反馈很好,但我心里清楚,那篇文章有一个我没明说的话:

那个“双击bat安装”的方案,我其实还没完全跑通。

不,准确地说,我在自己的设备上跑通了。但要把它做成一款“给任何人拿去都能一把过”的工具——这中间差着一道我当初低估了的天堑。

那篇文章里我写道:

“不需要打开Chrome开发者模式,不需要点’加载已解压的扩展程序’,不需要翻墙去Chrome商店,不需要5美元注册费。双击安装包就完事。”

每一个字,都是我真心想达成的目标。但真正要交付到读者手里、要让他们一键安装成功,这条路我走了整整两天,烧掉了一百多美元的 API token 用量,试错了无数方案,才最终打通。

今天就跟你聊聊这两天的故事。


二、Chromium 的安全限制:一道被全世界 AI 都搞不清楚的墙

事情是这样的。

我想做的是一个安装器:用户双击exe,自动识别你电脑上的Chrome或Edge浏览器,自动打开扩展程序页面,自动点击“开发者模式”开关,自动点击“加载解压缩的扩展”,自动跳出文件夹选择框,自动填入扩展路径,自动点击“确认”——整套流程一气呵成,用户只看到进度条走了几步,就告诉你装好了。

听起来不难对吧?不就是浏览器自动化吗?Selenium、Playwright这些老牌工具不都是干这个的?

问题来了:Chrome 的安全策略。

Google 对 chrome://extensions/ 页面做了极其严格的安全限制。常规的 Playwright 或 Selenium 的 CDP(Chrome DevTools Protocol)会话,在导航到这个页面时——直接被拒绝。你拿不到页面元素,点不了按钮,操作不了 UI。

这不叫“页面不好解析”,这叫“整个交互接口被封死”。

然后我就开始问各个 AI 怎么办。

ChatGPT 说:“用 CDP 的 Runtime.evaluate 注入 JS”。不行,页面直接拒绝。

Claude 说:“用 --disable-web-security 参数启动浏览器”。不行,Chrome 新版本这个参数只在测试模式有效,而且 extensions 页面依然拦着。

Gemini 说:“用 chrome.debugger API”。那个 API 是你自己写插件去操控浏览器的——我现在连插件都没装上,哪来的 API 可用?

**最要命的是,这些 AI 给你的回答都特别自信。**每一个都说“你可以这样做”“按照这个方案一定行”。你照着做一遍,炸了;换一个方案,又炸了;再换一个,还是炸。你以为是自己参数没配对,一遍遍调,一遍遍试,烧了几十块钱 token,回到原地——才发现是他告诉你的路根本走不通。

这就像当年做嵌入式遇到硬件 bug:文档里写着“支持”,芯片上的寄存器就是不动。你信了文档,折腾了两天,最后发现是芯片的勘误表没更新。

AI 的知识有滞后。而且这个滞后,在安全策略这种“谷歌经常改”的领域,特别致命。


三、Playwright方案:100M的巨兽,我用不起

中间一度,我换了一个思路。

Playwright 虽然 CDP 会话直接访问 chrome://extensions/ 受限,但它提供了 “Persistent Context” 模式,可以挂载一个本地用户数据目录来启动浏览器——这样浏览器启动时,插件跟着配置目录一起加载,不需要经过“手动安装”的 UI 流程。

我当时兴奋地觉得找到路子了:用 Playwright 挂载浏览器配置,然后把插件文件夹复制进去,再修改 Preferences 和 Secure Preferences JSON 文件,最后启动浏览器——理论上插件就应该出现了。

我甚至还真的在某些浏览器上跑通了。

但问题像俄罗斯套娃一样冒出来:

  1. 每个浏览器的配置格式不一样。 Edge 在 Secure Preferences 里用的是 “state”:1,Chrome 可能是 “mode”:“developer”,360 浏览器又是一种写法。写死一个浏览器的逻辑,换个浏览器就崩。

  2. 安全签名校验。 Chrome 会对 Secure Preferences 做 HMAC 校验。你手动改了 JSON,浏览器检测到被篡改,直接丢弃你的修改,甚至重置整个配置文件。

  3. 配置冲突。 如果你挂着配置打开两个浏览器实例,Profile 被锁,启动失败。

  4. 体积。 这个最要命。Playwright 带一个完整的 Chromium 运行时,发布成单文件 exe 后,安装包至少 100M。而我的目标是:一个轻量工具,随插件一起分发,最好控制在几M以内。

100M 的安装器,给一个可能只有几十K的插件当安装包?

不优雅。太不优雅了。

这条路我走了近一天,烧了将近 40 美元的 token。最后在一个深夜,我盯着那个 107M 的 build 文件夹,决定推倒重来。


四、UIA——最后的救命稻草,也是最终的答案

重来之前,我重新思考了这个问题的本质。

核心矛盾是什么?Chrome/Edge 的 extensions 页面是一个 Web 页面,但它的 DOM 不对外开放。 意味着你不能用 Web 自动化那套思路去打它——什么 document.querySelector、page.click(),全都不好使。

那如果我不走 Web 自动化呢?如果我不把它当网页,而当做一个 Windows 原生窗口呢?

对——Windows UI Automation(UIA)。

UIA 是微软做的一套桌面无障碍框架,可以让你遍历操作系统上任何窗口的 UI 元素树。不管这个窗口肚子里嵌的是原生控件、WPF、还是 Chrome 渲染的网页——UIA 看到的都是统一的 AutomationElement 节点。

Chrome 虽然不让 Playwright 碰 extensions 页面的 DOM,但它拦不住 UIA 在操作系统层面查看窗口里的按钮。

一下子,所有的死胡同都通了:

  • 不用 CDP,不用 WebDriver,不用 Playwright → 包体积从 100M 降到 1M+
  • 不用改浏览器配置文件,不用跟 HMAC 校验斗智斗勇 → 直接走 GUI 操作流程
  • 不用每个浏览器写一套配置逻辑 → 一个 JSON 配置文件,定义了 Edge、Chrome、360、搜狗、QQ、UC、夸克、豆包、千问……近十种浏览器的 UI 元素识别特征

五、UIA 方案的实现:麻雀虽小,五脏俱全

说干就干。我用 .NET 8 + WPF 写了一个精巧的安装器程序,项目名叫 BrowserProfileExtensionInstaller。

它干了什么?

启动后,程序自动扫描你电脑上正在运行的浏览器进程。不像 Playwright 那样要自己下载一个内置浏览器——UIA 安装器直接调起你本机的 Chrome 或 Edge,不额外带任何浏览器运行时。

然后给你一个下拉框,列出所有检测到的浏览器和配置。你点一下,剩下的全自动:

  1. 把 extension 文件夹复制到系统固定目录

  2. 打开 chrome://extensions/ 页面

  3. 用 UIA 在窗口 UI 树里找到“开发者模式”开关,点一下打开

  4. 用 UIA 找到“加载解压缩的扩展”按钮,点一下

  5. 弹出的系统文件夹对话框——UIA 继续接管,自动导航到目标目录,填进去,点“选择文件夹”

  6. 完成。插件已经出现在浏览器扩展页里了。

全程 UIA 在操作系统层面直接操控窗口控件,不看 DOM,不看网页元素,不碰 CDP。Chrome 的安全限制对它来说形同虚设——因为 Chrome 根本不知道有人在动它的按钮。

支持多少浏览器?

browser-config.json 里写死了:

浏览器 适配方式
Microsoft Edge 原生 UIA + 中文界面控件名
Google Chrome 原生 UIA + 中/英文控件名
360 极速 / 安全浏览器 自动探测安装路径
搜狗浏览器 自动探测安装路径
夸克浏览器 自动探测安装路径
UC 浏览器 自动探测安装路径
豆包 / 千问等 AI 工具 内嵌 Chromium 窗口,独立适配

而且每一种浏览器的“开发者模式开关”在 UI 树里的名字、“加载解压缩”按钮的文字,连文件夹对话框的标题,都被精细化地一一标注。

你知道这意味着什么吗?意味着以后你换个浏览器、换个电脑、甚至换个中文/英文系统——只要 browser-config.json 里写了对应的 UI 特征,安装器就能找到正确的按钮。

不止是浏览器——AI 时代的必备工具,也能装

留意到表格最后一行了吗?豆包客户端、千问客户端——这两个是当下 AI 时代几乎人手一个的工具。它们的桌面客户端本质上是 Chromium 内核套壳,内置了扩展程序页面。

这意味着什么?

你在豆包里问 AI 写了一段代码,想直接验证——可以在豆包客户端里装一个即时运行插件。

你在千问里做文献调研,想一键高亮、翻译、导出——可以在千问客户端里装一个辅助阅读插件。

这不是“浏览器插件”了,这是**“AI 工作台的增强层”。**

传统思维里,插件只能装在 Chrome/Edge 这些“正经浏览器”里。但 UIA 方案不受此限制——只要内嵌了 Chromium 内核,有扩展管理页面,安装器就能干活。

这不叫 Hack,这叫工程化封装。


六、但 UIA 这条路也不好走——两天踩过的坑

别以为 UIA 方案一上来就通。我踩的坑,比前两种方案加起来还多。

坑1:UIA 树太大,查找元素太慢

浏览器窗口的 UI 元素树动辄几千个节点。如果你每次都从头遍历整棵树——慢得让你怀疑人生。我最后做了分层级缓存:先缓存窗口根节点,再按 AutomationId / Name / ControlType 的分层匹配策略快速定位,查找时间从秒级降到毫秒级。

坑2:不同浏览器的同一个按钮,名字不一样

Edge 叫“开发人员模式”,Chrome 叫“开发者模式”,英文版叫“Developer mode”。那个“加载解压缩扩展”按钮,Chrome 写“加载已解压缩的扩展程序”,Edge 写“加载解压缩的扩展”,千问写“加载已解压的扩展程序”——各种变体。

解决思路:多模式匹配。browser-config.json 里每种按钮都配了多个候选名称,中英文全写、缩写全写、标点变体全写,做成字典式匹配。

坑3:XAML 资源绑定引用了不存在的颜色名

一个 PrimaryTextBrush 的资源名称写错了,编辑窗口一打开整个程序闪退。排查花了三个小时——因为异常发生在 XAML 编译后的 InitializeComponent() 调用里,堆栈信息非常模糊。最后是靠打日志,逐行定位到那一行 <SolidColorBrush Color="{StaticResource PrimaryTextBrush}">。

坑4:一个“好看一点的图标”引发的血案

说出来你可能不信——这个坑,纯粹是因为我“想好看一点”。

程序默认的图标太丑了,我就想换个精致点的,于是找了个 64×64 的 ico 替换上去。结果换完图标,exe 双击直接没反应了。

就加了一张图片而已!

排查过程极为煎熬:先怀疑是 MainWindow.xaml 里 Icon 路径写错了,查了一遍没错;又怀疑 .csproj 的 ApplicationIcon 配置有冲突,试了各种写法都无效;再怀疑是 XAML 资源加载阶段出了问题,打了一堆日志也没抓到明显异常。

谁能想到——最后发现是那个 ico 文件本身的问题。 某些“长得像 ico 的图片文件”,其实内部格式不是标准的 ICO 编码。WPF 在初始化阶段解析这个图标时,直接底层报错,连 try-catch 都兜不住,窗口还没构造完就崩了。

一张图片,折腾了几个小时。

但这个坑也没白踩。 我顺手把这些踩坑经验全部沉淀进了 Skill 的参考文档里——以后 AI 给任何人生成 WPF 程序时,Skill 会自动约束它:图标走标准 .ico 格式、XAML 静态资源全部预先声明、窗口初始化链路上必须有最外层异常兜底。你永远不会遇到“换个图标程序就崩了”这种诡异问题——因为我替你踩过了。

坑5:已存在的浏览器窗口识别

用户打开安装器的时候,浏览器可能已经在跑了。UIA 如何知道页面上那个“加载解压缩”按钮在哪里?如何判断“开发者模式”是开是关?——这些状态判读,全部依赖运行时 UIA 遍历。代码里写了大量的条件分支和容错逻辑。


七、两种方案的终极对比

对比维度 Playwright 方案(中间态) UIA 方案(最终版)
发布包大小 100M+(自带Chromium运行时) **1M+**(纯.NET 8单文件发布)
安装方式 改浏览器配置文件 + HMAC签名绕过 操作系统GUI自动化
稳定性 不同浏览器格式不同,容易崩 UIA元素树遍历,适配层解耦
浏览器支持 最多3~4种 10种+,可配置扩展
依赖 Playwright + Chromium .NET 8 Desktop Runtime(大多数Win11自带)
对Chrome安全限制 绕不过去 从操作系统层面绕过

1M 对比 100M。这是工程思维的胜利。

精益求精、工匠精神——不只是写代码写得好,更是在方案选择上敢于推翻自己、敢于推倒重来、敢于迎着最难的那条路走下去。


八、这套方案到底是什么?——一种“黑科技”路线

聊到这儿,我必须坦诚地跟你交个底:这套 UIA 方案不是什么“官方推荐”的路径。

恰恰相反,它属于那种——在官方封死了所有正规通道之后,你自己拿着图纸在墙上重新找缝撬的方案。

官方给我们的是什么?

Google 和微软对浏览器插件的安装只给了两条“正道”:

正道一:Chrome / Edge 应用商店。 开发者付 5 美元注册,提交审核,等 1-3 天,审核通过后用户翻墙去商店搜索下载。这条路的门槛对普通用户来说高到离谱——且不说国内 Chrome 用户大部分没翻墙、没登录浏览器账号,光是一个“注册开发者”就已经筛掉了 99.9% 的人。你只想给自己的浏览器装个小插件方便办公,为什么要先成为一个“注册开发者”?

正道二:开发者模式手动加载。 打开浏览器→找到扩展管理页面→打开右上角的“开发者模式”开关→点“加载已解压缩的扩展程序”→在弹出的系统文件夹选择框里手动导航到插件目录→点“选择文件夹”。这一套操作对程序员来说不叫事,但对普通办公用户——光是听到“开发者模式”四个字就劝退了。谁会觉得自己在“开发”什么东西?他们只是想要一个按钮而已。

这就是官方的态度: 你要么走商店(翻墙+付费+审核),要么走开发者模式(手动+术语劝退)。没有第三条路。没有“一键安装”。

而 Google 这些年还在不断收紧安全策略:CDP 会话被系统页面拒绝、Secure Preferences 加了 HMAC 签名校验、--disable-web-security 参数持续弱化……他们在堵每一个可能被绕过的口子。初衷是安全——没错,恶意插件确实危险。但结果是什么?普通人完全被挡在了插件生态的门外。

我做的事:在墙上找到一条缝,然后撬开了它

Chrome 封死了 Web 自动化访问 chrome://extensions/ 页面 DOM 的通道。但它封的是“门”,封的是“窗”,封的是浏览器框架内部的通道。

它封不了操作系统。 Windows 操作系统比你浏览器跑得更底层。浏览器窗口在 Windows 眼里,跟一个计算器窗口、一个记事本窗口没什么区别——都是带 UI 控件的窗口而已。

所以我的思路其实很简单,也很“野蛮”:

你 Chrome 不让我从浏览器框架里面动你的按钮?那我就从 Windows 操作系统外面动你的按钮。

UIA 框架进入你的窗口,遍历你的 UI 树,找到你的按钮,点击它。整个过程,你的浏览器浑然不觉——它只以为是用户在操作鼠标键盘。

这就是“黑科技”的本质:在官方规则之外,用更底层的通用能力,把死路走通。

这有点像什么呢?就像官方给你发了一台路由器,说你只能用他们给的 APP 来配置。你发现 APP 很难用,很多人用不了。你一怒之下,拿 telnet 连上了路由器的底层端口,直接发了配置命令。路由器不知道你不是官方 APP——命令格式对就行。

这不是破解,不是 hack,不是针对安全机制的攻击。这是在你完全有权限操作的 Windows 桌面上,用一种 Chrome 没防到的角度,完成了一个完全合法的操作——安装你自己的插件到你自己的浏览器。


九、最终成果:一个让你“哇”出来的体验

公众号文章插图

现在这个 Skill 的完整使用流程是:

你:“帮我做一个浏览器插件,在百度搜索结果里高亮已经访问过的链接。”

AI:分析需求 → 搭建项目 → 写代码 → 构建打包 → 生成安装器 →把安装器和插件一起交付给你。

你:双击 BrowserProfileExtensionInstaller.exe → 选你的浏览器 → 等几秒 → 完成。

打开百度搜个东西——已经访问过的链接自动变了颜色。

没有命令行、没有 Chrome 商店、没有翻墙、没有开发者模式的手动开关、没有手动选择文件夹。

AI 替你做了所有那些你“不想学、不想碰、不想知道”的事。你只负责描述需求,和最后享受结果。


十、免费开放,欢迎体验、欢迎打赏、欢迎加好友

从 VBA Skill 到 Python Skill 到多维表格 Skill 到浏览器插件 Skill——我把这条路走通了。

不是“理论上可以”,不是“在某些条件下可以”,而是实打实的:在我的电脑上用各种浏览器跑通了,在你的电脑上也可以用同样的流程一把过。

这套 Skill,全部免费开放。 你拿去用,直接让 AI 给你写浏览器插件,马上就能装。我这两天的弯路你一步也不用走——因为我把坑全填平了,把路全铺好了,固化在了 Skill 的规则和脚本里。

如果你觉得:

  • 这 100 美元的 token 烧得值得
  • 两天时间死磕一个 1M 的工具值得敬佩
  • 放弃 100M 的 Playwright 方案、推倒重来值得尊重
  • 把一道“所有人都说做不了”的墙推倒值得赞赏

请不要客气,狠狠打赏。 我不用设固定金额——你自己觉得值多少,就打赏多少。打赏是一种认可,不是入场券。你的每一笔打赏,都是对“工匠精神”的一次投票。

也欢迎加我好友,进入我的免费社群。 群里你可以:

  • 亲自体验:一句话让 AI 写一个浏览器插件,双击自动安装
  • 看到其他群友怎么用这套 Skill 做出各种意想不到的东西
  • 提出你的需求,我来帮你想方案
  • 第一时间拿到新 Skill 的内测资格

这个社群的入场券只有一个要求:你对“用 AI 增强你的日常工具”这件事感兴趣。


写在最后

这两天走下来的感受只有一句话:

真正难的事,不是你不知道怎么做。而是你被一些“看起来能行”的方案一遍遍地带到沟里,烧了钱、熬了夜、推翻了无数次,最后在不被看好的那条路上——自己亲手走通了。

Chrome 的安全限制是一堵墙。Playwright、Selenium、CDP,都是墙这边的人告诉你“应该能翻过去”的梯子——但它们不够高。

UIA 是一扇门。只是之前没人告诉你门在哪里。

现在,我找到了这扇门。而且把它做成了一个 1M 的钥匙,交到了你手里。

拿去用,别客气。


想体验浏览器插件 Skill?想亲眼看看 1M 的安装器怎么一把过?欢迎评论区留言,也欢迎加我好友进入免费社群,直接上手玩一把。

如果你觉得这段经历值得肯定,打赏随意——感谢你的每一次认可。