fix(installer): Windows 一键安装器加磁盘空间闸,不足时就地拦下(dev-board#350) - #689
Merged
Conversation
以前 AwdUpdateSpace 只把可用空间显示成「可用 X GB」,不足照装不误:NSIS 在解压 中途报「Error opening file for writing」,用户拿到一个残缺安装。 闸放在 AwdInstallClick 里、$INSTDIR 定下来之后(用户可能刚在「自定义安装」里换过盘): 不足则弹提示说明「需要约 X.X GB / 该盘可用 Y.Y GB」,并把展开行的可用空间标签染红, 不进安装页。 所需空间不手抄数字:桌面端在 installer.nsh 里接 electron-builder 的 APP_64_UNPACKED_SIZE——打包时对 win-unpacked 整个目录(含 backend/jre/python/ frontend dist/skills 等 extraResources)实测的解包体积,KB,由 makensis 命令行 -D 传入, 在生成脚本第一行就存在(与 $launchLink/StdUtils 那批晚到的东西不同)。拿不到就 !error 编译失败,不静默少一道闸。余量 512MB:ARM64 壳覆盖层约 260MB(不在上面那个数里) + 解压临时占用 + 不把盘塞到 0 字节。 三条刻意的保守选择: - **读不出可用空间一律放行**(空串/0/非数字都算读不出来)。宁可让 NSIS 自己在解压时 报错,也不能因为一次读盘失败把装得下的用户挡在门外——闸设得过严比不设闸更糟。 - 引擎侧整套代码在 !ifdef AWD_UI_REQUIRED_KB 内,插件端安装器(装一份清单)不设闸, 编译产物一字节不变。 - 静默安装(/S,自动更新)不进 GUI 代码,这道闸对它不生效,那条路的失败处理归更新器管。 NSIS 地雷已按 eng-infra 的记录处理:FileFunc 的 GetRoot/DriveSpace 会踩调用方 $0-$2 (历史上把窗宽写成剩余 GB),所以 AwdReadFreeSpace 进出各 Push/Pop 一次、结果只落 Var;GB 文案自己算一位小数,取整会把「差 1.9 GB」显示成「差 1 GB」。顺手修一个会 自己造出来的陈旧态:AwdUpdateSpace 开头复位标签颜色,否则用户换到大盘后标签还红着。 验证:本机 makensis 不可用(homebrew v3.12 与 electron-builder v3.04 两个 mac 构建 都是非 ASCII 报 Bad text encoding、纯 ASCII 写产物 std::bad_alloc,**未改动的 HEAD 文件 同样复现**,已记进 eng-infra),只能靠 installer-ui-smoke。因此把反向用例做进了 CI: ui-harness.nsi 收 -DREQUIRED_KB,工作流多编一个所需空间约 858GB 的 harness-nospace.exe, installer-smoke.ps1 加 -ExpectBlocked 断言「弹了提示框 + 进程没退出 + 窗口还是 760 宽的 大卡片(真开装会缩成 360x132 的角落进度卡)」;两个正常 harness 也打开了闸(200MB), 正向那条路本身就是「闸没挡住正常安装」的回归证据。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
首轮 installer-ui-smoke(run 33466932338)证明闸本身是对的:截图里提示框写着 「安装需要约 858.3 GB,C: 盘当前可用 31.7 GB」,卡片没进安装页、窗口仍是 760 宽。 两处要修: 1. 标签没变红。InvalidateRect 只打脏标记,而提示框在卡片中部、盖不住右下角那个 「可用 31 GB」标签,关框时不会顺带擦除重画它,颜色就一直是旧的灰。改用 RedrawWindow(RDW_INVALIDATE|RDW_ERASE|RDW_UPDATENOW) 同步重绘。 2. 冒烟收尾把用例判红了。拦下用例最后点大卡片右上角 ✕ 想干净退出,实跑里进程 2 秒内没退(AwdCloseClick 是 Quit,从 nsDialogs::Show 的回调里调用是否即时生效 没有验证过)——这条路径与本闸无关,不该拿它把用例判红。收尾改为直接杀进程; 关窗行为由 zh/en 两条正常流程在完成卡上覆盖。 顺带留个观察给维护者:大卡片 ✕ 这条路至今没有任何用例覆盖过,值得单独看一眼。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
两轮 installer-ui-smoke 的截图都证明运行期改这个控件的颜色不生效:先试 SetCtlColors + InvalidateRect(第一轮,文案对、标签还是灰的),再试 SetCtlColors + RedrawWindow 同步重绘(第二轮,还是灰的)。本机没有 Windows 真机可调, 而提示框已经把「需要多少 / 该盘有多少 / 怎么办」说全了——与其留一段看着像生效 其实没生效的代码,不如不留,把「为什么不做」的结论写进注释。 顺带把 AwdUpdateSpace 还原成 master 原样(那句颜色复位只为撤销染红而存在)。 本文件相对 master 现在是纯新增,一行都没删。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Owner
Author
CI 验证结果1. 真实桌面打包(决定性的那条)
2. installer-ui-smoke 逐阶段截图(跑了三轮)
最终
一处做了又撤掉的原本还想在展开行把「可用 X GB」标签染红。试了两轮都不生效:先 顺带的一条观察(没有动,留给维护者)拦下用例第一轮点大卡片右上角 ✕ 后,进程 2 秒内没退出。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
修 dev-board#350。
AwdUpdateSpace取了DriveSpace但只把它显示成「可用 X GB」,没有任何闸:磁盘不够时安装照常开始,NSIS 在解压中途报Error opening file for writing,用户拿到一个残缺安装。闸放在哪
AwdInstallClick里、$INSTDIR定下来之后——用户可能刚在「自定义安装」里换过盘,先算就算错了。不足时弹提示说明「需要约 X.X GB / 该盘可用 Y.Y GB」并把展开行的可用空间标签染红,然后Return,不进安装页。所需空间从哪来(不手抄数字)
桌面端在
desktop/build/installer.nsh里直接接 electron-builder 的APP_64_UNPACKED_SIZE:那是打包时对win-unpacked整个目录(含extraResources:backend / jre / python / frontend dist / skills…)实测的解包体积,单位 KB。它是 makensis 命令行
-D传进来的(NsisTarget.js的executeMakensis把 defines 逐个args.push(\-D${name}=${value}`)),所以在生成脚本的第一行就已经存在——和$launchLink/APP_EXECUTABLE_FILENAME/StdUtils那批「晚于本 include 才出现、-WX` 下三连编译失败」的东西不是一回事。手抄常量才是错的:v0.28.0→v0.29.0 的安装包已经从 1516MB 长到 1517MB,每版都在长。拿不到这个 define 就
!error编译失败,不静默少一道闸(USE_NSIS_BUILT_IN_COMPRESSOR在 electron-builder 源码里硬编码false,只有它改了契约才会撞上)。余量 512MB = ARM64 机器上
customInstall还要铺的纯 arm64 Electron 壳(约 260MB 未压缩,不在上面那个数里)+ NSIS/7z 解压临时占用 + 不把盘塞到 0 字节。刻意没给更大:闸设得过严会把「其实装得下」的用户挡在门外,那比不设闸更糟。三条刻意的保守选择
IntCmp会把非数字当 0,不特判就会误判成不足)。网络盘、UNC 路径、某些卷上DriveSpace会返回空。!ifdef AWD_UI_REQUIRED_KB内。插件端安装器不设闸(装的是一份 manifest),编译产物一字节不变。/S,自动更新路径)不进 GUI 代码,这道闸对它不生效——那条路的失败处理归更新器管,此处不越界。NSIS 地雷(按
.claude/agents/eng-infra.md的记录处理)GetRoot/DriveSpace会踩调用方$0-$2(历史上DriveSpace把窗口宽度写成了剩余 GB,CI 截图实锤;引擎里AwdToggleCustom还留着那条注释)。所以AwdReadFreeSpace进出各Push/Pop一次,结果只落 Var——调用方拿到的$0-$2与调用前逐字节一致,上面那段路径处理的结果不受影响。AWDUI_SPACE_W是 104px、按「可用 XX GB」排的版,文案与美术位图、热区坐标是同一套 96dpi 基准,改一处要改三处。顺手修一个这次会自己造出来的陈旧态:
AwdUpdateSpace开头复位标签颜色,否则用户被拦下后换到大盘,标签还红着。验证
本机 makensis 不能用来预检(2026-09-01 实测,Darwin 27):homebrew v3.12 与 electron-builder 缓存的 v3.04 两个 mac 构建都一样——非 ASCII 源码报
Bad text encoding,纯 ASCII 脚本走到写产物时std::bad_alloc崩。未改动的 HEAD 文件同样复现,是环境问题不是本改动引入的(已把这条记进 eng-infra,省得下次再查一遍)。所以把反向用例做进了 CI,而不是靠人眼看代码:
ui-harness.nsi收-DREQUIRED_KB;harness-nospace.exe;installer-smoke.ps1加-ExpectBlocked,断言三件事:弹了提示框(前台窗不再是卡片自己)、进程没退出、窗口还是 760 宽的大卡片(真开装会缩成 360×132 的角落进度卡)。截图落shots/nospace/03-blocked.png。installer-ui-smoke 已在本分支手动触发,跑完会把逐阶段截图作为 artifact 传上来;结论回评在本 PR 里。
复测提示
下个发版装 Windows 桌面端:正常磁盘应与现在毫无区别(点「立即安装」直接进进度卡);把安装盘塞到剩余空间小于安装包解包体积再点,应当弹出「可用空间不足」并留在大卡片上,展开「自定义安装」可见可用空间标签是红的。
🤖 Generated with Claude Code