Skip to content

Releases: xiaolu511/dsh-hot-restart

v0.3.17 — 重启之后,窗口会自己回来 🔄

Choose a tag to compare

@xiaolu511 xiaolu511 released this 01 Nov 09:07

🔄 重启更完整

  • 重新拉起时带上原始启动参数:以前只拉 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.17

spec 要带准确版本号:刚发布的版本 24 小时内会被 DSH 的供应链策略跳过,按名字装会停在 0.3.16。
装完重启一次 DSH 才生效。

v0.3.16 — 自检看得见、还快了 3 倍 ⚡

Choose a tag to compare

@xiaolu511 xiaolu511 released this 12 Oct 13:24

⚡ 自检从 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 — 修掉「能关闭但拉不起来」🩹

Choose a tag to compare

@xiaolu511 xiaolu511 released this 12 Oct 12:52

🩹 就绪握手

  • 助手先报「我准备好了」:助手校验完 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 — 内置自检系统 + 重启提速 ⚡

Choose a tag to compare

@xiaolu511 xiaolu511 released this 12 Oct 12:25

🔍 自检系统

  • 按钮右键菜单:「自检并生成诊断报告」/「复制诊断信息」/「查看版本」
  • 出错自动自检:重启请求被拒时、点了变灰的按钮时、宿主发现「上一次启动是失败的」时
  • 助手也会自检: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 搞崩 🩹

Choose a tag to compare

@xiaolu511 xiaolu511 released this 12 Oct 05:27

🩹 事故修复

  • 优雅关闭优先:先 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 — 独立工具与备用派发 🧰

Choose a tag to compare

@xiaolu511 xiaolu511 released this 12 Oct 05:05

🧰 独立重启工具

  • 不再写死外壳 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 — 助手确认活着之前,绝不杀外壳 🛡️

Choose a tag to compare

@xiaolu511 xiaolu511 released this 12 Oct 04:52

🛡️ 安全闸

  • 派发助手后先等它往日志写第一行 [relaunch],等不到就换 PowerShell 助手再试
  • 两条路都不吭声时直接放弃重启并返回可读的错误,而不是先把 DSH 关掉

📌 背景

  • 用户日志里五次重启尝试没有一行 [relaunch]:助手在他机器上根本没跑起来,
    而 wscript.exe //B 是静默模式,外壳照样被杀掉,只留下一个消失的 DSH。

v0.3.8 — 「关掉了但没起来」的防线 🪤

Choose a tag to compare

@xiaolu511 xiaolu511 released this 12 Oct 04:22

🪤 防线

  • 宿主改成 taskkill /F /T,连整棵进程树一起收(后来在 0.3.11 里撤回,理由见那一版)
  • 助手:清掉外壳残留的子进程;端口若仍被占用,只结束属于自己这套栈的进程;启动后确认新实例真的起来了
  • 起不来时依次改走 ShellExecute、cmd start 再试;全部失败就弹窗告诉用户手动打开 DSH
  • PowerShell 兜底助手同步补上这几层

v0.3.7 — 分清「已安装」与「运行中」🔀

Choose a tag to compare

@xiaolu511 xiaolu511 released this 11 Oct 15:09

🔀 版本可见性

  • status.json 同时报两个版本:version 是磁盘上装的那份,runningVersion 是此刻真正在跑的宿主模块
  • 两者不一致时,按钮提示和弹窗直接写明「已安装 vX,运行中的宿主还是 vY:重启一次 DSH 才会生效」

📌 背景

  • 有用户装好新版本但没重启 DSH,宿主仍在跑旧模块,于是又看到旧版本才会出现的原因码。

v0.3.6 — 外壳判定不再依赖某份构建的启动标记 🎯

Choose a tag to compare

@xiaolu511 xiaolu511 released this 11 Oct 15:02

🎯 判定

  • 不再要求宿主 argv 里有字面量 dsh-desktop-host(那只是某一份构建的写法)
  • 改为看父进程本身:不是 Electron 的 --type= 子进程、不是终端或解释器,且 exe 名字像 DSH 应用
  • 判定规则抽成纯函数并加进单测:六种真实构建写法各一条用例