Repository navigation
Releases: xiaolu511/dsh-hot-restart
Releases · xiaolu511/dsh-hot-restart
Release list
v0.3.17 — 重启之后,窗口会自己回来 🔄
🔄 重启更完整
- 重新拉起时带上原始启动参数:以前只拉 exe,
--no-sandbox、自定义--user-data-dir
这类参数会在每次重启后悄悄丢掉。现在助手直接读外壳进程的CommandLine,
只替换可执行文件那一段,其余原样透传,不重新拼引号 - 带上用户真实的环境变量:助手是经 WMI 派发的,手里那份环境是 WmiPrvSE 的,不是用户的。
宿主现在把必要变量写成快照交给它(用户目录、PATH、代理、DSH_*;名字里带
TOKEN/SECRET/PASSWORD/KEY 的一律跳过),所以自定义DSH_HOME不会再丢 - 拉起方式改成直接启动:wscript 自己没有控制台,可以直接拉起 DSH 并继承上面那份环境;
WMI 保留为兜底 —— 当年必须用 WMI 是因为启动器是 PowerShell(控制台程序)
🪟 窗口自己回来
- 重启后 DSH 窗口会自己出现,不用再点托盘。实测(EnumWindows 观察日志)外壳建好主窗口后
一直把它藏着,页面就绪了也没人显示它,只能靠用户点托盘图标 —— 看起来就像「重启后没起来」 - 显示时机选在页面真正画好之后:早显示会露出一帧 Electron 白底,而且外壳两秒后还会把它藏回去,
用户看到的就是「白闪一下又没了」 - 等待期间屏幕上不弹任何东西:不显示空白窗口、不弹等待面板
🪟 按钮挪进标题栏
- Windows 桌面壳里,按钮从主区域左下角挪到窗口右上角、最小化按钮左边:贴着系统窗口按钮更顺手,
也不压正文内容(40px 标题栏内居中,右侧留出 Electron 画的三个原生按钮 138px + 8px 间隔) - 标题栏整条是拖动区,所以给按钮加了
-webkit-app-region:no-drag,照样点得动 - 全屏没有标题栏,退回左下角;纯浏览器打开(
dsh web)保持原来的左下角 - 来源:社区 PR #3,感谢 @xiangjian9998
⚡ 更快
- 强杀前的身份核对加上 1.2 秒上限:原来会一直等那次 PowerShell 往返(这台机器上约 3 秒),
实测「开始优雅关闭 → 强杀」之间白等 4 秒
🧪 测试
- 新增 30 多条断言:环境快照存在且不带密钥、快照按 UTF-16 读写、命令行从 WMI 取、
WMI 那条也改用还原后的命令行、直接启动优先于 WMI、窗口显示脚本必须用EnumWindows
且任何非注释代码都不许用MainWindowHandle、等待面板已移除
📦 安装 / 升级
桌面客户端让 Agent 执行 plugin_manager 的 install_bundle,target 写准确版本:
dsh-hot-restart@0.3.17
web profile 走 CLI:
dsh plugin --profile web add dsh-hot-restart@0.3.17spec 要带准确版本号:刚发布的版本 24 小时内会被 DSH 的供应链策略跳过,按名字装会停在 0.3.16。
装完重启一次 DSH 才生效。
v0.3.16 — 自检看得见、还快了 3 倍 ⚡
⚡ 自检从 29 秒压到 9 秒
- 五条派发探针默认不再实跑:每条都要真的起一个脚本宿主进程,杀毒软件会拦、会弹授权窗口,
在被拦的机器上这一步能磨二十多秒 —— 恰好是「自检很慢」的主因 - 端口枚举改成先查一次进程表:原来每个连接查一次 WMI,几十个连接就是十秒
- 路由探测不再写死端口(43120 那种空端口,探两次白等四秒)
🔍 默认模式改成「读策略」
- 新增「安全环境」一节:Windows Script Host 策略、PowerShell 生效执行策略、
已安装的安全软件、Defender 受控文件夹访问 / ASR、AppLocker - 这些查询只读、在进程内完成、不创建任何进程,所以不会触发杀软授权窗口
- 想拿实测证据时:
tools\diagnose.cmd -DeepProbe再跑一次
📊 进度看得见,还能取消
-
自检时屏幕正中弹一张小卡片(不是全屏遮罩 ✗):进度条 + 「第 N/8 步:在干什么」 + 已用秒数
-
进度由脚本一步步写出来,页面每 0.7 秒读一次;跑完自己消失并给出报告完整路径
-
带取消自检按钮:点一下宿主会把那个脚本进程连同探针子进程一起收掉
-
卡住会说清楚:12 秒还一步没走,就提示「像是被安全软件挂住了」,
并给出手动路线tools\diagnose.cmd(那样授权窗口会正常弹出来)
📌 背景 -
主人反馈「点完自检一片安静,不知道它动没动」,而且怀疑是杀软在弹授权
v0.3.15 — 修掉「能关闭但拉不起来」🩹
🩹 就绪握手
- 助手先报「我准备好了」:助手校验完 exe 路径与凭据之后才写
helper ready,宿主必须等到这一行才敢关 DSH。
以前只要助手往日志写一行就算通过 ✗ —— 于是助手明明报了 ABORT,宿主照样把 DSH 关掉,
用户看到的就是「DSH 消失了、没回来」 - 助手报 ABORT 时绝不关 DSH:三条派发通道都不就绪就直接放弃这次重启,
弹窗里原样带上助手给出的原因
🌏 中文路径
- 借 Explorer 派发时用的包装脚本改成 UTF-16LE + BOM。原来按 ASCII 写盘,
装在C:\Users\-\新建文件夹\这类路径下会被毁成乱码
(实测新建文件夹→苞圅9,与用户报告里那行一字不差),助手因此拒绝动手
📋 报告可读性
- 自检报告读
restart.log时改用 UTF-8:以前按默认编码读,宿主写的中文路径在报告里显示成乱码,
看起来像插件本身坏了
📌 背景
- 一台纯净无插件的机器上,WMI 创建进程被安全策略挡住;插件退到 Explorer 通道后,
又因为上面的编码问题没能把 DSH 拉起来。这份报告是自检系统第一次实战,四条证据一次到手
🔒 编码合同(防回归)
- 新增编码合同测试:非 ASCII 的
.ps1必须带 UTF-8 BOM、.vbs/.cmd必须纯 ASCII,改坏了直接变红 - 新增中文路径金丝雀:用产品自己的写法生成包装脚本,真的交给 wscript 跑一遍,
确认新建文件夹这类路径原样送达(当年就是它变成苞圅9,害得 DSH 关闭后没起来)
v0.3.14 — 内置自检系统 + 重启提速 ⚡
🔍 自检系统
- 按钮右键菜单:「自检并生成诊断报告」/「复制诊断信息」/「查看版本」
- 出错自动自检:重启请求被拒时、点了变灰的按钮时、宿主发现「上一次启动是失败的」时
- 助手也会自检:DSH 被关掉之后只有助手还活着 —— 它启动新实例失败、或者新实例起来 12 秒内又死了,就自动生成报告并弹窗
- 报告位置会明确报出来:脚本把路径写进 last-report.txt,页面显示完整路径,助手弹窗里也带着同一个路径
- 自检脚本
tools/diagnose.ps1加双击入口tools/diagnose.cmd,全程只读,报告写到桌面并用记事本打开 - 报告里有什么:结论速览、派发能力矩阵(五条通道各自报「进程建了没 / 还活着吗 / 脚本产出了没」)、环境、全部进程命令行、插件文件与哈希、市场锁是否卡死、上次启动停在哪个阶段、GPU 崩溃次数、端口、路由、完整 restart.log
⚡ 重启提速:56 秒 → 14 秒左右
- 修掉
taskkill /PID undefined:那条「优雅关闭」从来没生效过,每次重启都在白等助手兜底 - 等待循环里的存活判断从「同步起一个 PowerShell」换成
process.kill(pid, 0)(前者把等 3 秒拖成了 10~45 秒) - 优雅关闭只给 1 秒:DSH 有托盘,WM_CLOSE 只会把它收进托盘
- 强杀之前的身份核对与等待并行,不再串在关键路径上
- 外壳探测移出启动路径,改成挂载后空闲预热
- 助手兜底等待从 25 秒收紧到 10 秒
- 剩下约 7 秒是 DSH 自己启动,插件动不了
🛡️ 防止误杀
- 宿主与助手在强杀之前都会核对exe 路径 + 创建时间,而不只看 PID —— Windows 会复用 PID 值
🧊 界面与提示
- 重启冷却 5 秒;冷却被拒不再自动自检,弹窗语气变成「稍等一下再试」
- 被拒之后立刻撤掉遮罩,不再留着「正在热重启 DSH…」的画面
- 同一份诊断报告只提示一次,手工跑的报告不推给用户
📦 安装 / 升级
- spec 要带准确版本号(刚发布的版本 24 小时内会被 DSH 的供应链策略跳过),装完重启一次 DSH 才生效
v0.3.11 — 不再把用户的 DSH 搞崩 🩹
🩹 事故修复
- 优雅关闭优先:先
taskkill不带/F(等于发 WM_CLOSE),让 DSH 正常收尾、写完状态、释放文件锁;
最多等 12 秒,还在才强杀 - 绝不加
/T:整棵树一起收会连带杀掉正在写状态的子进程,那正是留下state.json.lock的原因 - 凭据通道:宿主派发助手前写下
restart-ticket.json,放弃重启时删掉它;
助手动手前必须确认凭据还在且新鲜,否则只写一行日志、什么都不碰 - 独立工具
tools\restart-dsh.vbs同步改造:优雅关闭优先、带凭据、失败即撤销
📌 背景
- 之前反复用
taskkill /F硬杀,打断了 DSH 写desktop-market/state.json,留下state.json.lock;
那把锁记的是持有者 PID,PID 一旦被别的进程复用就永远不会自己释放 —— DSH 之后每次启动都等锁超时,
直接进恢复模式。已经卡住的锁只能人工删除。
v0.3.10 — 独立工具与备用派发 🧰
🧰 独立重启工具
- 不再写死外壳 exe 名(原来找
DeepSeek Harness.exe,别的构建叫DSH Desktop.exe时它只会说「没在运行」) - 不再「先杀再等」:等助手的
[relaunch]日志,等不到就换 PowerShell 助手,两条都不吭声就只提示、不动手 - 端口不再写死 19387,改为从外壳的子进程占用的监听端口里探出来
🚚 备用派发
- 新增一条不经过 WMI 的路:借已经跑着的 Explorer 打开包装脚本,脚本运行在 Explorer 的进程树下
- 派发时把实际发送的命令行原文写进日志,并记下最终生效的派发方式
- 确认助手活着不再只认日志:派发回来的 PID 还活着同样算数
🩹 其他修复
- 修掉按 UTF-16 下标切字节的 bug:日志含中文时会切到旧内容,把没启动的助手误判成已启动
- 助手确认「新实例起来了」时不再把 Electron 的渲染/GPU 子进程算进去
- 新增安全自检开关:
restart-dsh.vbs --check与restart-dsh.ps1 -Check只编译不动手
v0.3.9 — 助手确认活着之前,绝不杀外壳 🛡️
🛡️ 安全闸
- 派发助手后先等它往日志写第一行
[relaunch],等不到就换 PowerShell 助手再试 - 两条路都不吭声时直接放弃重启并返回可读的错误,而不是先把 DSH 关掉
📌 背景
- 用户日志里五次重启尝试没有一行
[relaunch]:助手在他机器上根本没跑起来,
而wscript.exe //B是静默模式,外壳照样被杀掉,只留下一个消失的 DSH。
v0.3.8 — 「关掉了但没起来」的防线 🪤
🪤 防线
- 宿主改成
taskkill /F /T,连整棵进程树一起收(后来在 0.3.11 里撤回,理由见那一版) - 助手:清掉外壳残留的子进程;端口若仍被占用,只结束属于自己这套栈的进程;启动后确认新实例真的起来了
- 起不来时依次改走 ShellExecute、
cmd start再试;全部失败就弹窗告诉用户手动打开 DSH - PowerShell 兜底助手同步补上这几层
v0.3.7 — 分清「已安装」与「运行中」🔀
🔀 版本可见性
status.json同时报两个版本:version是磁盘上装的那份,runningVersion是此刻真正在跑的宿主模块- 两者不一致时,按钮提示和弹窗直接写明「已安装 vX,运行中的宿主还是 vY:重启一次 DSH 才会生效」
📌 背景
- 有用户装好新版本但没重启 DSH,宿主仍在跑旧模块,于是又看到旧版本才会出现的原因码。
v0.3.6 — 外壳判定不再依赖某份构建的启动标记 🎯
🎯 判定
- 不再要求宿主 argv 里有字面量
dsh-desktop-host(那只是某一份构建的写法) - 改为看父进程本身:不是 Electron 的
--type=子进程、不是终端或解释器,且 exe 名字像 DSH 应用 - 判定规则抽成纯函数并加进单测:六种真实构建写法各一条用例