Skip to content

Improve installation and update check logic - #87

Merged
danielchalmers merged 3 commits into
mainfrom
harden-install-update-flow
Oct 5, 2026
Merged

danielchalmers merged 3 commits into
mainfrom
harden-install-update-flow

Conversation

@danielchalmers

@danielchalmers danielchalmers commented Oct 5, 2026 •

Copy link
Copy Markdown
Owner

Problem

A review of the install and update flow found three defects on the main path. A fourth, a second copy starting on relaunch, is fixed separately in #88.

  • Missing PATH after install. The copy the installer starts inherited the Windows Installer service's environment, which lacks every HKCU PATH entry until the app restarts. After each install or update, Script actions that call Store pwsh, python, code, winget, or npm and dotnet global tools failed.
  • Restore point stall. A double-click install could sit at "Please wait while Windows configures Radial Actions" while Windows Installer created a System Restore point. It took 49 s in one run.
  • Early update notices. Releases are published before CI attaches files, so the update check announced v0.5.0 through v0.7.0 about 3 minutes before any download existed. It also took the highest tag from /releases and ignored the prerelease flag, while Download opens /releases/latest.

Changes

  • Launch through Explorer. LaunchApp in Package.wxs runs "[WindowsFolder]explorer.exe" "[INSTALLFOLDER]RadialActions.exe", so the shell starts the app with the user's environment. It also starts unelevated when the installer runs from an elevated terminal.
  • No restore point. Package.wxs sets MSIFASTINSTALL=1.
  • Update check. UpdateService reads /releases/latest and only reports a version for a release that isn't a draft or prerelease and has an .msi asset. Tests are rewritten for the single-release payload, and a new test covers comparing the exe's four-part version with a three-part tag.

Validation

  • dotnet build in Debug and Release: 0 warnings. dotnet test: 599 passed.
  • Tested on Windows 11 with an isolated test product that has its own UpgradeCode, install folder, Start menu folder and registry key. The real install was hash-checked before and after.
    • Full-UI upgrade, app running, from today's package design. Windows Installer showed its "applications should be closed" prompt with "Automatically close applications" preselected. Restart Manager closed the app, and the new package made no restore point. LaunchApp started the new version through Explorer's factory, and its PATH had all 14 HKCU entries.
    • Basic-UI and silent upgrades. The running app was closed and one instance of the new version ran afterwards.
    • Uninstall while running. The app was closed, and only the settings files were left.
  • The live /releases/latest payload for v0.7.0 parses to 0.7.0.

Considered and rejected

MajorUpgrade Schedule="afterInstallInitialize", which would roll back a failed update to the old version. In a per-user install without elevation, the rollback restored the old files but not the old product's registration (tested). That leaves a copy with no Installed apps entry, which later updates install beside and uninstalls can't remove. The default schedule stays, and Package.wxs says why.

Risks

  • Copies on v0.7.0 keep the old update check until they update.
  • The first upgrade from v0.7.0 still lets the old package's removal request a restore point, because MSIFASTINSTALL is only in the new package. Later upgrades skip it.
  • After install, the app's working directory is System32 (inherited from Explorer), the same as a Run-key start at sign-in. Actions with no working directory start there on that first run.
  • explorer.exe <path> is widely relied on but isn't a documented API.
  • Not run on Arm hardware.

Follow-ups (separate PRs)

  • Update notification copy and click target.
  • A welcome hint for Run at Windows startup.
  • A Run at Windows startup toggle that reads the registry.
  • A banner when settings can't be saved.
  • Package.wxs polish: icon and links in Installed apps, ICE03 and ICE64 fixes, excluding *.settings* from the harvested files.
  • artifactErrorsFailBuild in deploy.
  • README updates, including a warning that updating from 0.6.0 or earlier deletes settings.

- Keep one copy per session: a later launch asks the running copy to open Settings instead of starting a second tray icon whose hotkey fails.
- Start the app after install through Explorer so it gets the user's PATH instead of the Windows Installer service's environment.
- Remove the old version inside the install transaction so a failed or cancelled update rolls back to it.
- Skip the System Restore point that could hold the installer at Please wait for most of a minute.
- Only announce the latest stable release once its installer is attached, matching the release the Download button opens.
Rolling back an in-transaction removal in a per-user install without elevation restores the old files but not the old product's registration, so a failed or cancelled update would leave a copy that later updates and uninstalls can't find. Also cover the guard's can't-open branch with a test and describe it accurately.
@danielchalmers danielchalmers changed the title Harden the install and update flow Launch with the user's environment, skip the restore point, and only announce installable updates Oct 5, 2026
@danielchalmers danielchalmers changed the title Launch with the user's environment, skip the restore point, and only announce installable updates Launch via Explorer, set MSIFASTINSTALL, and use /releases/latest Oct 5, 2026
@danielchalmers danielchalmers changed the title Launch via Explorer, set MSIFASTINSTALL, and use /releases/latest Improve the installer and update check Oct 5, 2026
@danielchalmers danielchalmers changed the title Improve the installer and update check Improve installer and update check logic Oct 5, 2026
@danielchalmers danielchalmers changed the title Improve installer and update check logic Improve installation and update check logic Oct 5, 2026
@danielchalmers
danielchalmers merged commit 53d3798 into main Oct 5, 2026
1 check passed
@danielchalmers
danielchalmers deleted the harden-install-update-flow branch October 5, 2026 21:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant