Skip to content

Improve Windows installer runtime packaging#2303

Merged
ten9876 merged 1 commit intoten9876:mainfrom
jensenpat:aether/windows-installer-vcruntime
May 3, 2026
Merged

Improve Windows installer runtime packaging#2303
ten9876 merged 1 commit intoten9876:mainfrom
jensenpat:aether/windows-installer-vcruntime

Conversation

@jensenpat
Copy link
Copy Markdown
Collaborator

@jensenpat jensenpat commented May 3, 2026

Summary

  • Bundle app-local MSVC runtime DLLs in the Windows installer so users do not need a machine-global VC runtime install before launching AetherSDR.
  • Keep vc_redist.x64.exe out of the generated setup package; CI stages only the runtime DLLs that Inno Setup needs to install beside the app.
  • Add the project license/welcome flow and AetherSDR branding to the installer, including the setup EXE icon, the large left-side wizard artwork, and the small wizard corner icon.
  • Update the finished page copy with: "It's time to get on the air."

Motivation

The Windows installer could produce a working install on developer machines while still leaving fresh user machines exposed to missing MSVC C/C++ runtime DLL errors. The installer also jumped directly to options/tasks in the tested local setup flow and used stock Inno Setup artwork on some pages, which made the first-run install experience feel less polished than the app itself.

This change focuses on the installer path first, rather than the portable ZIP, so the out-of-the-box Windows setup experience has the required runtime files and branded wizard screens.

Implementation

  • Added packaging/windows/stage-msvc-runtime.ps1 to find the x64 Microsoft.VC*.CRT redist directory from VCToolsRedistDir when available, with a Visual Studio redist directory fallback.
  • Updated .github/workflows/windows-installer.yml so CI stages those MSVC runtime DLLs into installer-runtime before compiling the Inno setup package.
  • Pass /DVC_RUNTIME_DIR=... into Inno Setup so packaging/windows/installer.iss can install those DLLs app-local.
  • Exclude concrt140.dll, msvcp140*.dll, vccorlib140.dll, and vcruntime140*.dll from the generic deploy copy when VC_RUNTIME_DIR is supplied, avoiding duplicate runtime sources.
  • Left the fallback installer behavior intact when VC_RUNTIME_DIR is not defined.
  • Added LicenseFile, DisableWelcomePage=no, SetupIconFile, WizardImageFile, and WizardSmallImageFile settings to improve the installer flow and branding.
  • Generated wizard-image.bmp from docs/logo.jpg for the large left-side wizard panel and wizard-small-image.bmp from the AetherSDR round icon for the small wizard image.

Validation

  • Built AetherSDR locally with CMake/Ninja using the requested 10-way build parallelism.
  • Compiled the Inno Setup installer locally and confirmed the compile log reads the license file plus both custom wizard images.
  • Confirmed the installer output does not include or run vc_redist.x64.exe.
  • Deleted C:\Program Files\AetherSDR, reran setup, and verified the fresh install includes app-local MSVC runtime DLLs such as msvcp140.dll, msvcp140_1.dll, msvcp140_2.dll, vcruntime140.dll, and vcruntime140_1.dll.
  • Verified the fresh install does not contain stale vc_redist.x64.exe, dxcompiler.dll, dxil.dll, or tls\qopensslbackend.dll artifacts.
  • Ran ldd across the installed .exe/.dll files with the app and plugin directories on PATH; no missing dependencies were reported.
  • Confirmed ldd resolves Qt, hidapi, fftw, deepfilter, and MSVC runtime DLLs from C:\Program Files\AetherSDR, while expected system DLLs resolve from System32.
  • User-tested the installer visually and confirmed the result looked fantastic.

👨🏼‍💻 Generated with OpenAI Codex (GPT-5.5 Pro 4/23) and tested by @jensenpat

@jensenpat jensenpat marked this pull request as ready for review May 3, 2026 06:21
@jensenpat jensenpat requested a review from ten9876 as a code owner May 3, 2026 06:21
Copy link
Copy Markdown
Contributor

@aethersdr-agent aethersdr-agent Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @jensenpat — this is a nicely scoped, well-documented installer improvement. The app-local runtime approach via Inno's Excludes + /DVC_RUNTIME_DIR is the right call, and routing through VCToolsRedistDir (which ilammy/msvc-dev-cmd exposes in CI) before falling back to a Visual Studio scan is a sensible discovery order. I confirmed the referenced assets (LICENSE, docs/AetherSDR.ico) exist in the tree, and the conditional [Files] section will only kick in when the define is supplied, leaving the legacy fallback intact.

A few small things worth considering:

Portable ZIP still ships without the MSVC runtime. The Compress-Archive -Path deploy\* step at windows-installer.yml:80 happens after staging but only zips deploy\, not installer-runtime\. Your PR description calls this out as intentional scope-narrowing, so not a blocker — but follow-up users grabbing the portable ZIP on a fresh box will hit the same vcruntime140.dll not found failure this PR fixes for the installer path. A one-line follow-up that copies the staged DLLs into deploy\ before Compress-Archive (or zips both directories) would make the two distribution paths behave consistently.

Inno Setup wizard image dimensions. Inno Setup is picky about WizardImageFile / WizardSmallImageFile sizes — the modern-style defaults are 164×314 (or 192×314 with high-DPI variants) and 55×58 respectively. If the BMPs aren't sized to one of the supported variants, ISCC will either reject them or stretch them ugly. Your validation notes say it looked good locally, so likely fine, but worth double-checking on the high-DPI runtime path.

Minor (non-blocking): Sort-Object @{ Expression = ...; Descending = $true }, FullName -Descending works, but the cmdlet-level -Descending is redundant with the hashtable's own Descending = $true for the first key, and applies to FullName too — the tiebreak ends up being "highest FullName wins," which is probably fine in practice but slightly unusual. If you wanted alphabetical tiebreak, drop the trailing -Descending.

Nothing here is blocking — the core change is solid. Nice work on tracking down the redist directory robustly and on the branding polish.

@ten9876 ten9876 merged commit 2f82130 into ten9876:main May 3, 2026
5 checks passed
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.

2 participants