Skip to content

Building on Windows

On Windows, pyzed build makes a folder with Shop.exe and everything it needs. You can share that folder as a zip, or wrap it in an installer.

  1. Install uv if you do not have it (PowerShell):

    Terminal window
    powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
  2. In the project folder, build:

    Terminal window
    uv run pyzed build
  3. Try it: double-click dist\Shop\Shop.exe, or from PowerShell:

    Terminal window
    .\dist\Shop\Shop.exe

The result has no console window (windowed = true). While you are testing, build with --console to see errors and print output in a terminal next to the app.

Folder (default) --onefile
Result dist\Shop\Shop.exe plus an _internal folder dist\Shop.exe
Starts Fast Slower: it unpacks itself to a temporary folder each time
Antivirus Rarely flagged Flagged more often (false positives)
Self-update Supported (Updates) Not supported

Prefer the folder build, and give people a zip or an installer.

Windows uses an .ico file. Put it in the project and point to it:

pyproject.toml
[tool.pyzed.build]
icon = "assets/icon.ico"

See Icons and metadata to make an .ico from a PNG and to set the version shown in the file’s properties.

The simplest way: zip the app folder and share the zip. People unzip it anywhere and run Shop.exe.

Terminal window
Compress-Archive -Path dist\Shop -DestinationPath Shop-windows-x86_64.zip

Name it <app>-windows-<arch>.zip if you plan to update the app by itself.

An installer adds the app to the Start menu, can create a desktop shortcut and registers an uninstaller.

Pyzed Design itself is installed this way: its Inno Setup script is installer/windows/pyzed-design.iss and is a good template. It installs for the current user only, without administrator rights, in %LOCALAPPDATA%\Programs\<App>, which keeps the folder writable so the app can update itself. A minimal script:

installer/shop.iss
#define AppName "Shop"
#define AppExe "Shop.exe"
[Setup]
; Generate your own AppId once (Tools -> Generate GUID in Inno Setup) and never change it.
AppId={{00000000-0000-0000-0000-000000000000}
AppName={#AppName}
AppVersion=1.0.0
DefaultDirName={autopf}\{#AppName}
PrivilegesRequired=lowest
OutputBaseFilename=Shop-setup
Compression=lzma2/max
SolidCompression=yes
WizardStyle=modern
[Files]
Source: "..\dist\Shop\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
[Icons]
Name: "{autoprograms}\{#AppName}"; Filename: "{app}\{#AppExe}"
Name: "{autodesktop}\{#AppName}"; Filename: "{app}\{#AppExe}"; Tasks: desktopicon
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; Flags: unchecked

Compile it (Inno Setup 6 installs ISCC.exe; choco install innosetup also works):

Terminal window
& "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" installer\shop.iss

With PrivilegesRequired=lowest, {autopf} is the user’s own programs folder.

Windows SmartScreen warns about executables that are not signed (“Windows protected your PC”). Unsigned apps still run (More info → Run anyway), but signing with a code signing certificate removes the warning over time.

Terminal window
signtool sign /f certificate.pfx /p $env:CERT_PASSWORD /fd sha256 `
/tr http://timestamp.digicert.com /td sha256 dist\Shop\Shop.exe

signtool.exe comes with the Windows SDK. Sign the .exe before zipping or building the installer, then sign the setup .exe too. The CI page shows how to keep the certificate in a GitHub secret.

  • Architecture: the app is built for the architecture of the Python that runs the build (usually x86-64). An x86-64 build also runs on Windows on ARM through emulation.
  • Paths: Windows paths in pyproject.toml use forward slashes (assets/icon.ico); that works on every system.
  • Antivirus: if an antivirus quarantines the app, prefer the folder build, sign it, and report the false positive to the vendor.