Native Windows installer pages
原生 Windows 安装页面
The Windows installation interface needs branded light and dark pages without introducing another application runtime or replacing the release mechanisms that extract, register, upgrade, and uninstall Desktop.
English
Problem
The Windows installation interface needs branded light and dark pages without introducing another application runtime or replacing the release mechanisms that extract, register, upgrade, and uninstall Desktop.
Decision
The installer adds custom welcome, progress, and completion pages through electron-builder's NSIS include. The stock script remains responsible for installation and uninstaller generation. A custom full script bypasses electron-builder's separate uninstaller signing path and is therefore unsuitable for this interface change. The Desktop release decision continues to own release identity, update distribution, and signing requirements.
NSIS native controls preserve directory editing, folder selection, checkbox state, and keyboard interaction. An x86 Win32/GDI+ helper retains DWM shadows and draws installation progress on the UI thread while the stock installation worker runs. Stock page visibility is suppressed even when NSIS shows the page after MUI's callback. Windows 11 supplies the outer corner radius; Windows 10 retains its supported frame appearance.
Installation is per-user. Welcome-page leave validation reads the current edit control for mouse and keyboard navigation; the debounced inline hint is not an installation authority. Running-process checks match the affected executable path, leaving other installations independent. Completion-page leave honors the launch checkbox for both mouse and keyboard navigation. Electron-builder resolves the registered directory before custom initialization, so silent updates without /D= retain that directory. Directory staging and promotion retain the release installer’s rollback behavior; first-launch profile preparation remains outside the installer.
Alternatives considered
An Electron installer interface adds a runtime before the application exists and requires a separate installation bridge. Native controls provide the required interaction within the existing installer.
Replacing the full NSIS script with the lightweight prototype also replaces upgrade, registry, uninstaller, and signing behavior. The prototype's transaction mechanism requires separate release qualification and is excluded from the UI integration.
A window region for rounded corners disables the DWM frame shadow. The system frame preserves the shadow while accepting the platform's corner radius.
Consequences
Windows packaging additionally requires the x86 Visual C++ compiler and Windows SDK. The helper is signed before embedding by the same signer as other Windows artifacts. The preparation hook returns true on every platform so electron-builder collects production dependencies. The directory installer owns staging, promotion, registration, and recovery. Its extraction hook invokes the pinned 7-Zip executable with a dedicated progress pipe and a separate diagnostic file. The child inherits only its standard streams and joins a kill-on-close job at creation, so installer termination also stops extraction. Only a zero exit code permits promotion. The helper parses percentages across pipe-read boundaries; it does not implement archive extraction or recursive copying. Preparation, promotion, registration, and cleanup retain bounded estimates. Stage weights express completed work, not remaining time. Displayed progress never regresses, and captions follow the displayed stage. NSIS success authorizes a 600 ms fill animation and a brief 100% frame, with a 750 ms transition target; timers cannot authorize success. The frame stays hidden until branded controls are ready and is initialized once; page transitions preserve its position. Finish hides the window before creating the installed process directly under the current user. An explicitly elevated installer retains shell-mediated launch. Launch failure restores the finish page. Application startup time is independent of installer dismissal.
The native installer regression builds English-only and Chinese-only variants and identifies their language from the visible welcome button; the Windows installation language does not determine test labels. Sequential runs use a unique product identity and private installation directories to verify path rejection, folder selection, launch choices, upgrade, running-process preservation, hidden stock progress, first-show readiness, and uninstall. Registered paths with trailing separators remain upgrade destinations, while drive roots remain invalid. Deterministic native progress tests cover fast and slow extraction, stalls, source resets, fragmented progress tokens, short cleanup, and success between UI ticks. Directory tests exercise extraction through the helper, long paths, new installation, replacement, locked-file recovery, missing staged directories, broken archives, and cancellation. Screenshots and expected behavior belong to Desktop tests rather than recorded Session snapshots. Signed release qualification still requires the configured certificate and token, and actual Windows update artifacts.
中文
Problem
Windows 安装界面需要符合品牌设计的亮暗页面,同时避免引入额外的应用运行时,也不能替换 Desktop 的解压、注册、升级和卸载发布机制。
Decision
安装程序通过 electron-builder 的 NSIS include 接入自定义欢迎页、进度页和完成页。原生脚本继续负责安装和卸载程序生成。完整自定义脚本会绕过 electron-builder 单独生成并签名卸载程序的流程,因此不适合这次界面改动。Desktop 发布决策继续负责发布身份、更新分发和签名要求。
NSIS 原生控件保留目录编辑、文件夹选择、复选状态和键盘交互。x86 Win32/GDI+ 辅助库保留 DWM 阴影,并在原生安装工作线程运行期间,由界面线程绘制安装进度。即使 NSIS 在 MUI 回调之后重新显示页面,原生页面仍保持隐藏。Windows 11 提供外框圆角半径;Windows 10 保留其支持的窗口外观。
安装面向当前用户。欢迎页离开校验在鼠标和键盘导航时均读取当前编辑框;防抖显示的行内提示不决定实际安装路径。进程检查匹配受影响的可执行文件路径,使其他安装保持独立。完成页离开回调在鼠标和键盘导航时均遵循启动复选框。electron-builder 在自定义初始化之前解析已登记目录,因此不带 /D= 的静默更新会保留该目录。目录暂存和替换保留发布安装器的回滚行为;首次启动的配置档案准备仍不属于安装程序。
Alternatives considered
Electron 安装界面会在应用安装前引入运行时,并要求额外的安装通信机制。原生控件能在现有安装程序内提供所需交互。
使用轻量原型替换完整 NSIS 脚本还会替换升级、注册表、卸载和签名行为。原型的事务机制需要单独进行发布验证,不纳入界面接入。
使用窗口区域裁剪圆角会禁用 DWM 窗口阴影。系统窗口框架保留阴影,同时接受平台提供的圆角半径。
Consequences
Windows 打包额外要求 x86 Visual C++ 编译器和 Windows SDK。辅助库在嵌入前使用与其他 Windows 产物相同的签名器签名。准备钩子在所有平台返回 true,使 electron-builder 收集生产依赖。目录安装器负责暂存、替换、注册和恢复。其解压钩子通过独立进度管道和单独的诊断文件调用锁定版本的 7-Zip 可执行文件。子进程仅继承标准流句柄,并在创建时加入关闭即终止的 Job,因此终止安装程序也会停止解压。只有退出码为零才允许替换目录。辅助库跨管道读取边界解析百分比,不自行实现压缩包解压或递归复制。准备、替换、注册和清理仍使用有界估算。阶段权重表示已完成工作量,而非剩余时间。显示进度不回退,文案跟随显示阶段。NSIS 成功信号允许执行 600 毫秒补满动画并短暂显示 100%,切换目标时长为 750 毫秒;计时器不能宣告成功。窗口框架在品牌控件准备完成前保持隐藏,且只初始化一次,页面切换保留其位置。点击完成后先隐藏窗口,再以当前用户直接创建已安装应用的进程;显式提权的安装程序保留通过用户桌面启动的方式。启动失败会恢复完成页。应用启动耗时与安装窗口关闭分别处理。
原生安装回归构建仅英文和仅中文的变体,并从可见的欢迎页按钮识别语言;Windows 安装语言不决定测试文案。顺序执行的测试使用独立产品身份和私有安装目录,验证路径拒绝、文件夹选择、启动选项、升级、运行中进程保留、原生进度条隐藏、首次显示时就绪和卸载。末尾带分隔符的已登记路径仍可用于升级,磁盘根目录仍然无效。确定性的原生进度测试覆盖快速和慢速解压、停滞、进度来源重置、分片进度文本、短暂清理,以及两次界面刷新之间成功的情况。目录测试通过辅助库执行解压,覆盖长路径、新装、替换、文件占用恢复、暂存目录缺失、损坏压缩包和取消。截图和预期行为归属 Desktop 测试,不放入录制 Session 快照。签名发布仍需使用已配置的证书、Token 和真实 Windows 更新产物进行验证。