-
Notifications
You must be signed in to change notification settings - Fork 4
16 updater
Update checking, the Updater.exe flow, restart/reinstall. Related: 04 — Architecture · 15 — Development
SimpleLauncher\Services\CheckForUpdatesService.cs (WPF) and
SimpleLauncher.Avalonia\Services\AvaloniaCheckForUpdatesService.cs (Avalonia).
-
Source fallback chain (app + updater):
- GitHub API
https://api.github.com/repos/purelogiccode/SimpleLauncher/releases/latest(primary repo), - Secondary server
assets.purelogiccode.com/Simple Launcher/Simple Launcher/version.txt(Cloudflare-hosted) — builds the release/updater URLs from it (release_{version}_{rid}.zip/updater_{rid}.zip).
- GitHub API
- Silent check at startup. If every GitHub source is unreachable (offline, rate-limited, blocked), the check falls back to the secondary server.
- Manual check: About window "Check for Updates".
- Version comparison against the current
5.8.0; new version → prompts to download.
Both apps read the same GitHub release, which ships the unified bundle and a single updater:
-
release_{version}_{rid}.zip— the unified payload:SimpleLauncher.exe(WPF) andSimpleLauncher.Avalonia.exe(Avalonia) next to each other plus the shared content files (images/,tools/,samples/,appsettings.json, …). Both apps are framework-dependent single executables (managed assemblies bundled; native libraries such as SQLite/Skia ship beside the exe), so the .NET 10 Desktop Runtime is required. -
updater_{rid}.zip— the single standaloneUpdater.exe(framework-dependent single file) shared by both apps. It bundles the Avalonia native libraries it needs (libSkiaSharp.dll,libHarfBuzzSharp.dll,av_libglesv2.dll,IncludeNativeLibrariesForSelfExtract) and self-extracts them at launch, so the one file runs from either app folder and on legacy WPF-only installs that never had those natives (which is how the old WPF updater asset name is reused for the unified release).
sequenceDiagram
participant A as App (WPF or Avalonia)
participant U as Updater.exe
A->>A: ShutdownForUpdateAsync (QuitSimpleLauncher)
A->>U: download fresh Updater.exe from GitHub/secondary server (if needed) + launch with current PID and target app
A->>A: app exits
U->>U: download the unified release zip, extract over the shared app folder
U->>A: relaunch the app that launched it with -whatsnew
A->>A: shows UpdateHistoryWindow (release notes)
-
QuitSimpleLauncher(WPF) /AvaloniaQuitSimpleLauncher(Avalonia):-
RestartApplicationAsync— spawns itself with--restarting, then shuts down; failed restart → "FailedToRestart" box, app stays alive; user-canceled launch (Win32 error 1223) → Information log + "FailedToRestart" box, app stays alive. -
ShutdownForUpdateAsync— downloads a freshUpdater.exefrom GitHub (fallback: secondary server), launches it with the current PID and the target executable name, kills the app.
-
-
ReinstallSimpleLauncher(WPF) /ReinstallAndShutdownAsync(Avalonia):-
StartUpdaterAndShutdownAsync/LaunchUpdaterAndShutdownAsync— launches the localUpdater.exeor downloads it from GitHub/secondary server, then hard-exits; access-denied (error 5) → correct message box.
-
-
--restartingskips single-instance enforcement during startup;-whatsnewshows the release-notes window. - The updater relaunches with
-whatsnew(not--restarting), so the restarted app still goes through the shared single-instance guard: if another instance is somehow still alive, the relaunch exits and restores that instance instead of running two copies.
The single updater (Updater.exe) shared by both apps. Responsibilities: fetch the latest
release (GitHub API primary → secondary server as fallback), download the unified release zip
for the current RID (retrying from the secondary server if the primary download fails), extract
over the application folder, relaunch the app that launched it. The launching app passes its
PID as the first argument and the target executable name (SimpleLauncher.exe or
SimpleLauncher.Avalonia.exe) as the second; older WPF releases pass only the PID, so the
updater detects the target from the process name. It was built from the Avalonia codebase
(cross-platform net10.0 / net10.0-windows) and replaced the former WPF-specific updater.
The updater excludes its own files (Updater*) during extraction so it can replace the
applications while running.
Behavior parity with the dropped WPF updater is intentional: same Serilog setup (rolling warning
file + bug-report sink) and launch stats, same progress/log window with a Cancel button, the same
Dokan detection/install prompt after a successful update, the same retry/secondary-server
fallback, and the same global exception handling — including a UI-thread handler that logs,
reports the bug, shows the error dialog and exits with code 1 instead of vanishing. The app's
project reference uses ReferenceOutputAssembly=false; Private=false so the SDK does not copy
the updater's plain build sidecars into the publish output, and the publish step cleans the
updater's staging tree first because dotnet publish overwrites but never deletes
(Remove-UpdaterSidecars in scripts/package-release.ps1 remains as a guard).
- 04 — Architecture (startup/shutdown lifecycle)
- 15 — Development (release packaging)
- 17 — Release Notes
- Home
- 01 Overview
- 02 Projects And Solution
- 03 Quickstart
- 04 Architecture
- 05 Configuration
- 06 Systems And Launch
- 07 Core Services
- 08 Ui Layer
- 09 Retroachievements
- 10 Game Scanning
- 11 Bundled Tools
- 12 Data Formats
- 13 Logging And Debug
- 14 Testing
- 15 Development
- 16 Updater
- 17 Release Notes
- 18 Emulator Parameters
- Manual Tests
- Parameters