Skip to content

fix(installer): detect WinFsp via 32-bit registry view and install before unmount - #23

Merged
hooyao merged 7 commits into
mainfrom
fix/installer-winfsp-ordering
Jun 19, 2026
Merged

fix(installer): detect WinFsp via 32-bit registry view and install before unmount#23
hooyao merged 7 commits into
mainfrom
fix/installer-winfsp-ordering

Conversation

@hooyao

@hooyao hooyao commented Jun 19, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes two installer bugs in setup/RamDrive.iss.

Bug 1 — WinFsp reinstalls on every run

Not a version issue — a registry-view bug. WinFsp stores HKLM\SOFTWARE\WinFsp\InstallDir in the WOW6432Node (32-bit) view on all 64-bit systems. The installer runs in 64-bit install mode (ArchitecturesInstallIn64BitMode, introduced in #18 for ARM64), so the bare-HKLM read in IsWinFspInstalled mapped to the 64-bit view and never found the key → WinFsp reinstalled every time.

  • Verified on the reporter's machine: 64-bit view → not found; 32-bit view → InstallDir = C:\Program Files (x86)\WinFsp\.
  • Fix: read HKLM32 explicitly (GetWinFspInstallDir), and add ShouldInstallWinFsp, which compares GetPackedVersion of bin\winfsp-<arch>.dll against the bundled WinFspVersion macro via ComparePackedVersion — installs only when strictly older.

Bug 2 — WinFsp install fails when TEMP is on the RAM disk

msiexec extracts WinFsp's own payload into the system %TEMP%, which may live on the RAM disk being replaced. The old flow unmounted the drive in InitializeSetup before installing WinFsp, deleting that %TEMP% mid-install.

  • Fix: introduce PrepareToInstall (runs before [Files] copy) that does, in order: install WinFsp while the drive is still mounted → stop service + KillProcess + unmount (still before [Files], so the locked RamDrive.exe is gone before it's overwritten).
  • The MSI now uses dontcopy + ExtractTemporaryFile so it isn't pre-copied to a possibly-RAM-disk {tmp}.
  • InitializeSetup now only collects consent; teardown is deferred to PrepareToInstall.
  • Refreshed the TEMP-on-RAM-disk warning wording (its old WinFsp failure mode no longer applies).

Docs

  • Documented both constraints (HKLM32 detection, install-before-unmount ordering) in CLAUDE.md.

Testing

  • Registry diagnosis confirmed on the reporter's machine (64-bit vs 32-bit view).
  • Installed WinFsp DLL version 2.1.25156.0 matches the bundled MSI → equal-version comparison correctly skips reinstall.
  • Function declaration order and begin/end balance checked manually.
  • ⚠️ Not compile-verified locally (ISCC not installed on the dev box; CI installs it via Chocolatey). Recommend a local ISCC.exe setup/RamDrive.iss before merge.

🤖 Generated with Claude Code

hooyao and others added 7 commits June 19, 2026 09:51
…fore unmount

Two installer bugs in setup/RamDrive.iss:

1. WinFsp reinstalled on every run. WinFsp stores InstallDir under the
   WOW6432Node (32-bit) registry view on all 64-bit systems, but the
   installer runs in 64-bit install mode (ArchitecturesInstallIn64BitMode,
   added in PR #18 for ARM64), so the bare-HKLM read in IsWinFspInstalled
   hit the 64-bit view and never found the key. Read HKLM32 explicitly and
   add ShouldInstallWinFsp, which compares GetPackedVersion of
   bin\winfsp-<arch>.dll against the bundled WinFspVersion macro and installs
   only when strictly older.

2. WinFsp install failed when TEMP was on the RAM disk. msiexec extracts
   WinFsp's payload into the system %TEMP%, which may live on the RAM disk
   being replaced. The old flow unmounted the drive in InitializeSetup before
   installing WinFsp, deleting that %TEMP% mid-install. Move both steps into
   PrepareToInstall (runs before [Files] copy): install WinFsp while the drive
   is still mounted, then stop the service and unmount before the locked
   RamDrive.exe is overwritten. The MSI now uses dontcopy + ExtractTemporaryFile
   so it isn't pre-copied to a possibly-RAM-disk {tmp}; InitializeSetup only
   collects consent, deferring teardown to PrepareToInstall.

Also refresh the TEMP-on-RAM-disk warning wording (the WinFsp failure mode it
described no longer applies) and document both constraints in CLAUDE.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add an `installer` job to ci.yml that compiles RamDrive.iss (both x64 and
arm64 legs) so .iss structure and [Code] Pascal syntax regressions surface
on PRs instead of only at release time.

- Gated behind a dorny/paths-filter `installer` output (setup/** or ci.yml),
  so it never runs on changes that don't touch the installer — no wasted CI.
- Stages text placeholders for RamDrive.exe / appsettings.jsonc / the WinFsp
  MSI to satisfy [Files] source-existence checks. ISCC never executes the exe
  or reads its version, so the ~10-min dual-arch AOT publish is unnecessary
  for a syntax/structure check. The MSI filename is read from the WinFspMsi
  macro to stay in sync.
- Asserts both -setup.exe artifacts are produced.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a `package` job that runs the actual AOT publish, bundles the real
WinFsp MSI, and compiles an installable setup.exe, then uploads both the
portable build and the installer as workflow artifacts. The existing
`installer` job only stages placeholder binaries to validate .iss/Pascal
syntax, so its setup.exe is not runnable; this job fills that gap for
local testing without installing Inno Setup locally.

x64 only, mirrors release.yml's proven steps minus the Release upload.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
….zip

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Inno Setup 6 is a Unicode compiler but reads a BOM-less script using the
system ANSI code page. The wizard dialogs contain em-dash characters
(U+2014, UTF-8 E2 80 94); without a BOM these render as mojibake (â€")
on non-UTF-8 default locales. Prepending the BOM makes ISCC read the
file as UTF-8 regardless of the build host's code page. Content is
otherwise byte-identical.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hooyao
hooyao merged commit c8125ba into main Jun 19, 2026
8 checks passed
@hooyao
hooyao deleted the fix/installer-winfsp-ordering branch June 19, 2026 04:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant