Repository navigation
Replies: 3 comments
|
确认了:这是 Shell 端的优雅退出门槛,旧 Host 过不去。
Host 侧现在是 所以老版本自更新是单行道:手动跑已下载的安装包(在更新器缓存里),或先升到 rc.1+ 再走内置更新。rc.3 的 我读的是 master 的代码,没跑你那台机的更新。 |
|
这条和 #13214 是同一条更新链路上的两个相邻断点,方向互补,建议合并看:
源码上两者紧邻。 740 requireCleanStop = true
742 await Promise.all([backend.stop(), stopOperationReports()])
743 updateStoppedHost = true
746 if (stopFailure !== undefined) throw new DesktopUpdatePreparationError('stop-failed', ...)
747 await operationJournal?.drain(500)
749 shellInstallerOwnsQuit = true
而 // apps/desktop/src/update-coordinator.ts:218
this.updater.quitAndInstall(true, true)
// → BaseUpdater.quitAndInstall():
// const isInstalled = this.install(...) // 同步 spawn NSIS
// if (isInstalled) setImmediate(() => this.app.quit())所以顺序是「clean stop 通过 → spawn 安装器 → app.quit() → 四个进程退出 → 安装器早已在改名」。静默模式( 完整的根因、实测数据和双向修复建议见 #13214 的补充评论: 结论:只把 Host 的 clean stop 做扎实不够,还需要让安装器的 spawn 发生在 |
|
这条补充对:我只讲了 stop-failed,没讲安装器起跑后的占用。 anylink 说的顺序我核了: 所以上一轮那句“老 build 单行道”只覆盖 stop-failed 一种;rc.1+ 上 #13214 的 error 5 窗口还在(安装器改名时目录仍被占用)。 两处可以分开修:stop 失败重试/降级;spawn 前等 app 退出,或让安装器等 Restart Manager 清锁。 我读的是 master 的代码,没跑安装器。 |
Uh oh!
There was an error while loading. Please reload this page.
[Windows/Desktop] 内置更新在“停止 Host”阶段失败:旧版 Host 退出慢被 SIGTERM,Shell 判定非干净退出而拒绝安装
TL;DR(English)
On Windows, the in-app desktop update fails at the "stop the Host" step. The Shell gives the Host process 10 s to exit after the Host acknowledges shutdown, then sends SIGTERM and refuses to install because the exit was not graceful (
exit null, signal SIGTERM, shutdown acknowledged true, graceful deadline exceeded true). Older nightly builds (0.2.1-rc.2 and 0.2.1-rc.5) do not forceprocess.exit()aftershutdown-complete, so a leaked handle can keep the Host alive past the deadline. Result: those builds can never self-update from the GUI — a one-way door — and users must quit the app and run the already-downloaded installer manually.0.2.2-rc.1and currentmasteralready forceprocess.exit()inapps/desktop-host/src/index.ts, but the Shell-side refusal is unchanged, so the dead end remains for anyone still on an older build.环境
app-update.yml: providergeneric,https://download.deepseek.com/dsh-desk/feeds/win-x64/)D:\software\DSH(非默认安装目录)0.2.1-rc.2→ 待装0.2.1-rc.3(2026-10-27)②
0.2.1-rc.5→ 待装0.2.2-rc.1(2026-11-13)现象
点击“安装并重启更新”后弹出:
“查看技术详情”展开为:
update-info.json记录一致,Authenticode 签名有效(Hangzhou DeepSeek Artificial Intelligence Co., Ltd.),FileVersion 与目标版本一致。复现步骤
update-tasks确认没有活动任务后进入停止阶段:向 Host 发shutdown。shutdown-complete(所以shutdown acknowledged true),但进程本身在 10 秒内没有退出。SIGTERM强杀,进程以exit null / signal SIGTERM结束。DesktopHostUncleanExitError→stop-failed→ 拒绝安装并弹窗。同一台机器、两个不同版本对上各复现一次(2/2)。
代码定位
Shell 侧(
apps/desktop/src/host-process.ts,DesktopHostProcess.stop()):graceful === false且exitCode === null(SIGTERM 的结果)时,即使shutdownCompleted === true,也一定会抛错并拒绝安装。Host 侧(
apps/desktop-host/src/index.ts的stop()):旧构建(
0.2.1-rc.2、0.2.1-rc.5)在disconnect()之后没有process.exit(),完全依赖 Node 事件循环自然退空。任何被插件/运行期留下的未释放句柄(子进程、socket、watcher、native thread 等)都会让进程一直活着,正好撞上 Shell 的 10 秒死线。根因判断
这是一个“旧版本无法自更新”的单向门:
0.2.2-rc.1(以及当前master)已在 Host 侧加入process.exit()(注释原文:“A handle a disposed plugin left open would otherwise keep the Host alive past the shell's graceful deadline”),我在这台机器升级后的app.asar里核对确认该行存在;0.2.1-rc.5的 bundle 中确认不存在。也就是说 Host 侧问题在新版已修,但 Shell 侧的 10 秒硬超时 + 拒绝安装逻辑在master中没有变化,旧版本用户依然过不去。影响
建议
shutdownCompleted === true时,把“SIGTERM 后退出”视为可接受(至少提供“仍然安装”确认),而不是直接stop-failed;或者在收到 ack 后再给 30–60 秒宽限并重试一次。shutdown-complete之后、process.exit()之前,用环境变量开关打印process._getActiveHandles()/_getActiveRequests()摘要,方便定位残留句柄。0.2.2-rc.1”的版本区间给出明确的手动升级指引。变通方法(已验证)
DeepSeek Harness进程;%LOCALAPPDATA%\@deepseek-aidsh-desktop-updater\pending\deepseek-harness-<version>-win-x64.exe(本机为
C:\Users\Mec\AppData\Local\@deepseek-aidsh-desktop-updater\pending\deepseek-harness-0.2.2-rc.1-win-x64.exe)0.2.2-rc.1。附:证据
C:\Users\Mec\AppData\Local\@deepseek-aidsh-desktop-updater\(pending/update-info.json、pending/*.exe、current.blockmap)exit null, signal SIGTERM, shutdown acknowledged true, graceful deadline exceeded true0.2.2-rc.1):swcK0J6ofGkaAWLRpOes2ca7CWO8vuM5Vp0FRnQ/DG3q+Z+OhvsgLz3hIiSYpRUETY+fEz+Ww86fNa0jiVIifw==,与本机update-info.json一致,签名有效All reactions