feat(updater): hot update for Windows NSIS installs - #720
Merged
Merged
Conversation
The app no longer disappears while it updates on Windows. NSIS installs of
JVM apps are laid out as App.exe + app\App.cfg at the root and
versions\<version>\{app,runtime}, so installAndRestart installs the new
version next to the running one, launches it, and exits once the new
version's first window is on screen.
- plugin: versioned app image layout and NSIS hooks that neither kill the
running app nor delete its files when NUCLEUS_HOT_UPDATE=1
- updater: install while running, handoff on the new version's first frame,
cleanup of retired versions, classic fallback when the hot path cannot start
- multi-instance: cross-process install lock, pendingRestartVersion /
restartToInstalledVersion, explicit relaunchArguments
- fix: PowerShell update scripts are written with a BOM, so updates work for
accented profile paths (classic path included)
- fix: the post-update event is only reported when its target version runs
- E2E: examples/hot-update-demo + scripts/windows-hot-update-e2e.ps1
…ot-update # Conflicts: # plugin-build/plugin/src/main/kotlin/dev/nucleusframework/desktop/application/tasks/AbstractElectronBuilderPackageTask.kt
kdroidFilter
added a commit
to NucleusFramework/nucleus-website
that referenced
this pull request
Sep 25, 2026
…hread hotkeys Covers NucleusFramework/Nucleus#720, #721 and #722.
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
On Windows,
installAndRestartused to close the app, run the NSIS installer and relaunch it — about 13-15 s with nothing on screen. The app now stays visible for the whole update.App.exe+app\App.cfgstay at the install root, the runtime and the app move toversions\<version>\. The.cfgpoints there withapp.runtime/$ROOTDIR, so a new version installs next to the running one without touching a file it holds open.NUCLEUS_HOT_UPDATE=1. Generated NSIS hooks (customCheckAppRunning,customRemoveFiles) then neither kill the app nor delete its files; without the variable they reproduce electron-builder's defaults.TaoWindowreports the new version's first presented frame (UpdateHandoff.signalReady()). The new version then deletes the retired version and launcher (rename-then-delete, so a version still in use is kept).Program Files) use the classic update.pendingRestartVersionwithout downloading anything;restartToInstalledVersion(relaunchArguments);relaunchArgumentsis explicit because replaying the command line would resend the autostart marker or a deep link.C:\Users\Hélène\…), classic path included.consumeUpdateEvent/wasJustUpdatedno longer report an update whose install failed.Public API (additive):
UpdateHandoff,VersionedInstall,SingleInstanceManager.releaseForHandoff(),NucleusUpdater.installAndRestart(file, relaunchArguments),pendingRestartVersion,restartToInstalledVersion().Not covered: GraalVM native images (no
.cfgindirection, would need a stub launcher), MSI and portable builds. They keep the classic update.Test plan
UpdateHandoffTest,WindowsHotUpdateTest,WindowsHotUpdateMultiInstanceTest,WindowsHotUpdateLayoutTest,UpdateEventTestapiCheckon the touched modulesscripts/windows-hot-update-e2e.ps1+examples/hot-update-demo), sampling visible windows and the on-screen pixel every ~18 ms:update: 0 ms gap, retired version and launcher cleaned uprelaunch-during-install: launcher starts fine mid-install, one window leftclose-during-install: app not relaunched, install completes, next start runs the new versionfailing-installer: app stays on its version, same process, no gapstale-target-dirtwo-instances: installs serialized, each instance comes back with its own documentnotify-other-instance: second instance downloads nothing, restarts throughpendingRestartVersionNativeLibraryLoaderTest(5) andElectronBuilderRpmConfigTest(2) fail on Windows. They fail identically on the base commit, so they are unrelated to this PR.