用 Go + Wails 给 DeepSeek Harness 做了个 Windows 桌面壳,首次运行自动配好环境
先说痛点
DeepSeek Harness(dsh)的图形界面是要开浏览器用的:
$ dsh web
dsh web: http://127.0.0.1:3388/?token=a1b2c3d4e5f6...
每次都得敲命令、复制那串带 token 的地址、粘到浏览器。而且这个地址是一次性的——dsh 重启就换,所以做快捷方式也没用。
DSH Desktop 就是替你把这件事做完的:双击图标,1.5 秒后界面直接出现。
不用敲命令、不用复制粘贴、不会挂着一个黑窗。关掉窗口只是收进托盘,托盘右键才真正退出。
最省事的点:不用先装环境
市面上同类封装基本都要求你先自己 npm i -g @deepseek-ai/dsh。这个不用。
全新机器上你只需要 exe 本体。 第一次启动会走一个四步向导:
| 步骤 | 做什么 |
|---|---|
| 1 · 检测 Node | 列出本机所有 Node(不是只取 PATH 第一个),逐个跑版本 + 运行时探针 |
| 2 · 检测 dsh | 枚举所有安装位置,并实际执行一次 dsh --version 确认能用 |
| 3 · 确认端口 | 默认 3388,实时检测占用并显示是哪个进程,可一键结束或另选端口 |
| 4 · 启动 | 展示最终选定的组合,确认后拉起 |
缺什么当场装上,装的是便携版 Node、不需要管理员权限,删目录即卸载。每一步都是"检测 → 报告 → 按需安装 → 复检",已经满足的直接给绿勾可以跳过。
配置好了之后,以后每次双击就是秒开。
它不碰你已有的环境
这是我很在意的一点:
- 已经有可用的 dsh → 直接用,什么都不装
- 有 Node 没有 dsh → 装到那个 Node 自己的全局目录,和你的其他全局包放一起
- 只有向导下载的便携版 Node → 才装到应用私有目录
全程不写系统 PATH、不改动任何已有安装。
其他特性
- 后台无黑窗 —— dsh 和内部命令全部以
CREATE_NO_WINDOW运行,任务管理器里看不到黑窗 - 退出不留孤儿 —— 两层保障:正常退出走进程树清理;崩溃或被强杀由 Windows Job Object 兜底带走 dsh
- 不碰你的 Key —— 代码里没有读取、存储或转发任何模型凭据,key 由 dsh 自己管(在
~/.dsh/) - 状态可见 —— 启动页实时显示
dsh web的输出;dsh 意外挂掉时自动拉回启动页并给「重试」,不留死页面 - 托盘菜单 —— 显示窗口 / 在浏览器中打开 / 重新加载 / 重启 dsh / 环境设置 / 退出
适合谁
- 在用 dsh、但嫌每次开浏览器麻烦的人
- 想给不熟悉命令行的同事装一个"点开就能用"的版本
- 想把任何跑在
localhost上的 Web 服务包成桌面应用的开发者 —— 仓库里 SameSite 踩坑、Job Object、托盘实现、无黑窗这些都有完整记录和可复现的诊断脚本,可以直接参考
交代一下技术栈和边界
- 技术栈:Go 1.21+ / Wails v2 / WebView2,MIT 协议
- 平台:只做 Windows 10/11 x64(WebView2 运行时一般已内置)
- Node 要求 ≥ 22.14 —— 这不是我定的,是 dsh 需要
import.meta.main。低于这个版本(尤其 22.0~22.13)dsh 会零输出静默退出,看起来像装坏了,所以向导会直接拦下来 - 目前没做:跨平台(macOS/Linux)、自动更新、多语言界面
下载
- GitHub:https://github.com/Echosong/dsh-desktop-go
- Gitee(国内访问快):https://gitee.com/hn-1024_0/dsh-desktop-go
也可以自己编译:
git clone https://github.com/Echosong/dsh-desktop-go
cd dsh-desktop-go
wails build -clean
需要 Go 1.21+、Wails CLI v2.9+、gcc(MinGW-w64)。注意必须用
wails build,go build不会把前端资源打进 exe。
关于"这算不算重复造轮子"
坦白说,dsh 的桌面封装已经有几个很成熟的项目了,Star 数比我高一个量级,功能也更全。
我做这个的出发点不太一样:开发过程中踩到的坑,比成品本身更值得留下记录。
wails.localhost 和 127.0.0.1 是两个不同 site 导致 Cookie 不回传、302 绕不过去、GUI 进程里执行 netstat 会疯狂闪黑窗、JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 才是崩溃场景的唯一解——这些东西散落在各个 issue 里,但很少有人完整写一遍。
所以这个项目的定位是技术参考实现:功能够用,重点是那些坑和解法都有据可查、有脚本可复现。
如果你正好在做类似的事,希望能帮你省掉那两天。
问题、建议、想加的功能,都欢迎提 Issue。

浙公网安备 33010602011771号