dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
会话头部的电源按钮,两个动作,都需再点一次确认。重启结束的是 Electron 主进程本身(taskkill /F 不带 /T),因此不会出现崩溃弹窗;宿主在 IPC 断开后自行优雅退出,分离的 helper 等单实例锁释放后重放同一可执行文件,并以真实窗口句柄确认新实例已启动。关闭同理但不重新拉起。上一轮残留的 GPU 与渲染器进程会被尽力清理。仅 Windows 桌面版。
你是不是也受够了? 😤
装个插件——重启。卸个插件——重启。改行配置——还是重启。
一晚上下来插件没装几个,任务管理器倒是熟得像自己家 🏠
本鲸鱼小姐也是受害者 🐋💢 每次都要在一堆 node.exe 里大海捞针,捞错了把别的东西干掉,捞对了又忘了当初那行命令是啥……
于是气不过,自己写了一个 🔨
右上角多一枚电源键 🔘
点一下,DSH 进程真的没了 💀;再点一下,它真的又爬起来了 🧟
不是location.reload()🙅 不是router.refresh()🙅 更不是「转两圈假装重启好了」那种糊弄学 🎭
是这个进程真的从任务管理器里消失,然后一个新的它站起来 💪
而且不弹那个吓人的「宿主停止」框了 🎉 —— 这版专门把这个坑填了,下面有交代。
装插件 🧩、改配置 ⚙️、调 patch 🩹 之后,DSH 十次有八次来一句:「重启一下才生效哦~」
然后你就开始了这套祖传行为艺术 🎪:
node.exe 里猜哪个是 DSH(纯玄学)dsh web,端口又变了,浏览器地址失效一套下来十五分钟没了,插件还没生效 🙃
最气的是什么? 你只是想卸载一个插件而已 😑 结果为了「让卸载生效」,你得先把自己这个正在用的 DSH 干掉。 ……等一下,那我卸载完拿什么重新打开它?🤡
dsh-power-switch 就是为这一刻写的 ✍️ 把这一整套压缩成两次点击 👆👆(第二次是防误触,它有点礼貌,不是啰嗦)
会话头部右侧多一枚小电源图标 ⚡,不抢位置、不遮最小化 ➖ / 隐藏 👻 / 关闭 ❌ 那组窗口按钮(这点我盯得很死,谁也别想挤到它们)
点开是个小菜单,里面只有两个按钮,干干净净:
按钮 · 干了什么 ⚡ 重启 · 结束整个 DSH(含桌面主进程),随后自动拉起一个全新的 🔁 ⏻ 关闭 · 结束整个 DSH,不自动拉起,安静地走 🌙
两个按钮都要点两次 👆👆: 第一次是「你真的想好了吗 🤨」,第二次才是「好,动手 🔨」
老版本会弹这个:
Error: dsh desktop host stopped: ...新版本不会了 ✅ 因为这次杀的是桌面主进程,不是宿主子进程。
道理很直白 🧾:
剩下的收尾由宿主自己完成: 主进程一死,宿主那边的 IPC 通道就断了,宿主监听着 disconnect, 于是它自己走一遍正常关闭流程(会话日志好好落盘 📝),然后安静退出 😴
🔑 一句话记住:以前杀的是「儿子」,爸爸在旁边看着当然要哭;
现在直接把「爸爸」请走,全家一起安静退场 🤐
方案 · 结果 只杀宿主子进程(老版本) · ⚠️ 功能没问题,但主进程必然报一次「宿主停止」 退出码设 0 想骗过它 · ❌ fail() 的两个分支都触发,文案从「exited」变「stopped」而已 想设 stopping 标志 · ❌ 那是主进程私有状态,插件够不到 找 IPC 白名单走正门 · ❌ 只认 ready / shutdown-complete / platform-session / fatal,没有重启入口 杀主进程(不带 `/T`) · ✅ 本次方案:没人能弹窗,宿主自己优雅退出 杀主进程带 /T · ❌ 会连宿主一起强杀,宿主来不及落盘,等于拔电源 🔌
那个 /T(连同子进程)看着更彻底,其实是坑 —— 不带它才是对的 🙅
四段接力,没有任何魔法:
process.pid / process.ppid / process.execPath 现场问出「我是谁、我爸是谁、我是被哪个 exe 启动的」,不猜 profile 🙅 不写死 路径 🙅
detached 的 helper。它不在任何进程树里,所以父进程死光它也活着taskkill /PID /F—— 注意没有 `/T`,只杀主进程本身
→ 用原 exe 拉起新实例 → 确认它真的画出了窗口 → 收拾上一轮残留 → helper 自己退出
为什么必须等干净?因为 Electron 有单实例锁(requestSingleInstanceLock)🔒旧主进程没退利索就 spawn 新的,新实例会发现自己不是「老大」,直接 quit() 自杀 ——我实测过,369 毫秒就没了 💀 快到你以为它起来了,其实连窗口都没开。
所以 helper 会重试最多 5 次,每次间隔 3 秒 —— 手慢不要紧,起来就行 😌
环境变量要清干净 🧹:拉起前会把 ELECTRON_RUN_AS_NODE 和 DSH_DESKTOP_NODE_EXECUTABLE 删掉。 不删的话新实例会以 node 模式启动 —— 进程是起来了,但没有窗口,等于白起 🙃
这是这一版最较真的地方。
老版本判活:spawn 完等 5 秒,进程还在就算成功。 问题是 —— 进程在、窗口没画出来,这种半死不活的状态它照样报「重启完成」🙃 你对着一个没有窗口的任务管理器发呆,那才叫真尴尬 😑
现在查 MainWindowHandle,真的见到窗口才算数,最多等 30 秒,等不到就杀掉重来。
还有个细节 🧐:MainWindowHandle 有时查不到 —— PowerShell 没跟上、查询超时、权限抖动。 这种状态我记为 unknown,它不等于失败: unknown 就继续等,超时了只要进程还活着,就当它起来了。
宁可少杀一次,也别因为探测不到就把好好的实例打掉 🔪
新实例窗口出来之后,会清掉上一轮剩下的进程(GPU / 渲染器 / 插件后台)。
这里我自己先踩了一脚 😵 一开始按「孤儿」定义清理 —— 结果 helper 本身也是用 DeepSeek Harness.exe 跑起来的, 启动时间还更早,第一刀就把自己砍了 🔪 日志里 restart complete 后面干干净净,reap: 一行都没有,我才反应过来。 (所以你现在在老日志里看不到那行,是这么没的,不是我偷懒 😤)
现在判据是启动时间:新实例整棵树都晚于新主进程,按时间切绝对安全; 并且显式排除 process.pid(自己)。
这也算 best effort 🤷♀️ 渲染器偶尔粘着不走,不保证 100% 清空,但正常情况下够用了。
同一条路,只是最后不 spawn。主进程走人 → 宿主优雅退出 → 结束 🌙
旧页面跟着旧进程一起消失了,刷新它没有意义 🙅 点完按钮就显示「正在关闭 / 正在重启」,然后等页面自己断线。 新实例起来是个新的地址、新的页面,从桌面应用或启动器进去就行。
如果十几秒后页面还活着 —— 说明那一下没生效,它会老实告诉你「没反应,再点一次?」🤔
POST,跨站一律 403插件市场里搜 电源 🔌 / power ⚡,或者:
dsh plugin add dsh-power-switch装完重启一次 DSH(对,就用它自己 😏 第一次得手动,之后就不用受这罪了)
POST,跨站请求一律 403 🚫DeepSeek Harness.exe 拉起新实例dsh web / node bin.js 启动的宿主:没有 Electron 主进程,就直接结束宿主自身(这种形态本来也不会弹框)
GET /dsh-power-switch/api 的 facts / restartable 字段如实自报(它不会撒谎)Q:重启后还弹「宿主停止」吗? 😰