# Baut VersaPadViewer.exe (PyInstaller --onedir) und kopiert das Ergebnis # nach %LOCALAPPDATA%\VersaPadViewer (nicht $projectDir\dist wie im # jappel-Upstream -- hier bereits die tatsaechlich installierte/genutzte # Instanz, siehe Speicher-Notiz "VersaPad Viewer Tool"; ein Pfadwechsel # wuerde bestehende Verknuepfungen/Autostart-Eintraege brechen). # # WICHTIG: Sowohl Bauen als auch Laufen muessen lokal passieren, NICHT auf # dem Netzlaufwerk (Z:\Git\...): # - Laufzeit: Windows blockiert das Nachladen der PyInstaller-_internal- # DLLs von einem Netzwerkpfad (SMB-Share) ohne jede Fehlermeldung, der # Prozess startet einfach nie. # - Buildzeit: PyInstaller scheitert beim Kopieren von Tcl/Tk-tzdata (viele # tief verschachtelte, lang benannte Zeitzonen-Ordner) mit # "FileNotFoundError: [WinError 3]" -- Pfadlaengen-Problem auf dem # SMB-Share, kombiniert mit dem eh schon langen Projektpfad. # # Deshalb: Quellcode zuerst nach lokal (%TEMP%) kopieren, dort bauen, danach # das fertige Bundle nach $projectDir\dist kopieren. Z: wird nur zum Lesen # der Quelldateien angefasst. # # Fehlerverhalten: Bei Doppelklick im Explorer schliesst sich das Fenster # sofort nach Skriptende -- ohne Pause waeren Fehlermeldungen unsichtbar # ("stirbt ohne jede Fehlermeldung"). Deshalb: alles in try/catch, im # Fehlerfall UND am Ende eine Pause, ausser bei -NoPause (fuer CI/Automation). param( [switch]$NoPause ) $ErrorActionPreference = "Stop" $projectDir = $PSScriptRoot $buildSrc = "$env:TEMP\versapad_build_src" $localDir = "$env:LOCALAPPDATA\VersaPadViewer" $requirementsFile = "$projectDir\requirements.txt" function Assert-LastExitCode([string]$step) { if ($LASTEXITCODE -ne 0) { throw "$step ist fehlgeschlagen (Exit-Code $LASTEXITCODE) -- Ausgabe oben pruefen." } } function Wait-ForKeyIfInteractive { if ($NoPause) { return } try { Read-Host "Taste druecken zum Schliessen" } catch { # z.B. nicht-interaktiver Aufruf (stdin nicht verfuegbar) -- einfach ignorieren } } try { Write-Host "Pruefe Python-Installation..." py --version Assert-LastExitCode "'py --version' (ist Python installiert und im PATH?)" if (-not (Test-Path $requirementsFile)) { throw "requirements.txt nicht gefunden unter $requirementsFile" } Write-Host "Installiere/aktualisiere benoetigte Pakete aus requirements.txt..." py -m pip install --quiet --disable-pip-version-check -r $requirementsFile Assert-LastExitCode "Paketinstallation (pip install -r requirements.txt)" if (Test-Path $buildSrc) { Remove-Item $buildSrc -Recurse -Force } New-Item -ItemType Directory -Path $buildSrc | Out-Null Copy-Item "$projectDir\*.py" -Destination $buildSrc Copy-Item "$projectDir\icon.ico" -Destination $buildSrc Copy-Item "$projectDir\icon.png" -Destination $buildSrc Push-Location $buildSrc try { Write-Host "Baue mit PyInstaller (--onedir --windowed)..." py -m PyInstaller --windowed --onedir --name VersaPadViewer ` --icon icon.ico --add-data "icon.png;." --add-data "icon.ico;." ` desktop_viewer.py --noconfirm Assert-LastExitCode "PyInstaller-Build" } finally { Pop-Location } if (-not (Test-Path "$buildSrc\dist\VersaPadViewer\VersaPadViewer.exe")) { throw "PyInstaller hat keine VersaPadViewer.exe erzeugt, obwohl der Exit-Code 0 war -- Build-Ausgabe oben pruefen." } # Zielverzeichnis abraeumen, aber NIE Nutzerdaten mitloeschen: die Config # liegt zwar inzwischen woanders (Roaming-AppData, siehe # versapad_data.app_dir()), aeltere Installationen haben sie aber noch # hier liegen -- ohne diese Sicherung loescht jeder Rebuild sie mit # (am 2026-08-15 genau so passiert, alle Notizen weg). $userData = Get-ChildItem $localDir -Filter "versapad_config*.json" -File -ErrorAction SilentlyContinue $rescued = @() foreach ($f in $userData) { $tmp = Join-Path $env:TEMP $f.Name Copy-Item $f.FullName $tmp -Force $rescued += @{ Tmp = $tmp; Name = $f.Name } Write-Host "Nutzerdatei gesichert: $($f.Name)" -ForegroundColor Yellow } if (Test-Path $localDir) { Remove-Item $localDir -Recurse -Force } Copy-Item "$buildSrc\dist\VersaPadViewer" -Destination $localDir -Recurse foreach ($r in $rescued) { Copy-Item $r.Tmp (Join-Path $localDir $r.Name) -Force Remove-Item $r.Tmp -Force } Remove-Item $buildSrc -Recurse -Force Write-Host "" Write-Host "Fertig: $localDir\VersaPadViewer.exe" -ForegroundColor Green Wait-ForKeyIfInteractive } catch { Write-Host "" Write-Host "FEHLER: $($_.Exception.Message)" -ForegroundColor Red Wait-ForKeyIfInteractive exit 1 }