- 홈
- 플러그인
- 개발 및 플러그인 도구
- dsh-tray-restart
dsh-tray-restart
aaayeaaa-p1ws/dsh-tray-restart
Adds a Restart item to the DeepSeek Harness desktop tray menu, patching the app's tray template in place and re-applying the patch after desktop updates.
설치
dsh plugin --profile web add github:aaayeaaa-p1ws/dsh-tray-restartREADME
dsh-tray-restart
npm 包名:
@aaayeaaa-p1ws/dsh-tray-restart(dsh-tray-restart这个无前缀名字被别的作者先占了)
给 DeepSeek Harness 桌面端的托盘右键菜单加一条 「重启 DeepSeek Harness」。
DSH 桌面端的托盘图标右键原本只有「打开 / 退出」两项,改了插件想重载、或者开久了想重开,只能退出再双击一次图标。装上这个插件,菜单里就多一条「重启 DeepSeek Harness」:
打开 DeepSeek Harness
重启 DeepSeek Harness ← 新增
─────────────
退出 DeepSeek Harness
点击后走的是 Electron 主进程自己的重启写法(app.relaunch() + 静默退出),关掉再起来,和手动重开完全一样,但不用管图标和窗口。
安装
插件市场(推荐):在 DSH 的「插件市场」里搜 tray-restart,点安装,然后重启一次 DSH。
命令行:
dsh plugin add @aaayeaaa-p1ws/dsh-tray-restart
或者直接从 GitHub 装(还没发版时用):
dsh plugin add github:aaayeaaa-P1WS/dsh-tray-restart
本地 link(开发用):
// ~/.dsh/profiles/desktop/package.json
"dependencies": { "@aaayeaaa-p1ws/dsh-tray-restart": "link:C:/path/to/dsh-tray-restart" }
装完重启 DSH,右键托盘图标就能看到「重启 DeepSeek Harness」。
菜单是 DSH 启动时建好的一次性对象,所以装完必须重启一次 DSH 才会出现,之后每次启动都自动补丁。
工作原理
托盘菜单写死在桌面端 Electron 主进程的 resources/app.asar → lib/main.js 里:
tray.setContextMenu(Menu.buildFromTemplate([
{ label: messages.openApplication, ... },
{ type: "separator" },
{ label: messages.quitApplication, ... },
]));
插件跑在 Host 子进程里,拿不到 Electron 的 Menu/Tray,主进程的 IPC 协议也没有「加菜单项」这种消息——所以只能在归档层面动手:
- 读出 asar 头,定位
/lib/main.js的字节区间; - 把其中
//#region lib/types/tray.js整段等长替换,在「打开」和「退出」之间插一条{ label: "重启 " + messages.aboutProduct, click: () => { app.relaunch(); quitWithoutConfirmation(); } }; - 用空格补齐到与原段完全相同的字节数,整个
main.js长度不变,asar 头里的 offset/size 全部继续有效; - 写完
fsync并回读比对,不一致就报错并保留备份。
标签用 "重启 " + messages.aboutProduct 拼出来(显示为「重启 DeepSeek Harness」),和另外两条同格式,跟随产品名和界面语言,不写死中文。
安全性
- 等长替换:写入前后都校验字节数,绝不改变归档结构;写后回读比对。
- 先备份:第一次打补丁前把原始
main.js存到~/.dsh/tray-restart/main.js.orig。 - 认锚点,不乱动:
main.js里找不到quitWithoutConfirmation()、或者这段代码的形状变了(应用升级),就不动手,只写日志。 - 升级自动补回:桌面端自动更新会覆盖
app.asar,插件每次启动会检查一次,发现没有补丁就自动补上。 - 可一键还原:调用工具
tray_restart_status(restore: true)或用备份把原始main.js写回去。
工具
插件注册了一个工具 tray_restart_status:
| 参数 | 作用 |
|---|---|
| (无) | 查看当前补丁状态、asar 路径、main.js 大小、备份位置 |
apply: true | 立刻检查并打补丁(幂等) |
restore: true | 用备份还原原始菜单 |
日志:~/.dsh/tray-restart/log.ndjson。
限制
- 仅 Windows 桌面端:托盘菜单在 Windows 的 Electron 主进程里,Web 版 / macOS / Linux 没有这段代码,插件会自动跳过(不影响启动)。
- 依赖 DSH 桌面端版本:补丁按
0.2.2-rc.1的lib/main.js锚定,package.json里dsh.engines.dsh声明为>=0.2.2-rc.1。之后版本如果改了这段形状,插件会报anchor-mismatch并保持原样,等适配后再发版。 - 应用更新后补丁会被覆盖,但下次启动会自动补回(也可以在更新后立刻调一次
tray_restart_status,传apply: true)。
开发
git clone https://github.com/aaayeaaa-P1WS/dsh-tray-restart.git
主要文件:
index.js— 插件入口:启动时检查/补丁、注册tray_restart_status工具lib/tray-patch.mjs— asar 读写、锚点识别、等长替换、备份/还原cordis.patch.yml— Cordis bundle 补丁(把插件插进 profile)
打补丁只做文本级等长替换,不依赖任何运行时依赖;node --check 可通过。
English
Adds a Restart item to the DeepSeek Harness desktop tray menu (Windows), next to Open and Quit.
The tray menu is built once, at startup, inside the Electron main process (resources/app.asar → lib/main.js). Plugins run in the Host child process and cannot reach Electron's Menu/Tray, so this plugin patches the asar byte-for-byte: it replaces the whole //#region lib/types/tray.js block with an equal-length copy that inserts { label: "Restart " + messages.aboutProduct, click: () => { app.relaunch(); quitWithoutConfirmation(); } }. Same length ⇒ the asar header stays valid; the original main.js is backed up first, the write is verified by read-back, and the patch is re-applied automatically after a desktop update.
Restart DSH once after installing for the menu to appear. Windows desktop only; DSH desktop >= 0.2.2-rc.1.
License
MIT