Prepare for an installed deployment - #3
Merged
Conversation
Three things had to be true before an installer made sense. Settings must not live in the install directory. The app runs AsInvoker, so under Program Files a save would fail outright or be redirected into VirtualStore, where the app then reads a different file than the one on disk. A CWD-relative "config.json" is worse: launched from a Start Menu shortcut the working directory is not the install folder, so settings would neither load nor save where expected. Config now lives in %APPDATA%\VerseLink\config.json, and on first run settings are migrated from a copy left beside the exe or in the working directory, never overwriting a config already there. A relative logFilePath resolves beside it, and the tray's log viewer reads the resolved path rather than the configured one, so it can no longer show a different file than the logger is writing. The installer needs to know the app is running. A tray app holds its exe locked, so an upgrade that starts while VerseLink is running fails part way. The app now holds a named single-instance mutex, which an installer can declare as AppMutex to detect a running copy and prompt. It also stops a second copy from starting and fighting over the same hotkey. There was no version anywhere. The only one was a hardcoded string in the About box. Version.h is now the single source of truth, feeding a real VERSIONINFO resource, the About dialog and (later) the installer's AppVersion. The .rc also embeds the application icon, which the exe never had, so Explorer, the taskbar and shortcuts stop showing the generic executable glyph. Also: config file I/O goes through wide paths, since MSVC's narrow fstream constructors read char* paths in the ANSI codepage and would fail for a user whose profile name is not representable there. Tests: 1037 -> 1053 checks, covering the migration rules (copies from the first existing candidate, never overwrites, invents nothing when there is nothing to migrate) and a guard that VERSELINK_VERSION_STRING matches the numeric components the .rc uses. Verified by running the built exe: config and log land in %APPDATA%\VerseLink, settings migrate from a legacy location, a second instance refuses to start, and the hotkey still registers.
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.
Groundwork for shipping an installer. Three things had to be true first — each one would have caused a real failure for an installed copy.
1. Settings could not stay in the install directory
The app runs
AsInvoker, so under Program Files a save would fail outright, or be silently redirected into VirtualStore — where the app then reads a different file than the one on disk. A CWD-relativeconfig.jsonis worse still: launched from a Start Menu shortcut, the working directory isn't the install folder, so settings would neither load nor save where expected.%APPDATA%\VerseLink\config.json.logFilePathresolves beside it, and the tray's log viewer reads the resolved path, so it can no longer display a different file than the logger is writing.2. The installer needs to know the app is running
A tray app holds its own exe locked, so an upgrade started while VerseLink is running fails part way through. The app now holds a named single-instance mutex (
VerseLinkWindows.SingleInstance) that an installer can declare asAppMutexto detect a running copy and prompt. It also stops a second copy from starting and fighting over the same hotkey.3. There was no version anywhere
No
.rc, noVERSIONINFO— the only version was a hardcoded string in the About box.Version.his now the single source of truth, feeding a real version resource, the About dialog, and the installer'sAppVersion. The.rcalso embeds the application icon, which the exe never had, so Explorer, the taskbar and shortcuts stop showing the generic executable glyph.Also
Config file I/O goes through wide paths. MSVC's narrow
fstreamconstructors interpretchar*paths in the ANSI codepage, which would fail for a user whose profile name isn't representable there.Verification
Harness 1037 → 1053 checks, covering the migration rules (copies from the first existing candidate, never overwrites, invents nothing when there is nothing to migrate) and a guard that
VERSELINK_VERSION_STRINGmatches the numeric components the.rcuses.Beyond the tests, I ran the built exe and confirmed against the live behaviour:
...that a second instance refuses to start ("VerseLink is already running"), and that the embedded resources are real:
The installer and release workflow follow in a separate PR that builds on this.