Replace the generated cmd.exe + robocopy update helper — which silently
failed on some machines — with an in-app C# installer:
* Stage the new version to a per-user temp folder off the install and run
the new RemSound.exe from there, so nothing in the install is locked by
the updater itself.
* Wait for the old process to fully exit (real WaitForExit), then
back-up-and-swap files in C# with retry + rename-aside; roll the install
back to the previous version on any failure, so a failed update can never
leave a half-installed RemSound.
* Log every step to updater.log; clean up old stages and legacy batch
artefacts on launch. Removed the old BuildInstallScript batch generator.
Route the "RemSound is already running" dialog and its follow-up message
through ForegroundDialog so they surface in front from a background-relaunched
copy, matching the earlier post-update fix.
Docs: rewrite the readme update sections for the new mechanism, regenerate
MANUAL.md, refresh the About-box changelog and RELEASE_NOTES.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fixes the chained-fault runaway Andre hit after an update (multiple copies
stacking, audio climbing to deafening, terminal kill to recover).
- Single-instance lock (SingleInstanceCoordinator + SingleInstanceDialog,
wired in Program.Main). A named mutex makes two copies impossible. A second
launch offers: switch to the running copy (default; surfaces it from the
tray via a named activation event), or force the running copy closed and
start fresh (Process.Kill, retried elevated if the target is elevated).
This is the structural fix that makes the stacking runaway impossible.
- Prompt-free update exit. InstallUpdateAsync sets updatingInProgress before
Application.Exit(); the close path's skipPrompt now honours it, so no
unsaved-changes dialog (whose default button is Cancel) can abort the
update's restart.
- Read-only persistence fix. BuildCurrentProfile now carries
currentProfileReadOnly into the saved snapshot. Previously a deliberate
save of a locked profile wrote ReadOnly=false, silently unlocking it on
disk — which re-armed the save prompt that then blocked the update.
- In-process double-install guard. updateInstallStarted stops the ~4 s
startup check and the background poll both staging an install + helper.
- Docs: About box, RELEASE_NOTES.md, readme.html + MANUAL.md ("Only one copy
of RemSound runs at a time").
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>