HUGE OPTIMIZATIONS!
BuzzInstaller 1.1.0 — Release Notes
Executive Summary
This release delivers two major improvements: a 81% reduction in executable size for both BuzzInstaller.exe and BuzzInstallerInstaller.exe, and critical stability fixes for the PyInstaller onefile cleanup, background process lifecycle, and Windows shortcut integration.
1. Executable Size Comparison
BuzzInstaller.exe
| Metric | Before | After | Change |
|---|---|---|---|
| Size (bytes) | 256,744,993 | 49,408,266 | -207,336,727 |
| Size (MiB) | ~245 MiB | ~47 MiB | -81% |
BuzzInstallerInstaller.exe
| Metric | Before | After | Change |
|---|---|---|---|
| Size (bytes) | ~250,000,000 | 46,773,568 | -203,226,432 |
| Size (MiB) | ~240 MiB | ~45 MiB | -81% |
Combined savings: ~410 MB across both executables
Why was it so large?
Both build scripts used --collect-all PySide6, which instructs PyInstaller to bundle every PySide6 module and plugin — including dozens of optional Qt modules that neither application uses:
- QtWebEngine (~70 MB) — full Chromium browser engine
- Qt3D (~30 MB) — 3D rendering framework
- QtQuick/QtQml/QtDeclarative (~20 MB) — QML engine
- QtCharts + QtDataVisualization (~15 MB) — data visualization
- QtPdf (~10 MB) — PDF rendering
- QtBluetooth/QtNfc/QtSerialPort/QtSensors (~15 MB) — hardware interfaces
- QtQuick3D/QtSpatialAudio/QtMultimedia/QtWebSockets (~25 MB) — multimedia/3D/audio
- Plus ~30 more optional modules
Neither BuzzInstaller nor BuzzInstallerInstaller uses any of these — both are pure QtWidgets applications (buttons, labels, progress bars, file dialogs).
What changed
src/BuzzInstaller/build/build_exe.py and src/BuzzInstallerInstaller/build/build_installer.py:
- Removed
--collect-all PySide6— the primary fix - PyInstaller's standard
hook-PySide6.pynow collects only the actually imported modules (QtWidgets, QtCore, QtGui, QtNetwork) plus the required Qt plugins (platforms, imageformats, styles) - Removed unnecessary hidden imports (
PySide6.QtXml,PySide6.QtMultimedia) from BuzzInstaller - Added
system.background_launcherto hidden imports (new module from the handoff fix) - No functionality was removed — no modules were excluded because they were large; they were simply no longer force-collected when not imported
2. Fixes in this Release
Fix 1: PyInstaller "_MEI" Temporary Directory Cleanup Warning
Problem: When BuzzInstaller.exe (PyInstaller onefile) spawned --background, the child's bootloader inherited the parent's _MEIPASS2 environment variable and reused the parent's _MEI* extraction directory. The background process is intentionally long-lived, so it kept Qt DLLs loaded from the parent's directory — locking it. When the foreground exited, PyInstaller failed with:
Failed to remove temporary directory:
C:\Users\elial\AppData\Local\Temp\_MEIxxxxxx
Solution — background handoff mechanism:
src/BuzzInstaller/system/background_launcher.py (NEW):
- A short-lived intermediary that waits for the foreground process to fully exit (via
WaitForSingleObject— no fixed delays, no busy-wait) - Imports ONLY the standard library — holds no files from the parent's
_MEI*directory - Strips
_MEIPASS2from the environment when launching the final--backgroundprocess
src/BuzzInstaller/system/background_service.py (MODIFIED):
- In frozen mode,
--backgroundis never spawned directly from the foreground - Instead,
_launch_background_via_launcher()uses PowerShell as the intermediary (sincesys.executableis the bundled exe, not python): waits viaWait-Processfor the foreground PID, sets$env:_MEIPASS2 = $null, then launchesBuzzInstaller.exe --backgroundwith-WindowStyle Hidden - Non-background launches (download UI) still spawn directly with
_MEIPASS2stripped - Source mode still spawns directly (no launcher needed)
Fix 2: Clean Shutdown Behavior
src/BuzzInstaller/core/buzzheavier_api.py (MODIFIED):
- Added
BuzzHeavierAPI.close()to release therequests.Session(connection pools/sockets) before process exit - Fixed
get_download_url()to close HTTP responses withresp.close()in afinallyblock
src/BuzzInstaller/main.py (MODIFIED):
run_upload(): Addedservice.api.close()in worker'sfinallyblock; thread join afterapp.exec()run_download(): Addedworker_doneEvent,service.api.close()infinallyblock; thread join afterapp.exec()- Background mode: shutdown logging around
svc.run()andsvc.stop() __main__: exit logging
Fix 3: Windows Shortcut Creation
src/BuzzInstallerInstaller/shortcut.py (NEW):
create_shortcut(),delete_shortcut(),get_shortcut_target()using PowerShell's WScript.Shell COM — creates real.lnkfiles, not text
src/BuzzInstallerInstaller/installer.py (MODIFIED):
create_shortcut_for_installed()createsC:\BuzzInstaller\BuzzInstaller.lnkafter install/update — non-fatal on permission failuredelete_buzzinstaller()removes the shortcut, and only removesC:\BuzzInstallerif empty (unrelated files preserved)
3. Verification Results
| Check | Result |
|---|---|
| Version tests | ✅ 10/10 PASS |
| Installer tests | ✅ 24/24 PASS |
| Improvements tests | ✅ 19/19 PASS |
| Shortcut tests | ✅ 13/13 PASS |
| Background handoff tests | ✅ 8/8 PASS |
| Total tests | 74/74 PASS |
| BuzzInstaller.exe --version | ✅ "BuzzInstaller 1.1.0" |
| BuzzInstaller.exe --background | ✅ Idle event loop running |
| BuzzInstallerInstaller.exe UI | ✅ Launched, real Qt GUI (69 MB working set) |
| Build compile checks | ✅ All modified files compile |