How to build a Windows installer¶
Package a compiled bundle into a first-deployment setup.exe with Inno Setup, so end users get a standard Windows installer instead of a raw ZIP.
🔧 Prerequisites¶
- A working
CompilerConfigthat already compiles your project (see How to configure a compiler) - Inno Setup 6 installed, with
ISCC.exeonPATH(or in its defaultProgram Fileslocation)
No PyPI dependency
The installer stage shells out to ISCC.exe — there is no pip install ezcompiler[...] extra to add. Only the Inno Setup compiler itself needs to be installed on the build machine.
📝 Steps¶
-
Enable the installer stage in your config.
-
Run the build pipeline. The installer stage runs automatically after
zipwheninstaller_enabled=True.This produces
dist/installer/MyApp-1.0.0-setup.exeby default — see the config reference below to change the location. -
Point at a custom
.issscript if the generated one doesn't fit your needs.config = CompilerConfig( ..., installer_enabled=True, installer_iss_path=Path("installer/custom.iss"), )Your script can reuse the same
#PLACEHOLDER#tokens as the built-in template (#APP_NAME#,#VERSION#,#COMPANY_NAME#,#BUNDLE_DIR#,#OUTPUT_DIR#,#ICON_LINE#,#MAIN_EXE#,#DEFAULT_DIR#,#PRIVILEGES_REQUIRED#). -
Skip the installer for a single run without touching the config.
-
Install per-user instead of system-wide if the app also uses TUF secure updates.
By default the installer targets
{autopf}\<App>(Program Files) and requires admin rights (PrivilegesRequired=admin). A tufup auto-update runs as the logged-in user and cannot elevate to overwrite files there. Setinstaller_per_user=Trueto install into%LOCALAPPDATA%\Programs\<App>instead, withPrivilegesRequired=lowest— no elevation needed to install, and none needed later for auto-update to replace files in place.
⚙️ Config reference¶
| Field | Default | Description |
|---|---|---|
installer_enabled |
False |
Turn on the installer build stage |
installer_output_dir |
output_folder.parent / "installer" |
Directory receiving the generated .iss and the compiled setup.exe |
installer_iss_path |
None (built-in template) |
Path to a custom .iss script, overriding the bundled one |
installer_per_user |
False |
Install to %LOCALAPPDATA%\Programs with PrivilegesRequired=lowest instead of Program Files with admin rights — required for tufup in-place auto-update |
💻 CLI¶
Enable the stage from the generate config command:
✅ Result¶
run_pipeline() produces {project_name}-{version}-setup.exe in installer_output_dir. When tuf_enabled=True, upload() also copies it into the assembled release/ directory alongside the ZIP, so it ships with the rest of the release artifacts — see Release pipeline.
Error handling¶
| Exception | Raised when |
|---|---|
IsccNotFoundError |
ISCC.exe is not on PATH or in a default install dir |
InstallerBuildError |
ISCC.exe exits with a non-zero status |
InstallerConfigError |
bundle_dir is missing/empty, or installer_iss_path doesn't exist |
InstallerTypeError |
An unsupported installer_type was requested |