Denne guide beskriver hvordan man bygger OptiScaler-GUI til en standalone executable med PyInstaller, samt løsninger på almindelige problemer der opstår.
python -m PyInstaller build_executable.spec --cleanpython -m PyInstaller build_executable.specpython -m PyInstaller build_executable.spec --clean --noconfirmpython -m PyInstaller build_executable.spec --noconfirm💡 Tip: Brug altid
--noconfirmfor at undgå manuel bekræftelse når dist directory overskrives!
Efter successful build findes filerne i:
- Single file:
dist\OptiScaler-GUI.exe(~123 MB) - Portable:
dist\OptiScaler-GUI-Portable\(folder med alle filer)
Symptom:
Failed to scan games: [WinError 3] Den angivne sti blev ikke fundet: 'C:\Users\...\utils\robust_wrapper.py'
Løsning:
Implementeret PyInstaller-specifik wrapper i src/gui/widgets/game_list_frame.py:
# PyInstaller-aware import system
RUNNING_IN_PYINSTALLER = getattr(sys, 'frozen', False)
if RUNNING_IN_PYINSTALLER:
# Use SimpleGameWrapper for PyInstaller
class SimpleGameWrapper:
def safe_operation(self, operation, path):
# Simple file-based check for OptiScaler
def _fallback_is_installed(self, path):
# Basic DLL detection
robust_wrapper = SimpleGameWrapper()
else:
# Normal development import
from utils.robust_wrapper import robust_wrapperSymptom:
Knapper viser [ui.install_optiscaler] og [ui.open_folder] i stedet for korrekt tekst
Løsning:
PyInstaller-kompatibel path handling i src/utils/translation_manager.py:
# PyInstaller-compatible path handling
if getattr(sys, 'frozen', False):
# PyInstaller environment
bundle_dir = Path(sys._MEIPASS)
self.translations_dir = bundle_dir / 'src' / 'translations'
else:
# Development environment
self.translations_dir = Path(__file__).parent.parent / "translations"Symptom: Import fejl for utils moduler
Løsning: PyInstaller-kompatibel path setup i alle utils filer:
def setup_paths():
"""Setup paths for both development and PyInstaller environments"""
if getattr(sys, 'frozen', False):
# PyInstaller environment
bundle_dir = Path(sys._MEIPASS)
src_dir = bundle_dir / 'src'
else:
# Development environment
current_dir = Path(__file__).parent
src_dir = current_dir.parent
if str(src_dir) not in sys.path:
sys.path.insert(0, str(src_dir))
return src_dir
setup_paths()Symptom:
ValueError: Something went wrong converting icon image 'xbox_logo.png' to '.ico'
Løsning:
I build_executable.spec sæt:
icon=NoneVigtige Hidden Imports
I build_executable.spec skal disse hidden imports være inkluderet:
hiddenimports=[
# GUI dependencies
'customtkinter', 'tkinter', '_tkinter', 'PIL', 'PIL._tkinter_finder', 'CTkMessagebox',
# Archive extraction
'py7zr', 'py7zr.helpers', 'py7zr.exceptions',
# Utils modules
'utils.robust_wrapper', 'utils.translation_manager', 'utils.debug',
'utils.config', 'utils.cache_manager', 'utils.progress',
'utils.update_manager', 'utils.compatibility_checker', 'utils.archive_extractor',
'utils.i18n', 'utils.logging_utils',
# GUI modules
'gui.widgets.game_list_frame', 'gui.widgets.dynamic_setup_frame',
# Scanner modules
'scanner.game_scanner',
# OptiScaler modules
'optiscaler.manager',
# System utilities
'psutil', 'requests', 'winreg', 'json',
],Vigtige data filer der skal inkluderes:
datas=[
# Include translations
(str(src_dir / 'translations'), 'src/translations'),
# Include assets
('assets', 'assets'),
# Include cache directory structure (empty)
('cache', 'cache'),
# Include requirements file
('requirements.txt', '.'),
# Include README
('README.md', '.'),
],- ✅ Game scanning
- ✅ OptiScaler installation/deinstallation
- ✅ Archive extraction (7z/ZIP)
- ✅ Robust error handling
- ✅ Debug logging
- ✅ Game scanning
- ✅ Installation status tjek (via DLL detection)
- ✅ Archive extraction (7z/ZIP)
- ❌ OptiScaler installation (sikkerhedsbesked)
- ❌ OptiScaler deinstallation (sikkerhedsbesked)
import sys
if getattr(sys, 'frozen', False):
print("Running in PyInstaller")
print(f"Bundle dir: {sys._MEIPASS}")
else:
print("Running in development")2. Tjek Hidden Imports
Hvis moduler mangler, tilføj dem til hiddenimports i spec filen.
Hvis assets mangler, tilføj dem til datas i spec filen.
Ved mærkelige fejl, kør altid:
python -m PyInstaller build_executable.spec --clean --noconfirmBrug --noconfirm for at undgå "Continue? (y/N)" spørgsmål når dist directory overskrives:
python -m PyInstaller build_executable.spec --noconfirmDette er især nyttigt i scripts eller automatiserede builds.
- Fordele: En enkelt fil, nem at distribuere
- Ulemper: Langsommere opstart (udpakker til temp hver gang)
- Størrelse: ~123 MB
- Fordele: Hurtigere opstart, alle filer synlige
- Ulemper: Mange filer at distribuere
- Størrelse: Samme indhold, bare udpakket
- Tilføj til
hiddenimportsibuild_executable.spec - Sikr PyInstaller-kompatibel path setup
- Test både development og PyInstaller mode
- Overvej om det skal virke i PyInstaller mode
- Implementer fallback hvis nødvendigt
- Test thoroughly på begge modes
Før release, tjek at:
- Build kompletter uden fejl
- Executable starter uden crashes
- Game scanning virker
- Installation status vises korrekt
- Archive extraction virker (hvis relevant)
- Ingen "file not found" fejl i logs
build_executable.spec- PyInstaller konfigurationbuild.py- Build script med error handlingsrc/gui/widgets/game_list_frame.py- PyInstaller compatibility wrappersrc/utils/- Alle moduler med PyInstaller path setup
Sidste opdatering: 29. juli 2025 Testet med: PyInstaller 6.14.2, Python 3.12.7