告别Alfred、uTools,自研跨平台Launcher的实践之路

发布时间:2026/9/15 0:20:37
告别Alfred、uTools,自研跨平台Launcher的实践之路 我先说一个可能让很多效率工具爱好者不太舒服的结论当你在 Alfred、Wox、PowerToys 和 uTools 之间反复横跳一遍遍搜索快捷键冲突、迁移配置、学习新插件语法的时候真正的问题可能不是工具不够好而是你还没想清楚自己到底需要一个什么样的 Launcher。这句话是我在 Mac 和 Windows 两台电脑上折腾了几年之后才彻底想明白的。中途经历过的崩溃、卸载、重装、再换次数多到我不好意思细数。最后我没有继续等一个“完美工具”而是花了一个多月时间自己动手写了一款只属于自己的 Launcher。如果你也在几个流行启动器之间徘徊或者已经对现有方案产生了一些“说不上来哪里不对”的感觉这篇文章应该能帮你省掉不少弯路。我会把四款主流工具的真实体验、压垮我的四根稻草、自研前的需求梳理以及我从零开始实现一个可用版本的完整路线图都摊开讲一遍包括掉进去的坑。1. 换了一个又一个Alfred、Wox、PowerToys、uTools 的实测横评1.1 AlfredmacOS 上最优雅的“效率图腾”我最早入坑的启动器是 Alfred那时候还在 macOS 上工作。严格来说 Alfred 解决的第一个痛点是 Spotlight 太弱文件搜索慢计算器和单位换算也时灵时不灵。Alfred 的即时反馈、模糊匹配、文件索引快照明显比系统自带的搜索结果更可靠这是它的第一层优势。第二层优势是 Powerpack 工作流。很多人买 Powerpack 其实不是为了搜索而是为了 Workflow——把一连串操作组合成一个关键词命令。比如我可以输入todo 明天交周报它会自动解析时间并把任务写进 Things输入open doc它会直接定位到某个常用目录并打开。这个机制的本质是把“输入意图”和“执行操作”之间的路径压缩到最短这也是我后来自己做 Launcher 时最想保留的核心体验。但 Alfred 的硬伤也很明显。首先是平台绑定它的所有工作流、剪贴板历史、Snippets 都是 macOS 专属的当我切换到 Windows 工作后这些积累直接归零。其次是收费模式Powerpack 属于买断制但版本升级经常要再掏一次钱对一个核心功能可能只用了 30% 的普通用户来说花费并不算低。再就是生态封闭虽然社区 Workflow 很多但高级功能基本只能在它定义的封闭框架里玩想接一个自定义脚本服务要绕不少路。1.2 WoxWindows 下的开源老兵换到 Windows 后我第一反应是找 Alfred 的替代品于是遇上了 Wox。Wox 在当年的 Windows 圈子里口碑很好免费、开源、加上 Everything 插件之后文件搜索速度非常夸张基本做到输入关键词的同时结果已经出来了。那种“手都没完全落在键盘上就搜完了”的感觉确实是 Wox 最吸引人的地方。而且 Wox 的插件系统比 Alfred 更开放Python、C#、JavaScript 都能写插件社区也贡献了不少有用的扩展比如直接搜索 Git 仓库、快速启动 内网工具、剪贴板历史等。当年我还在 Wox 上写过一个自动把选中文本转为 Markdown 链接的小插件至今记得第一次跑通时的成就感。但 Wox 的问题在后半程集中爆发。一是项目维护节奏越来越慢新一代 Windows 对任务栏、UWP 应用、无窗口进程的管理方式变化很大Wox 对很多新款应用扫描不全经常出现明明装了某软件却搜不到的情况二是插件质量参差不齐很多插件年久失修一升级系统就崩三是它的界面交互停在了“老式启动器”的思维里不支持现代动画、不支持深浅色主题平滑切换和 Windows 10/11 的观感越来越不搭。最终我还是把它卸了但“开源插件自由扩展”这颗种子已经种下了。1.3 PowerToys官方出品但启动器只是副业微软的 PowerToys 是我目前仍然保留在 Windows 上的工具因为 FancyZones、取色器、批量改名这些功能实在太好用了。不过要客观说一句PowerToys Run 作为启动器体验处于中等偏上但没有想象中那么完美。PowerToys Run 的打开速度和基础搜索稳定性都值得肯定尤其是对 Windows 系统设置项的覆盖输入声音能直接跳到对应设置页输入卸载能弹出软件管理列表这种系统级集成的深度是第三方启动器很难做到的。它也支持插件但插件生态的丰富度远不如 Alfred 或 uTools基本停留在“适用于开发者”的层次普通用户能感受到的扩展能力很弱。更关键的问题在于定位PowerToys 是一个“系统工具合集”Launcher 只是其中的一个边角功能。所以你会发现它的迭代优先级经常被窗口管理、颜色管理这些模块压住启动器层面的细节打磨明显不够。比如搜索结果的排序策略比较死板中文分词支持一般快捷键和候选框的配置项很少自定义动作脚本的能力约等于零。对我来说它是一把“瑞士军刀”但启动器这把刀片并不是它最锋利的那一面。1.4 uTools插件生态最强但离“原生”最远后来在团队推荐下用上了 uTools这个工具让我真真切切感受到“插件生态”的力量。翻译、JSON 格式化、图片压缩、颜色拾取、二维码生成、正则调试……一个启动器可以同时替代十几个零散的桌面小工具这种整合感确实很爽。uTools 在 Windows、macOS、Linux 全平台可用账号体系能同步部分数据对多设备用户也很友好。可以说 uTools 是几个工具里最接近“效率平台”定位的但也是我最终放弃它原因最集中的地方。首先底子是 Electron启动速度和常驻内存明显比原生应用高一个量级在配置一般的办公电脑上尤其明显。其次插件质量太依赖社区很多插件功能看着全实际运行起来要么要联网要么弹广告要么在特定分辨率下界面错乱。再就是隐私问题uTools 需要登录账号才能使用完整功能插件数据也会经过它的云服务中转对于部分内部项目信息我已经到了不敢往里放的程度。我并不是否认 uTools 的价值而是它走了一条“大而全”的路这种路线和我想要的“快速、原生、可掌控”已经越来越远。于是在某个周五晚上我又一次因为 uTools 插件崩溃导致无法呼出主界面之后终于决定不再等别人了。2. 决定自研前的四个引爆点跨平台、隐私、生态与快捷键2.1 跨平台工作流割裂让我双倍维护配置我的通勤场景是家里一台 Windows公司一台 Mac。四款工具我用下来最痛苦的不是单个产品不行而是它们之间的工作流完全无法迁移。Alfred 的 Workflow 出了 macOS 一碰就碎Wox 的插件在 macOS 上根本不存在PowerToys Run 又是 Windows 专属uTools 倒是有跨平台生态但它的账号体系和云同步也把很多本地数据带出去了。这种割裂意味着同一个操作我在两个系统上要记两套快捷键、两套插件语法甚至两套模板片段。时间一长我发现自己对效率工具的信任度反而在降低——因为关键时刻我根本想不起来该用哪个键呼出哪个功能。跨平台一致性是我自研清单里的第一条刚性需求。2.2 一个本地启动器为什么要往云端传数据做技术的人对数据出本机会有天然的敏感。很多 Launcher 为了同步配置、统计热词、提供在线插件服务会把用户在本地的搜索行为、打开过的文件路径、剪贴板内容送到云端。剪贴板里经常躺着密码、临时验证码、源代码片段这些东西经过第三方服务器中转不管对方承诺多安全我都觉得不合适。你可能觉得“又没人看你”但企业环境里合规审计会看账号被盗后黑产也会看。我不愿意把自己的日常工作轨迹绑定在一个不透明的黑盒里所以自研方案从一开始就定死了默认不联网所有索引和配置都保存在本地文件插件如果需要联网必须由我自己逐行审查过代码后才允许放行。2.3 每换一个工具就要重新学一套插件机制Alfred 的 Workflow 用 plist 和 Bash/AppleScriptWox 的插件可以选 Python 或 C#PowerToys Run 的插件是 C# 项目uTools 则是把插件打包成 upx 格式、前端的写法。四套机制之间不说毫无关系至少也是互不兼容。我花在每个工具上的学习成本已经远远超过它们实际给我节省的时间。我真正想要的插件机制特别朴素定义一个可执行程序或脚本输入一段 JSON输出一段 JSON主程序负责把用户的输入准备好、把结果渲染出来。至于脚本本身用什么语言写Python、Shell、JS 都无所谓。这样我就可以用自己最熟的 Python 快速搞定一个“查待办事项”的小动作而不需要为了某个平台去额外学一套工程结构。这个想法成了后面整个插件协议设计的原型。2.4 快捷键肌肉记忆的冲突是最不值得浪费的精力我用过的四款工具里Alfred 默认是CtrlSpace后来我改成OptionSpaceWox 是AltSpacePowerToys Run 是AltSpaceuTools 是AltSpace但国行版本又兼容了双击 Ctrl。听起来差不多但换来换去之后我的肌肉记忆彻底乱了。经常在 Mac 上习惯性按AltSpace结果呼出的是系统 Spotlight 和输入法切换器在 Windows 上按CtrlSpace又把输入法给切了。到了这个阶段我发现所有现成工具都在强加一套“它认为正确的快捷键逻辑”而我想要的是某种完全统一的、可由我任意定义的全局热键规则。这种控制欲后来变成了驱动自研计划的最直接动力。3. 自研 Launcher 的三个硬性需求清单在动手写代码之前我花了一整个周末把需求“降噪”到了最核心的三条。3.1 本地优先数据完全离线所有输入历史、文件索引、自定义动作、插件配置全部存成纯文本或 SQLite 文件放在本机。主程序启动时不访问任何远程接口也不做任何遥测上报。唯一的例外是某些插件明确需要外部服务比如翻译、天气但这类插件的启用必须通过一个显式的本地配置文件授权绝不默认开启。这一点直接决定了我对技术栈的偏好尽量选用内存占用低、打包体积小的方案不带一套完整浏览器的壳。3.2 同一套快捷键、同一套配置跨平台生效我希望 Mac 和 Windows 用同一份配置文件描述“按下OptionSpace后做什么”。快捷键、主题、插件路径、动作模板都从一份同名配置里读取两端的实现只有系统适配层不同。为了做到这一点我在设计交互协议时把所有平台相关的部分都收敛到最底层上层逻辑只处理“用户输入 - 匹配动作 - 渲染结果 - 执行动作”这一条链。3.3 插件即脚本任何人用 20 行代码就能接入插件协议简单到我敢让非程序员同事也用上一个插件就是一个文件夹里面放着plugin.json描述这个插件叫什么、接受什么参数、由哪个命令启动命令启动后主程序把用户输入作为标准输入写给它它把结构化结果作为标准输出返回。换句话说插件就是一个“吃进字符串、吐出 JSON 的小程序”。这个小约定成了我的 Launcher 里生命力最顽强的部分我用它接了一堆奇奇怪怪的内部工具从查工时到发周报模板都有。4. 首版落地方案Tauri 主程序、全局热键与 JSON 插件协议4.1 技术栈选型为什么我没有再次选择 Electron如果你用过 uTools就会理解我对 Electron 的犹豫内存占用动不动 300MB 起步、冷启动要等白屏、在不同缩放比例显示器之间切换时窗口偶发模糊。这些都和 Launcher 的核心体验背道而驰。我最终选择了 Tauri 2.0它的前端渲染层直接使用系统自带的 WebView后端是 Rust打包体积只有几 MB常驻内存能控制在 60MB 以内冷启动基本可以做到悄悄驻留后台、呼出时立即显示。Tauri 在生命周期里给了我很舒服的体验全局快捷键可以在 Rust 侧注册UI 层用 HTML/CSS 做深夜党喜欢的深色界面权限模型默认就支持“只暴露哪些本地能力给前端”这种细粒度控制。这也帮助我满足了“本地优先”的原则——绝大部分能力都锁在 Rust 主进程里前端只负责展示结果。4.2 全局热键与主界面弹出的实现思路Launcher 的第一个核心机制是“无论你在干什么按下约定的快捷键它得立刻铺到屏幕上”。在 Windows 上我用了RegisterHotKey这类系统级热键注册 API在 macOS 上则用了全局事件监听并过滤 KeyDown 事件。这里有一个重要细节全局热键和普通窗口快捷键不一样它必须绕过当前前台应用的输入法上下文。按OptionSpace呼出窗口后我会立刻让候选框获得焦点同时把输入法强制切成英文模式避免你敲出来的第一个字被输入法吞进去。然后我把输入框的内容实时分流给后端一部分走模糊匹配的“应用/文件/网址索引”另一部分走插件协议去问各个脚本“这个输入你能处理吗”。4.3 搜索索引从应用搜索到文件搜索应用搜索相对简单遍历系统已知的已安装应用清单并提取名称、图标、可执行路径。我额外把它做成了一份本地缓存表每隔 5 分钟检测一次新增和卸载变化保证你刚装的软件马上就能搜到。文件搜索是最容易被人低估的部分。我没有走全盘索引那么重的路线而是采用了“指定目录列表 增量快照”的策略只索引用户配置的几个工作区目录比如docs、downloads、projects并把目录修改时间记录下来。每次用户按下快捷键时后台线程会快速核对哪些目录的 mtime 变了只更新变化的部分。这样既能搜到日常真正需要定位的文件又不会让索引库膨胀成庞大的数据库。4.4 动作系统与脚本插件机制我制定的plugin.json形态大概是这样的{ name: snippet, description: 把选中文本变成链接格式, match: link , command: [python3, main.py], keep_open: false }当用户输入以link开头的内容时主程序会把整条输入通过 stdin 传给python3 main.py脚本解析输入后输出一行 JSON{ result: { title: [文本](url), prepend: [文本](url) } }主程序拿到result后可以直接把它回填到输入框或者一键复制到剪贴板。整个数据链路没有任何前端框架参与纯命令行交换稳定且调试容易。我后来还在动作系统里加了“通配符替换”机制。比如我配置了一个动作输入todo 买牛奶它会先匹配到todo前缀再把买牛奶推给一个待办记录脚本脚本把内容追加到本地inbox.md。这个动作在 Alfred 里做要写 Workflow在 uTools 里要装插件而在我自己的 Launcher 里只需要一段十几行的 Python。5. 跑通后的真实体感、翻车记录与复盘5.1 首版完成后的意外收获第一个版本虽然界面简陋但我在实际使用中立刻感受到了几个意料之外的好处。首先是启动速度所谓“一按即出”的感觉是真实存在的。由于主进程常驻内存窗口显示只做了非常轻量的 WebView 渲染所以从按下快捷键到看到候选结果几乎零等待。和 uTools 在冷启动时的白屏感完全是两个世界。其次是自由度我把“常用命令”“剪贴板历史”“快速打开工作区目录”“查 IP 地址”“JSON 格式化”“一键打开所有开发相关页面”全部按自己习惯做成了动作组。从现在开始不是我去适应工具而是工具按我的工作流来长。这个正反馈特别强让我有动力继续迭代。5.2 性能优化与兼容性调试中的关键教训自研不是只有爽踩坑也踩得够多。我在首版之后用了大概两周时间来修兼容性问题这里挑几个典型的记录一下。第一个坑是 Windows 下 DPI 缩放导致窗口定位错位。开发机上 150% 缩放没问题换到外接显示器 100% 缩放时候选框位置会偏离鼠标或偏离屏幕底部。后来我明白必须用物理像素坐标而不是逻辑像素坐标来定位窗口并且要监听WM_DPICHANGED事件在跨屏拖动时动态调整窗口大小。第二个坑是全局热键冲突。AltSpace在我的 Windows 上居然和某远程会议软件的快捷键撞了结果两个软件同时弹窗。解决方式也很经典热键注册失败时不能静默放弃必须在系统托盘弹一条警告并允许用户打开设置面板重新绑定。这个机制越早做越好不要等用户喊“为什么呼不出来”的时候才慌。第三个坑是索引目录过大导致内存暴涨。最开始我不小心把整个用户目录都加进了索引结果索引库瞬间跑到 2GB启动时要做大量 IO 读取。后来我学乖了在做 mtime 快照的同时加上对常见文件类型扩展名的过滤并且把索引更新放到空闲时间片执行。最终索引库被压缩到 200MB 以内对使用体感基本没有影响。5.3 哪些现成经验值得继续保留自研到第三周我反而开始理解那些大而全的 Launcher 为什么做不出原生手感了因为它们既要兼容海量插件生态又要处理各种系统的边界情况就不得不牺牲一部分响应速度和稳定性。而自研的优势在于你可以只为你自己的工作流做剪裁把 80% 的复杂性挡在门外。这才是 Launcher 工具最迷人的地方——它本质上不是软件是你个人电脑操作方式的镜像。另外如果你也想尝试自己做一个启动器我给你的建议是先从“快捷键弹窗 应用搜索 固定几段脚本动作”开始不要一上来就设计海量插件系统和云同步。Launcher 的起点是快速唤起终点是顺手高效中间那些花哨功能都是后话。做完这个项目之后我最大的收获其实不是代码本身而是对自己操作习惯的重新认识哪些操作是高频、低成本的哪些操作是假性高频、只存在于想象里的。这种认知会让你以后再用任何第三方工具时都能更快判断它到底值不值得装。如果你手里也已经积压了各种不顺手的效率工具也许下一把钥匙就在你的键盘旁边自己动手做一个小东西不一定要多完整但一定要先跑起来。