Build a standalone app¶
Ship the app without requiring Python on the target machine, using PyInstaller.
PyInstaller does not cross-compile
Build on the OS you want to target. A Windows .exe must be built on
Windows; a macOS .app must be built on macOS.
Build it¶
The bundled app appears in dist/:
| Platform | Output |
|---|---|
| Windows | dist/DontLockMyPC.exe (windowed, no console) |
| macOS | dist/DontLockMyPC.app |
What the spec does¶
dontlockpc.spec is checked into the repo so builds are reproducible. It:
- Uses
src/dontlockpc/__main__.pyas the entry point, withpathex=["src"] - Builds windowed (no console window on launch)
-
Declares hidden imports PyInstaller can't detect on its own:
pystray picks its platform backend dynamically, so it must be named
explicitly — otherwise the frozen app fails at startup with a tray import
error.
Automated releases¶
Pushing a version tag builds both platforms and publishes a GitHub Release automatically:
The release workflow then:
- Builds on
windows-latestandmacos-latestin parallel - Zips the results into
DontLockMyPC-windows.zip/DontLockMyPC-macos.zip - Attaches both to a GitHub Release with generated release notes
That's what the download buttons on this site point at — always the latest release.
Troubleshooting builds¶
Antivirus / SmartScreen flags the .exe
Unsigned PyInstaller binaries are a common false positive because the bootstrapper unpacks itself at runtime. Options: build it yourself, run from source, or code-sign the executable.
ModuleNotFoundError for pystray or PIL at runtime
A hidden import is missing. Add it to hidden_imports in
dontlockpc.spec and rebuild.
macOS says the .app is damaged
Gatekeeper quarantines unsigned downloads. Clear it with:
The build is very large
Expected — the bundle contains the Python interpreter, Tk, and Pillow. Roughly 30-60 MB compressed is normal.
Next: Development