Side-by-Side Install
The opt-in layout that lets an app apply real delta updates beside the running version — instead of a full re-install.
Why
A plain (flat) install writes files straight into the install directory. To update it you must overwrite the running files — which fails when they're locked, and can't be a delta. The side-by-side layout installs each version into its own folder and points a current junction at it; an update materializes a new version beside the old one and flips the junction. The running version is never written to.
Enable it
Set SideBySide in the project. Flat install remains the default, so nothing changes for apps that don't opt in.
{ "AppName": "MyApp", "AppVersion": "1.2.0", "SideBySide": true,
"AppUpdatesURL": "https://updates.example.com/stable/feed.json" }
The layout
C:\Program Files\MyApp\ (the base — what the user chose)
├─ current ──► app-1.2.0 (a junction shortcuts and ARP point at)
├─ app-1.2.0\ MyApp.exe, …, _payload-manifest.json, update-settings.json
└─ app-1.3.0\ (materialized by the next update, then current flips here)
How it comes together at install time (all no-ops for a flat install):
| Piece | What it does |
|---|---|
InstallContextBuilder | Sets InstallPath = <base>\app-<version>, LaunchPath = <base>\current, and the SideBySide flag. For a flat install every path is equal. |
JunctionCreateStep | Points current at the installed version (a junction — no elevation needed) and stamps the runtime InstallRoot into the shipped update-settings.json. |
ShortcutCreateStep | Targets the launch path (current), so a version flip is transparent to shortcuts. |
ExtractSolid | Ships _payload-manifest.json beside the files so a delta update can diff against what's on disk. |
UninstallStep | Removes the whole product-owned base tree (all app-* folders + the junction). |
How an update applies
The Updates domain's SideBySideApplier stages into <base>\.staging-<ver>, verifies every blob's SHA-256 as it writes (a mismatch aborts before any flip), promotes to app-<ver>, then flips current. A crash before the flip is harmless (the junction still points at the old version and stale staging is swept next time); Rollback flips back; RetireOldVersions deletes all but current + previous.