fix(installer): warn + offer relaunch when TEMP is on a RAM disk#15
Merged
Conversation
…rive
If the user's TEMP (or whatever directory Inno Setup is using as {tmp}) is
on the same drive they just selected for the RAM disk, installation breaks
catastrophically: the installer must stop the running RamDrive service to
swap binaries; stopping the service unmounts the drive; that erases {tmp}
mid-install; the installer then crashes with the new exe not in place and
the service stopped — leaving the system in a hard-to-recover state.
Detect this in NextButtonClick on the config page (after the user picks
the drive letter). If {tmp}'s drive matches the chosen mount letter,
show an actionable error explaining the problem and pointing to the
/T= command-line option:
setup.exe /T=C:\Windows\Temp
(or any directory on a different physical drive). The installer cancels
rather than proceeding.
This intentionally only catches the common case via the wizard's drive
dropdown — it doesn't try to detect WinFsp mounts in general. That covers
the user-reported failure mode (TEMP on RamDrive) without P/Invoke into
fsutil/IOCTL territory.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The first version of this PR added the temp-on-target check inside
NextButtonClick on the wizard's drive-letter page. That check is
unreachable in practice: InitializeSetup runs first, sees the existing
RamDrive service, prompts the user to stop it, and on Yes immediately
unmounts the drive — by the time the user reaches the drive-letter page,
{tmp} either still works (TEMP wasn't on the RAM disk) or the installer
has already crashed (TEMP was). Either way NextButtonClick never gets to
run the check.
Replaced with the right-place fix:
* In InitializeSetup (very first user-visible action), show a Vista-style
TaskDialog with three command-link buttons:
- "Continue installation" (TEMP isn't on a RAM disk)
- "Pick a different TEMP folder..."
- "Cancel"
* "Pick" opens BrowseForFolder defaulting to {sd}\Windows\Temp.
* On a chosen folder, the installer exec's cmd /c to set TEMP / TMP env
vars in a child shell, then `start` a fresh setup.exe that inherits
those vars. Current instance Result := False; exit cleanly.
* The relaunched setup.exe is the same .exe on disk — only the env it
inherits is changed, so its Inno bootstrap creates {tmp} under the
user-chosen folder instead of the RAM disk.
* If the user picks another RAM-disk path, they'll see the same dialog
again (self-correcting loop).
Edge cases handled:
* User cancels BrowseForFolder -> abort cleanly.
* User picks a non-existent path -> error + abort.
* Relaunch goes through UAC again (admin required for service install);
this is unavoidable given PrivilegesRequired=admin.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ded lines
The previous WriteAppSettings hand-built the file with `Lines[0..N] := '...'`,
so the installed jsonc was missing every field added since the helper was
last touched (FileInfoTimeoutMs, EnableNotifications) and all of the inline
JSONC comments. It also took the opposite of the intended upgrade behavior:
[Files] copied the template with `onlyifdoesntexist` (skipped on upgrade),
then WriteAppSettings unconditionally overwrote with a stale shape.
Replaced with a template-driven flow:
* [Files] now drops the published appsettings.jsonc into {tmp} (always).
* New helpers PatchScalarValue / PatchInitialDirectories / ReadScalarValue /
ReadInitialDirectories / CountSubstr operate on the in-memory line array.
* WriteAppSettings loads {tmp}\appsettings.jsonc as the base, then patches
exactly three user-controlled values: MountPoint, CapacityMb, and
InitialDirectories. Every other line — including all comments and any new
field added in future releases — flows through unchanged.
* On upgrade, MountPoint / CapacityMb / InitialDirectories are pre-loaded
from the existing config (read by ReadScalarValue / ReadInitialDirectories)
into the wizard controls in CurPageChanged, so the user sees their current
drive letter / capacity / initial-directory tree pre-filled and can either
keep or change them. The selected values are then patched into the *new*
template, picking up new defaults and schema additions automatically.
* On fresh install, the wizard defaults drive the patch.
* All other tunables (PageSizeKb, PreAllocate, EnableKernelCache,
FileInfoTimeoutMs, EnableNotifications, VolumeLabel, Logging) come from
the new template — so an upgrading user gets the latest default values
for those, without having to manually edit jsonc.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The release workflow rewrites #define MyAppVersion before invoking ISCC, so the value committed in the script never ships. "1.0.0" looked like a real release tag — local builds produced RamDrive-1.0.0-setup.exe which is indistinguishable from a public 1.0 build at a glance. Switch to 0.0.0-dev so accidental local artifacts are obviously not release artifacts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
If a user has `%TEMP%` on a RAM disk (their own, or any WinFsp mount), the installer self-destructs: `InitializeSetup` stops the running RamDrive service to swap binaries → service unmount erases `{tmp}` → installer crashes with new exe not in place.
This PR adds, as the very first user-visible action, a Vista-style TaskDialog with three command-link buttons:
If the user picks another RAM-disk path, they see the same dialog again (self-correcting loop).
Why not in NextButtonClick?
Earlier iteration of this PR put the check on the drive-letter wizard page. Reachability bug: `InitializeSetup` runs first; if it stops the service the wizard never gets to render. Removed in this revision.
What this PR does NOT try to do
Test plan
🤖 Generated with Claude Code