INSTALLIEREN.bat
Rama main · réplica de lectura del repositorio original.
@echo off
:: v1.8.0 (#1149 Punkt 8): Ein Ausrufezeichen im Ordnernamen (z.B. "Bewerbung!") verschwindet unter der verzoegerten
:: Expansion aus jedem Pfad, der aus %~dp0 gebildet wird: der Installer suchte src\ in einem Ordner, den es nicht gibt,
:: und meldete "ZIP nicht entpackt". Geprueft wird deshalb, BEVOR die verzoegerte Expansion eingeschaltet wird;
:: danach koennte man das Zeichen nicht mehr sehen.
setlocal DisableDelayedExpansion
set "PBP_START_ORT=%~dp0"
if "%PBP_START_ORT:!=%"=="%PBP_START_ORT%" goto :ort_ohne_ausrufezeichen
echo.
echo ****************************************************
echo * FEHLER: Der Ordnername enthaelt ein Ausrufe- *
echo * zeichen *
echo ****************************************************
echo.
echo Windows kann PBP aus diesem Ordner nicht einrichten:
echo %PBP_START_ORT%
echo.
echo SO GEHT ES WEITER:
echo 1. Verschiebe den entpackten Ordner an einen Ort ohne
echo Ausrufezeichen im Namen, z.B. nach C:\PBP
echo 2. Starte INSTALLIEREN.bat dort noch einmal
echo.
pause
exit /b 1
:ort_ohne_ausrufezeichen
:: v1.8.0 (#1207): dieselbe Pruefung fuer die Orte, aus denen der Installer seine Pfade bildet (Profil, Daten, TEMP). Ein "!"
:: im Windows-Profil verschwindet unter der verzoegerten Expansion ebenso: der Installer rechnete mit einem Ordner, den es nicht
:: gibt, und scheiterte erst nach dem Download am Schreibrecht. Gedruckt wird mit `set PBP_ORT_` (zeigt die Werte, ohne dass ein
:: "&" im Namen als Befehl gelesen wird) - ein eigenes setlocal gibt es hier nicht: PP19 verlangt, dass das erste
:: `setlocal EnableDelayedExpansion` der Datei das einzige bleibt.
set "PBP_ORT_1=%LOCALAPPDATA%"
set "PBP_ORT_2=%TEMP%"
set "PBP_ORT_3=%USERPROFILE%"
set "PBP_PROFIL_ORTE=%LOCALAPPDATA%%TEMP%%USERPROFILE%"
if "%PBP_PROFIL_ORTE:!=%"=="%PBP_PROFIL_ORTE%" goto :profil_ohne_ausrufezeichen
echo.
echo ****************************************************
echo * FEHLER: Dein Windows-Profil enthaelt ein *
echo * Ausrufezeichen *
echo ****************************************************
echo.
echo PBP legt seine Ordner in deinem Windows-Profil an. Geprueft habe ich:
set PBP_ORT_
echo Mit einem Ausrufezeichen im Namen verliert Windows das Zeichen
echo und der Installer wuerde einen Ordner suchen, den es nicht gibt.
echo.
echo SO GEHT ES WEITER:
echo 1. Melde dich mit einem Windows-Konto ohne Ausrufezeichen
echo im Namen an (oder lege eines an)
echo 2. Starte INSTALLIEREN.bat dort noch einmal
echo.
pause
exit /b 1
:profil_ohne_ausrufezeichen
endlocal
setlocal EnableDelayedExpansion
title PBP - Persoenliches Bewerbungs-Portal - Setup
color 0F
:: -------------------------------------------
:: PBP Installer
::
:: Versionsanzeige im UI ist DYNAMISCH — wird aus
:: src/bewerbungs_assistent/__init__.py gelesen (PBP_VERSION).
::
:: v1.7.0-beta.18:
:: - Claude-Desktop-Erkennung erweitert (PATH, laufender Prozess)
:: - Hinweis wenn Claude laeuft (sauber beenden fuer Konfig-Reload)
:: - Header zeigt dynamische Version statt hardgekodet
:: v1.6.0:
:: - Erkennung wenn BAT aus ZIP heraus gestartet wird
:: - Fehler-melden Hinweis bei allen Fehlern
:: - setuptools+wheel vor extract-msg (embeddable Python)
:: - Dashboard + Startdateien nach DATA_DIR kopieren
:: - Desktop-Shortcut zeigt auf DATA_DIR (stabil)
:: -------------------------------------------
:: Variablen
set "BASEDIR=%~dp0"
if "%BASEDIR:~-1%"=="\" set "BASEDIR=%BASEDIR:~0,-1%"
set "PYTHON_DIR=%BASEDIR%\python"
set "PYTHON=%PYTHON_DIR%\python.exe"
set "BASE_INSTALL=%LOCALAPPDATA%\BewerbungsAssistent"
set "APP_DIR=%BASE_INSTALL%\app"
set "DATA_DIR=%BASE_INSTALL%\data"
set "SRC_DIR=%BASEDIR%\src"
set "LOGFILE=%BASEDIR%\install_log.txt"
:: Version dynamisch aus __init__.py lesen (#344)
set "PBP_VERSION=unknown"
if exist "%SRC_DIR%\bewerbungs_assistent\__init__.py" (
for /f "tokens=3 delims= " %%v in ('findstr /C:"__version__" "%SRC_DIR%\bewerbungs_assistent\__init__.py" 2^>nul') do set "PBP_VERSION=%%~v"
)
:: Python Embeddable Download
set "PY_VERSION=3.12.10"
set "PY_ZIP=python-%PY_VERSION%-embed-amd64.zip"
set "PY_URL=https://www.python.org/ftp/python/%PY_VERSION%/%PY_ZIP%"
set "GETPIP_URL=https://bootstrap.pypa.io/get-pip.py"
:: -------------------------------------------
:: Integritaets-Check: Wurde das ZIP richtig entpackt?
:: v1.7.0-beta.18: zusaetzlich pruefen ob die Setup-Helper-Skripte
:: vorhanden sind — falls nicht, klare Fehlermeldung mit Hinweis,
:: wo das Problem liegt.
:: -------------------------------------------
if not exist "%SRC_DIR%" goto :err_not_extracted
if not exist "%BASEDIR%\_setup_claude.py" goto :err_setup_helper_missing
if not exist "%BASEDIR%\_selftest.py" goto :err_setup_helper_missing
if not exist "%BASEDIR%\_sicherung_vor_update.py" goto :err_setup_helper_missing
if not exist "%BASEDIR%\start_dashboard.py" goto :err_setup_helper_missing
:: v1.8.0 (#1093): Versionsordner und Aufraeumen
if not exist "%BASEDIR%\_programm_einrichten.py" goto :err_setup_helper_missing
if not exist "%BASEDIR%\_installer_aufraeumen.py" goto :err_setup_helper_missing
if not exist "%BASEDIR%\installer\boot\start_dashboard_launcher.py" goto :err_setup_helper_missing
:: -------------------------------------------
:: Logging initialisieren
:: -------------------------------------------
if exist "%LOGFILE%" for %%F in ("%LOGFILE%") do if %%~zF GTR 1000000 del "%LOGFILE%" 2>nul
echo ================================================== >> "%LOGFILE%"
echo PBP Installer (Version aus __init__.py) - %date% %time% >> "%LOGFILE%"
echo System: %OS% %PROCESSOR_ARCHITECTURE% >> "%LOGFILE%"
echo User: %USERNAME% >> "%LOGFILE%"
echo Pfad: %BASEDIR% >> "%LOGFILE%"
echo ================================================== >> "%LOGFILE%"
echo.
echo ====================================================
echo.
echo PBP - Persoenliches Bewerbungs-Portal
echo Dein KI-Bewerbungshelfer
echo Version: %PBP_VERSION%
echo.
echo ====================================================
echo.
echo Willkommen^^! Dieses Setup richtet ALLES automatisch ein.
echo Du musst NICHTS selber installieren oder konfigurieren.
echo Einfach warten - alles passiert von alleine.
echo.
echo Was du brauchst:
echo - Internetverbindung
echo - Claude Desktop ^(claude.ai/download^)
echo.
echo Was jetzt automatisch passiert:
echo 1. Python wird heruntergeladen und eingerichtet
echo 2. Alle Pakete werden installiert
echo 3. Claude Desktop wird konfiguriert
echo 4. Fertig - du kannst sofort loslegen
echo.
echo Dauer: ca. 3-5 Minuten
echo.
echo ****************************************************
echo * WICHTIG: Dieses Fenster NICHT schliessen! *
echo * Einfach warten bis "FERTIG" erscheint. *
echo ****************************************************
echo.
:: -------------------------------------------
:: Versions-Check: Ist die aktuelle Version schon installiert?
:: -------------------------------------------
echo [DEBUG] Versions-Check... >> "%LOGFILE%"
:: v1.7.149 (#1149): gelesen wurde %DATA_DIR%\src, installiert wird aber nach %APP_DIR%\src (seit
:: v1.5.0, #297). INSTALLED_VER blieb deshalb immer leer: "Update erkannt" und "bereits
:: installiert" erschienen nie, und die Frage unten kannte nur "j", nicht "ja".
:: v1.8.0 (#1093): seit dem Aufbau mit Versionsordnern steht die installierte Fassung in aktuell.txt;
:: nur ein Aufbau aus der 1.7er-Linie hat sie noch in src\.
set "INSTALLED_VER="
if exist "%APP_DIR%\aktuell.txt" set /p INSTALLED_VER=<"%APP_DIR%\aktuell.txt"
if not defined INSTALLED_VER if exist "%APP_DIR%\src\bewerbungs_assistent\__init__.py" (
for /f "tokens=3 delims= " %%v in ('findstr /C:"__version__" "%APP_DIR%\src\bewerbungs_assistent\__init__.py" 2^>nul') do set "INSTALLED_VER=%%~v"
)
if defined INSTALLED_VER (
for /f "tokens=3 delims= " %%v in ('findstr /C:"__version__" "%SRC_DIR%\bewerbungs_assistent\__init__.py" 2^>nul') do set "NEW_VER=%%~v"
if defined INSTALLED_VER if defined NEW_VER if "!INSTALLED_VER!"=="!NEW_VER!" (
echo [INFO] Version !INSTALLED_VER! ist bereits installiert >> "%LOGFILE%"
echo.
echo Version !INSTALLED_VER! ist bereits installiert.
echo.
set /p FORCE_INSTALL=" Trotzdem neu installieren? (j/n): "
set "FORCE_INSTALL=!FORCE_INSTALL:~0,1!"
if /i "!FORCE_INSTALL!" neq "j" if /i "!FORCE_INSTALL!" neq "y" (
echo.
echo Installation abgebrochen. Aktuelle Version laeuft bereits.
echo.
pause
exit /b 0
)
echo [INFO] Erzwinge Neuinstallation >> "%LOGFILE%"
) else (
echo [INFO] Update: !INSTALLED_VER! auf !NEW_VER! >> "%LOGFILE%"
echo.
echo Update erkannt: !INSTALLED_VER! wird auf !NEW_VER! aktualisiert.
echo.
)
)
:: -------------------------------------------
:: SCHRITT 1: Python pruefen / herunterladen
:: -------------------------------------------
echo [1/4] Python einrichten...
echo [1/4] Python einrichten... >> "%LOGFILE%"
:: Python bereits vorhanden? (1. im ZIP-Ordner, 2. in APP_DIR, 3. in DATA_DIR von frueherer Installation)
if exist "%PYTHON%" goto :python_ready
:: #350: Fruehere Installation in APP_DIR vorhanden? (dort wird Python seit v1.5.0 installiert)
if exist "%APP_DIR%\python\python.exe" (
echo [INFO] Python aus frueherer Installation gefunden: !APP_DIR!\python >> "%LOGFILE%"
echo Python aus frueherer Installation gefunden.
if not exist "%PYTHON_DIR%" mkdir "%PYTHON_DIR%"
xcopy "%APP_DIR%\python" "%PYTHON_DIR%\" /E /I /Q /Y >> "%LOGFILE%" 2>&1
if exist "%PYTHON%" goto :python_ready
echo [WARN] Kopie fehlgeschlagen >> "%LOGFILE%"
)
:: Fallback: Fruehere Installation in DATA_DIR vorhanden? (aeltere Versionen)
if exist "%DATA_DIR%\python\python.exe" (
echo [INFO] Python aus frueherer Installation gefunden: !DATA_DIR!\python >> "%LOGFILE%"
echo Python aus frueherer Installation gefunden.
if not exist "%PYTHON_DIR%" mkdir "%PYTHON_DIR%"
xcopy "%DATA_DIR%\python" "%PYTHON_DIR%\" /E /I /Q /Y >> "%LOGFILE%" 2>&1
if exist "%PYTHON%" goto :python_ready
echo [WARN] Kopie fehlgeschlagen, lade Python neu herunter >> "%LOGFILE%"
)
:: --- Python muss heruntergeladen werden ---
:download_python
echo.
echo Python wird heruntergeladen und eingerichtet...
echo Einfach warten!
echo.
:: 64-Bit pruefen
echo [DEBUG] Pruefe Architektur... >> "%LOGFILE%"
if "%PROCESSOR_ARCHITECTURE%"=="x86" if not defined PROCESSOR_ARCHITEW6432 goto :err_32bit
echo [DEBUG] Architektur OK >> "%LOGFILE%"
:: Curl pruefen
echo [DEBUG] Pruefe curl... >> "%LOGFILE%"
where curl.exe >nul 2>&1
if !errorlevel! neq 0 goto :no_curl
echo [OK] curl.exe gefunden >> "%LOGFILE%"
set "USE_CURL=1"
goto :curl_ok
:no_curl
echo [INFO] curl.exe nicht gefunden, nutze PowerShell >> "%LOGFILE%"
set "USE_CURL=0"
:curl_ok
:: Verzeichnis erstellen
echo [DEBUG] Erstelle python-Verzeichnis... >> "%LOGFILE%"
if not exist "%PYTHON_DIR%" mkdir "%PYTHON_DIR%"
echo [DEBUG] python-Verzeichnis: %PYTHON_DIR% >> "%LOGFILE%"
:: Download
set "PY_ZIP_PATH=%BASEDIR%\%PY_ZIP%"
echo Lade Python %PY_VERSION% herunter ^(ca. 11 MB^)...
echo [INFO] Download: %PY_URL% >> "%LOGFILE%"
echo [DEBUG] Ziel: %PY_ZIP_PATH% >> "%LOGFILE%"
if "!USE_CURL!"=="0" goto :download_ps
echo [DEBUG] Starte curl Download... >> "%LOGFILE%"
curl.exe -L --progress-bar -o "%PY_ZIP_PATH%" "%PY_URL%"
echo [DEBUG] curl beendet, errorlevel=!errorlevel! >> "%LOGFILE%"
goto :download_done
:download_ps
echo [DEBUG] Starte PowerShell Download... >> "%LOGFILE%"
powershell -ExecutionPolicy Bypass -NoProfile -Command "[Net.ServicePointManager]::SecurityProtocol=[Net.ServicePointManager]::SecurityProtocol -bor 3072; Invoke-WebRequest -Uri '%PY_URL%' -OutFile $env:PY_ZIP_PATH" 2>> "%LOGFILE%"
echo [DEBUG] PowerShell beendet, errorlevel=!errorlevel! >> "%LOGFILE%"
:download_done
echo [DEBUG] Pruefe ob ZIP existiert: %PY_ZIP_PATH% >> "%LOGFILE%"
if not exist "%PY_ZIP_PATH%" goto :err_download
echo [OK] Python heruntergeladen
echo [OK] Python heruntergeladen >> "%LOGFILE%"
:: --- Entpacken ---
echo [DEBUG] Starte Entpacken... >> "%LOGFILE%"
echo Entpacke Python...
echo [INFO] Entpacke %PY_ZIP_PATH% nach %PYTHON_DIR% >> "%LOGFILE%"
:: PowerShell Expand-Archive (zuverlaessiger als tar fuer ZIP)
echo [DEBUG] Rufe PowerShell Expand-Archive auf... >> "%LOGFILE%"
powershell -ExecutionPolicy Bypass -NoProfile -Command "Expand-Archive -LiteralPath $env:PY_ZIP_PATH -DestinationPath $env:PYTHON_DIR -Force" 2>> "%LOGFILE%"
echo [DEBUG] Expand-Archive beendet, errorlevel=!errorlevel! >> "%LOGFILE%"
:: Pruefen ob python.exe existiert
echo [DEBUG] Pruefe python.exe in: %PYTHON% >> "%LOGFILE%"
if not exist "%PYTHON%" goto :err_extract
echo [OK] python.exe gefunden >> "%LOGFILE%"
:: ZIP aufraeumen
del "%PY_ZIP_PATH%" 2>nul
echo [OK] Python %PY_VERSION% entpackt
echo [OK] Python %PY_VERSION% entpackt >> "%LOGFILE%"
:: --- _pth konfigurieren ---
echo [DEBUG] Konfiguriere _pth... >> "%LOGFILE%"
echo Konfiguriere Python...
set "PTH_FILE="
for %%f in ("%PYTHON_DIR%\python*._pth") do set "PTH_FILE=%%f"
if not defined PTH_FILE goto :pth_done
echo [DEBUG] PTH: !PTH_FILE! >> "%LOGFILE%"
:: import site entkommentieren
powershell -ExecutionPolicy Bypass -NoProfile -Command "(Get-Content -LiteralPath $env:PTH_FILE) -replace '^#import site','import site' | Set-Content -LiteralPath $env:PTH_FILE" 2>> "%LOGFILE%"
:: ../src Pfad hinzufuegen
findstr /C:"../src" "!PTH_FILE!" >nul 2>&1
if !errorlevel! neq 0 echo ../src>> "!PTH_FILE!"
echo [OK] _pth konfiguriert >> "%LOGFILE%"
:pth_done
:: --- pip installieren ---
echo [DEBUG] Starte pip-Installation... >> "%LOGFILE%"
echo Installiere Paketmanager ^(pip^)...
set "GETPIP_PATH=%PYTHON_DIR%\get-pip.py"
echo [DEBUG] Lade get-pip.py... >> "%LOGFILE%"
if "!USE_CURL!"=="0" goto :getpip_ps
curl.exe -sL -o "%GETPIP_PATH%" "%GETPIP_URL%" 2>> "%LOGFILE%"
echo [DEBUG] get-pip curl beendet, errorlevel=!errorlevel! >> "%LOGFILE%"
goto :getpip_done
:getpip_ps
powershell -ExecutionPolicy Bypass -NoProfile -Command "[Net.ServicePointManager]::SecurityProtocol=[Net.ServicePointManager]::SecurityProtocol -bor 3072; Invoke-WebRequest -Uri '%GETPIP_URL%' -OutFile $env:GETPIP_PATH" 2>> "%LOGFILE%"
echo [DEBUG] get-pip PowerShell beendet, errorlevel=!errorlevel! >> "%LOGFILE%"
:getpip_done
echo [DEBUG] Pruefe get-pip.py... >> "%LOGFILE%"
if not exist "%GETPIP_PATH%" goto :err_getpip
echo [DEBUG] Fuehre get-pip.py aus... >> "%LOGFILE%"
:: PP25 (Testlauf 11.10.2026): get-pip.py entpackt sich nach TEMP\tmpXXXX\pip.zip und kann das unter Windows nicht selbst
:: loeschen (die Datei ist noch geladen) - 1,7 MB blieben nach jeder Installation liegen. Ein eigener, kurzlebiger
:: Temp-Ordner nimmt den Rest auf und wird danach geloescht.
call :pip_beschaffen
if !errorlevel! neq 0 goto :err_pip
echo [OK] Python + pip bereit
echo [OK] pip installiert >> "%LOGFILE%"
:: Sicherheitsblockade entfernen
echo [DEBUG] Unblock-File... >> "%LOGFILE%"
powershell -ExecutionPolicy Bypass -NoProfile -Command "Get-ChildItem -LiteralPath $env:BASEDIR -Recurse -ErrorAction SilentlyContinue | Unblock-File -ErrorAction SilentlyContinue" >nul 2>&1
:: Python Schnelltest
echo [DEBUG] Python Schnelltest... >> "%LOGFILE%"
"%PYTHON%" -c "print('OK')" >nul 2>&1
if !errorlevel! neq 0 goto :err_python_test
for /f "tokens=*" %%v in ('"%PYTHON%" --version 2^^^>^^^&1') do set PYVER=%%v
echo [OK] !PYVER!
echo [OK] !PYVER! >> "%LOGFILE%"
echo.
goto :install_packages
:: -------------------------------------------
:python_ready
:: Python existiert schon
:: -------------------------------------------
echo [DEBUG] Python existiert bereits >> "%LOGFILE%"
powershell -ExecutionPolicy Bypass -NoProfile -Command "Get-ChildItem -LiteralPath $env:BASEDIR -Recurse -ErrorAction SilentlyContinue | Unblock-File -ErrorAction SilentlyContinue" >nul 2>&1
echo Teste Python...
"%PYTHON%" -c "print('OK')" >nul 2>&1
if !errorlevel! neq 0 goto :err_python_existing
for /f "tokens=*" %%v in ('"%PYTHON%" --version 2^^^>^^^&1') do set PYVER=%%v
echo [OK] !PYVER!
echo [OK] !PYVER! >> "%LOGFILE%"
:: _pth sicherstellen (import site + ../src)
set "PTH_FILE="
for %%f in ("%PYTHON_DIR%\python*._pth") do set "PTH_FILE=%%f"
if not defined PTH_FILE goto :pth_ready_done
:: import site muss entkommentiert sein, sonst findet Python pip/site-packages nicht (#386)
findstr /C:"import site" "!PTH_FILE!" >nul 2>&1
if !errorlevel! neq 0 echo import site>> "!PTH_FILE!"
powershell -ExecutionPolicy Bypass -NoProfile -Command "(Get-Content -LiteralPath $env:PTH_FILE) -replace '^#import site','import site' | Set-Content -LiteralPath $env:PTH_FILE" 2>> "%LOGFILE%"
findstr /C:"../src" "!PTH_FILE!" >nul 2>&1
if !errorlevel! neq 0 echo ../src>> "!PTH_FILE!"
echo [OK] _pth konfiguriert >> "%LOGFILE%"
:pth_ready_done
:: pip pruefen
"%PYTHON%" -m pip --version >> "%LOGFILE%" 2>&1
if !errorlevel! neq 0 (
echo [WARN] pip nicht gefunden, versuche Nachinstallation... >> "%LOGFILE%"
call :fix_pip
"%PYTHON%" -m pip --version >> "%LOGFILE%" 2>&1
if !errorlevel! neq 0 (
echo [WARN] pip immer noch defekt - loesche Python und lade neu herunter >> "%LOGFILE%"
echo Kopierte Python-Installation defekt, lade neu herunter...
rmdir /s /q "%PYTHON_DIR%" 2>nul
goto :download_python
)
)
echo [OK] pip vorhanden
echo [OK] pip vorhanden >> "%LOGFILE%"
echo.
:: -------------------------------------------
:install_packages
:: SCHRITT 2: Pakete installieren
:: -------------------------------------------
echo [DEBUG] Starte Paket-Installation >> "%LOGFILE%"
echo [2/4] Installiere PBP...
echo [2/4] Pakete installieren... >> "%LOGFILE%"
echo.
echo Das dauert 1-3 Minuten ^(je nach Internet^).
echo Bitte einfach warten...
echo.
echo Falls ein Fenster erscheint das fragt ob Python
echo auf das Internet zugreifen darf: Bitte "Zugriff
echo erlauben" / "Allow access" klicken!
echo.
:: Internetverbindung testen
echo [DEBUG] Teste Internet... >> "%LOGFILE%"
"%PYTHON%" -c "import urllib.request; urllib.request.urlopen('https://pypi.org/simple/', timeout=10); print('OK')" >> "%LOGFILE%" 2>&1
if !errorlevel! neq 0 goto :internet_retry
:internet_ok
echo [OK] Internet erreichbar >> "%LOGFILE%"
:: Kernpakete installieren
echo [DEBUG] Installiere Kernpakete... >> "%LOGFILE%"
echo Installiere Kernpakete...
:: Kernpakete inkl. geopy (Umkreissuche) und python-jobspy
:: (Indeed/LinkedIn-Booster, Core-Dep seit v1.6.0-beta.16, #500).
:: v1.7.145: Version und Grenzen wie in pyproject.toml. Ohne Grenze holte eine
:: frische Installation FastMCP 4 (seit 09/2026 auf PyPI), das PBP ausschliesst
:: (fastmcp>=3.0,<4); bei einem Update wird eine zu neue Fassung so auch
:: zurueckgesetzt. tests/test_v17145_installer_pakete.py haelt die Listen
:: gegen pyproject.toml.
"%PYTHON%" -m pip install "fastmcp>=3.0,<4" "uvicorn>=0.30" "fastapi>=0.115" "python-multipart>=0.0.9" "httpx>=0.27" "geopy>=2.4" "beautifulsoup4>=4.12" "lxml>=5.0" "python-jobspy>=1.2,<1.4" --no-warn-script-location >> "%LOGFILE%" 2>&1
if !errorlevel! neq 0 goto :err_packages
echo [OK] Kernpakete installiert (inkl. JobSpy + Geopy)
echo [OK] Kernpakete installiert >> "%LOGFILE%"
:: Optionale Pakete - Scraper (Playwright fuer stepstone, freelancermap, etc.)
echo [DEBUG] Optionale Pakete Scraper... >> "%LOGFILE%"
"%PYTHON%" -m pip install "playwright>=1.40" --no-warn-script-location >> "%LOGFILE%" 2>&1
if !errorlevel! equ 0 (
echo [OK] Playwright installiert
echo [DEBUG] Installiere Playwright Browser... >> "%LOGFILE%"
echo Lade Chromium fuer Stepstone/Freelancermap/LinkedIn...
"%PYTHON%" -m playwright install chromium >> "%LOGFILE%" 2>&1
if !errorlevel! equ 0 echo [OK] Job-Scraper komplett installiert
if !errorlevel! neq 0 echo [--] Browser-Download fehlgeschlagen
)
if !errorlevel! neq 0 echo [--] Job-Scraper uebersprungen
:: Optionale Pakete - PDF/Word
echo [DEBUG] Optionale Pakete PDF/Word... >> "%LOGFILE%"
"%PYTHON%" -m pip install "python-docx>=1.1" "fpdf2>=2.7" "pypdf>=4.0" --no-warn-script-location >> "%LOGFILE%" 2>&1
if !errorlevel! equ 0 echo [OK] PDF/Word-Export installiert
if !errorlevel! neq 0 echo [--] PDF/Word-Export uebersprungen
:: Optionale Pakete - Excel-Export und Diagramme (v1.7.145). Ohne openpyxl
:: lieferte der Excel-Knopf im Statistik-Tab eine Fehlermeldung mit einer
:: pip-Anweisung, die der Mensch nicht ausfuehren kann. Eigener Schritt,
:: damit ein Fehler hier den PDF/Word-Export oben nicht beruehrt.
echo [DEBUG] Optionale Pakete Excel/Diagramme... >> "%LOGFILE%"
"%PYTHON%" -m pip install "openpyxl>=3.1" "matplotlib>=3.8" --no-warn-script-location >> "%LOGFILE%" 2>&1
if !errorlevel! equ 0 echo [OK] Excel-Export und Diagramme installiert
if !errorlevel! neq 0 echo [--] Excel-Export/Diagramme uebersprungen
:: Optionale Pakete - Texterkennung fuer Scan-PDFs (E19, #750). Auf main kommen
:: pypdfium2 und pillow aus den Extras [docs]; die Stable-Linie hat sie nicht.
:: Eigener Schritt wie oben: ein Fehler beruehrt PDF/Word und Excel nicht.
echo [DEBUG] Optionale Pakete Texterkennung... >> "%LOGFILE%"
"%PYTHON%" -m pip install "pypdfium2>=4.0" "pillow>=10.0" --no-warn-script-location >> "%LOGFILE%" 2>&1
if !errorlevel! equ 0 echo [OK] Scan-PDFs lesbar vorbereitet
if !errorlevel! neq 0 echo [--] Scan-PDF-Vorbereitung uebersprungen
:: Optionale Pakete - E-Mail/Outlook
echo [DEBUG] Optionale Pakete E-Mail/Outlook... >> "%LOGFILE%"
:: setuptools + wheel muessen VOR extract-msg installiert werden,
:: weil extract-msg Abhaengigkeiten hat (z.B. red-black-tree-mod),
:: die aus dem Source gebaut werden und setuptools.build_meta brauchen.
:: Embeddable Python bringt setuptools/wheel NICHT mit.
echo [DEBUG] Installiere Build-Werkzeuge (setuptools, wheel)... >> "%LOGFILE%"
"%PYTHON%" -m pip install setuptools wheel --no-warn-script-location >> "%LOGFILE%" 2>&1
if !errorlevel! neq 0 (
echo [WARN] setuptools/wheel konnten nicht installiert werden >> "%LOGFILE%"
echo [--] E-Mail/Outlook-Import uebersprungen
echo Build-Werkzeuge konnten nicht installiert werden.
echo .msg-Dateien ^(Outlook-Mails^) werden NICHT unterstuetzt.
echo .eml-Dateien und PDF-Mails funktionieren weiterhin.
echo Tipp: Outlook-Mails als .eml oder PDF speichern.
goto :email_install_done
)
echo [OK] setuptools + wheel installiert >> "%LOGFILE%"
"%PYTHON%" -m pip install "extract-msg>=0.48" "icalendar>=5.0" --no-warn-script-location >> "%LOGFILE%" 2>&1
if !errorlevel! equ 0 (
echo [OK] E-Mail/Outlook-Import installiert
echo [OK] E-Mail/Outlook-Import installiert >> "%LOGFILE%"
) else (
echo [WARN] extract-msg/icalendar Installation fehlgeschlagen >> "%LOGFILE%"
echo [^^!^^!] Outlook-Mail-Import teilweise nicht verfuegbar
echo.
echo Das Paket 'extract-msg' konnte nicht installiert werden.
echo .msg-Dateien ^(Outlook-Mails^) werden NICHT unterstuetzt.
echo .eml-Dateien und PDF-Mails funktionieren weiterhin.
echo.
echo Workaround: Outlook-Mail oeffnen, dann:
echo Datei ^> Speichern unter ^> "Nur Text" ^(.eml^) oder PDF
echo Die gespeicherte Datei kann dann in PBP hochgeladen werden.
echo.
echo Details im Log: !LOGFILE!
)
:email_install_done
:: Verzeichnisstruktur erstellen (#297: app/ und data/ getrennt)
if not exist "%BASE_INSTALL%" mkdir "%BASE_INSTALL%"
if not exist "%APP_DIR%" mkdir "%APP_DIR%"
if not exist "%DATA_DIR%" mkdir "%DATA_DIR%"
if not exist "%DATA_DIR%\dokumente" mkdir "%DATA_DIR%\dokumente"
if not exist "%DATA_DIR%\export" mkdir "%DATA_DIR%\export"
if not exist "%DATA_DIR%\logs" mkdir "%DATA_DIR%\logs"
:: #351: Ein einziges Backup BEVOR irgendetwas verschoben wird (#349)
:: Pruefe beide moeglichen DB-Standorte, sichere den neuesten.
:: v1.7.149 (#1149): kein `copy` mehr. Die Datenbank laeuft im WAL-Modus; eine
:: Dateikopie verpasst, was nur im WAL steht (bei offener Verbindung gemessen:
:: 4 KB und "no such table"), die Erfolgsmeldung stand trotzdem da, und der
:: feste Dateiname wurde bei jedem Update ueberschrieben. _sicherung_vor_update.py
:: nutzt die SQLite-Sicherungsfunktion, schreibt einen Namen mit Zeitstempel,
:: liest die Sicherung zur Probe und meldet nur dann OK, wenn das stimmt.
set "BACKUP_DIR=%DATA_DIR%\backups"
set "BACKUP_DB="
if exist "%DATA_DIR%\pbp.db" set "BACKUP_DB=%DATA_DIR%\pbp.db"
if not defined BACKUP_DB if exist "%BASE_INSTALL%\pbp.db" set "BACKUP_DB=%BASE_INSTALL%\pbp.db"
if defined BACKUP_DB (
echo [INFO] Erstelle Sicherung vor Update: !BACKUP_DB! >> "%LOGFILE%"
"%PYTHON%" "%BASEDIR%\_sicherung_vor_update.py" "!BACKUP_DB!" "!BACKUP_DIR!" >> "%LOGFILE%" 2>&1
if errorlevel 1 (
echo [WARNUNG] Die Sicherung der Datenbank ist NICHT gelungen.
echo Die Gruende stehen im Log: !LOGFILE!
echo Kopiere die Datei !BACKUP_DB! zur Sicherheit von Hand,
echo bevor du PBP das naechste Mal startest.
echo [WARNUNG] Sicherung vor Update fehlgeschlagen >> "%LOGFILE%"
) else (
echo [OK] Sicherung der Datenbank erstellt: !BACKUP_DIR!
echo [OK] Sicherung erstellt >> "%LOGFILE%"
)
)
:: Migration v1.4.x -> v1.5.0: Daten aus flacher Struktur verschieben (#297, #341)
if exist "%BASE_INSTALL%\pbp.db" (
echo [INFO] Migration: Verschiebe Daten von flach nach data/ >> "%LOGFILE%"
if not exist "%DATA_DIR%\pbp.db" move "%BASE_INSTALL%\pbp.db" "%DATA_DIR%\" >> "%LOGFILE%" 2>&1
if exist "%BASE_INSTALL%\pbp.db-wal" move "%BASE_INSTALL%\pbp.db-wal" "%DATA_DIR%\" >> "%LOGFILE%" 2>&1
if exist "%BASE_INSTALL%\pbp.db-shm" move "%BASE_INSTALL%\pbp.db-shm" "%DATA_DIR%\" >> "%LOGFILE%" 2>&1
if exist "%BASE_INSTALL%\mcp_heartbeat.json" move "%BASE_INSTALL%\mcp_heartbeat.json" "%DATA_DIR%\" >> "%LOGFILE%" 2>&1
:: dokumente/ und export/ Inhalte migrieren, nur wenn im alten Pfad vorhanden
if exist "%BASE_INSTALL%\dokumente" (
xcopy "%BASE_INSTALL%\dokumente" "%DATA_DIR%\dokumente\" /E /I /Q /Y >> "%LOGFILE%" 2>&1
rmdir /s /q "%BASE_INSTALL%\dokumente" 2>nul
)
if exist "%BASE_INSTALL%\export" (
xcopy "%BASE_INSTALL%\export" "%DATA_DIR%\export\" /E /I /Q /Y >> "%LOGFILE%" 2>&1
rmdir /s /q "%BASE_INSTALL%\export" 2>nul
)
if exist "%BASE_INSTALL%\logs" (
xcopy "%BASE_INSTALL%\logs" "%DATA_DIR%\logs\" /E /I /Q /Y >> "%LOGFILE%" 2>&1
rmdir /s /q "%BASE_INSTALL%\logs" 2>nul
)
:: Alte python/ und src/ aus flacher Struktur entfernen
if exist "%BASE_INSTALL%\python" rmdir /s /q "%BASE_INSTALL%\python" 2>nul
if exist "%BASE_INSTALL%\src" rmdir /s /q "%BASE_INSTALL%\src" 2>nul
echo [OK] Migration von v1.4.x abgeschlossen
echo [OK] Migration abgeschlossen >> "%LOGFILE%"
)
echo [OK] Datenordner erstellt
echo [OK] Datenordner: %DATA_DIR% >> "%LOGFILE%"
:: Runtime in festen Pfad kopieren (update-sichere Pfade fuer Claude Desktop, #297)
echo.
echo Kopiere Runtime in festen Installationspfad...
echo [INFO] Kopiere python + src nach %APP_DIR% >> "%LOGFILE%"
:: Laufende PBP-Prozesse beenden (verhindert "Unzulaessiger SHARE-Vorgang")
:: #739: bis v1.7.54 lief das ueber wmic. Auf Windows 11 24H2 ist das
:: Werkzeug entfernt — die Schleife fand dann NICHTS, die Prozesse
:: liefen weiter, und das Kopieren der Runtime traf auf gesperrte
:: Dateien. Der Deinstaller war laengst umgestellt, der Installer nicht.
:: Bewusst OHNE for /f und ohne Pipe im Kommando: ein escaptes Rohr
:: kommt in der Subshell nicht als solches an (#990) — hier wird
:: deshalb genau die Form benutzt, die im Deinstaller erprobt ist.
echo [DEBUG] Pruefe laufende PBP-Prozesse... >> "%LOGFILE%"
:: PP21 (#1170, Gegenprobe 06.10.2026): Nach jeder Neuinstallation blieb ein Fenster "[FEHLER] Dashboard ist mit Fehlercode -1
:: beendet" mit "Pause" stehen: der Installer beendete das alte Python, und das Fenster, das es gestartet hatte
:: (`Dashboard starten.bat`), meldete den Abbruch und wartete. Dieses Fenster geht jetzt mit: es gehoert zu dem, was ersetzt wird.
powershell -ExecutionPolicy Bypass -NoProfile -Command "Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object { ( ($_.Name -eq 'python.exe' -or $_.Name -eq 'pythonw.exe') -and ( ($_.CommandLine -match 'bewerbungs_assistent|start_dashboard|uvicorn|fastmcp') -or ($_.ExecutablePath -match 'BewerbungsAssistent') ) ) -or ($_.Name -eq 'cmd.exe' -and $_.CommandLine -match 'Dashboard starten\.bat') } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }" >> "%LOGFILE%" 2>&1
:: Kurze Pause, damit gesperrte Datei-Handles freigegeben werden.
ping -n 3 127.0.0.1 >nul 2>&1
echo [OK] Prozess-Stopp durchlaufen >> "%LOGFILE%"
:: python/ Ordner kopieren (#297: nach app/)
echo [DEBUG] Kopiere python-Ordner... >> "%LOGFILE%"
if exist "%APP_DIR%\python" rmdir /s /q "%APP_DIR%\python" 2>nul
if exist "%APP_DIR%\python" (
echo [WARN] python-Ordner konnte nicht geloescht werden, warte 3s... >> "%LOGFILE%"
timeout /t 3 /nobreak >nul
rmdir /s /q "%APP_DIR%\python" 2>nul
)
if exist "%APP_DIR%\python" (
echo [WARN] python-Ordner immer noch gesperrt, versuche ueberschreiben >> "%LOGFILE%"
)
xcopy "%PYTHON_DIR%" "%APP_DIR%\python\" /E /I /Q /Y >> "%LOGFILE%" 2>&1
if !errorlevel! neq 0 goto :err_copy_runtime
echo [OK] python kopiert >> "%LOGFILE%"
:: src/ Ordner kopieren (#297: nach app/)
echo [DEBUG] Kopiere src-Ordner... >> "%LOGFILE%"
if not exist "%SRC_DIR%" goto :err_not_extracted
:: v1.8.0 (#1093): das Programm kommt in einen eigenen Versionsordner (app\versions\<Fassung>), daneben der
:: Startbaustein (app\boot), und aktuell.txt wird ZULETZT umgestellt. Die alte Fassung bleibt als Rueckweg
:: liegen. Der Helfer ist Python, damit sich seine Zusagen testen lassen.
"%PYTHON%" "%BASEDIR%\_programm_einrichten.py" "%BASEDIR%" "%APP_DIR%" >> "%LOGFILE%" 2>&1
if !errorlevel! neq 0 goto :err_copy_runtime
echo [OK] Versionsordner eingerichtet >> "%LOGFILE%"
:: Startdateien nach APP_DIR kopieren (Dashboard starten.bat + start_dashboard.py)
echo [DEBUG] Kopiere Startdateien... >> "%LOGFILE%"
if exist "%BASEDIR%\Dashboard starten.bat" copy /Y "%BASEDIR%\Dashboard starten.bat" "%APP_DIR%\" >> "%LOGFILE%" 2>&1
:: PBP-Icon (#502) an stabilen Ort kopieren — die Desktop-.lnk zeigt
:: spaeter darauf, statt das generische Batch-Symbol zu zeigen.
if exist "%BASEDIR%\assets\pbp.ico" copy /Y "%BASEDIR%\assets\pbp.ico" "%APP_DIR%\pbp.ico" >> "%LOGFILE%" 2>&1
:: start_dashboard.py und _selftest.py liegen jetzt in der Fassung (der Helfer oben legt sie dort ab); im Programmordner
:: steht der unveraenderliche Starter. Ein Kopieren der echten Datei hierher wuerde ihn ueberschreiben.
if exist "%BASEDIR%\DEINSTALLIEREN.bat" copy /Y "%BASEDIR%\DEINSTALLIEREN.bat" "%APP_DIR%\" >> "%LOGFILE%" 2>&1
if exist "%BASEDIR%\favicon.ico" copy /Y "%BASEDIR%\favicon.ico" "%APP_DIR%\" >> "%LOGFILE%" 2>&1
echo [OK] Startdateien kopiert >> "%LOGFILE%"
echo [OK] Runtime installiert in %APP_DIR%
echo [OK] Runtime installiert >> "%LOGFILE%"
echo.
:: -------------------------------------------
:: SCHRITT 3: Claude Desktop konfigurieren
:: -------------------------------------------
echo [DEBUG] Starte Claude-Konfiguration >> "%LOGFILE%"
echo [3/4] Verbinde mit Claude Desktop...
echo [3/4] Claude Desktop... >> "%LOGFILE%"
:claude_suche
set "CLAUDE_FOUND=0"
:: v1.7.0-beta.18: erweiterte Pfad-Liste (Anthropic rotiert die Install-Pfade
:: zwischen Releases). Reihenfolge nach Haeufigkeit, frueher Treffer = Stop.
if exist "%LOCALAPPDATA%\Programs\claude-desktop\Claude.exe" set "CLAUDE_FOUND=1"
if exist "%LOCALAPPDATA%\AnthropicClaude\Claude.exe" set "CLAUDE_FOUND=1"
if exist "%LOCALAPPDATA%\Programs\Claude\Claude.exe" set "CLAUDE_FOUND=1"
if exist "%LOCALAPPDATA%\anthropic-claude\Claude.exe" set "CLAUDE_FOUND=1"
if exist "%ProgramFiles%\Claude\Claude.exe" set "CLAUDE_FOUND=1"
if exist "%ProgramFiles(x86)%\Claude\Claude.exe" set "CLAUDE_FOUND=1"
if exist "%USERPROFILE%\AppData\Local\Programs\Claude\Claude.exe" set "CLAUDE_FOUND=1"
:: #361: Windows Store Version erkennen
for /d %%P in ("%LOCALAPPDATA%\Packages\Claude_*") do (
if exist "%%P\Claude.exe" set "CLAUDE_FOUND=1"
if exist "%%P\LocalCache\Roaming\Claude" set "CLAUDE_FOUND=1"
)
for /d %%P in ("%LOCALAPPDATA%\Packages\AnthropicPBC.Claude*") do (
if exist "%%P\Claude.exe" set "CLAUDE_FOUND=1"
if exist "%%P\LocalCache\Roaming\Claude" set "CLAUDE_FOUND=1"
)
:: PATH-Fallback: Claude.exe ueber `where` finden (z.B. Custom-Install)
if "!CLAUDE_FOUND!"=="0" (
where Claude.exe >nul 2>&1
if !errorlevel! equ 0 set "CLAUDE_FOUND=1"
)
:: MSIX-/Store-Installation (#990, Nutzer-Report 07.09.2026): Claude aus
:: dem Microsoft Store liegt unter C:\Program Files\WindowsApps\<Paket> —
:: einem Verzeichnis mit eigenen ACLs, in das ein `if exist` aus einer
:: normalen Shell auch dann nicht hineinsieht, wenn die Datei da ist. Im
:: PATH steht es ebenfalls nicht, weil MSIX-Apps ueber einen
:: App-Execution-Alias starten. Und %LOCALAPPDATA%\Packages\Claude_*
:: enthaelt nur Anwendungsdaten, nie das Binary — die #361-Erkennung
:: suchte also an der richtigen Stelle nach der falschen Sache.
:: Deshalb: die Appx-API fragen statt ueber Pfade raten.
if "!CLAUDE_FOUND!"=="0" (
rem BEWUSST ohne Pipe: ein `^|` im Backtick-Kommando von `for /f` kommt
rem in der Subshell nicht als Pipe an — gemessen, die Abfrage lieferte
rem dann still nichts. Die Auswahl macht deshalb PowerShell selbst.
for /f "usebackq delims=" %%F in (`powershell -NoProfile -Command "$p = Get-AppxPackage -Name '*Claude*' -ErrorAction SilentlyContinue; if ($p) { $p[0].PackageFamilyName }"`) do set "CLAUDE_APPX=%%F"
if defined CLAUDE_APPX (
set "CLAUDE_FOUND=1"
echo [INFO] Claude als Store-/MSIX-Paket erkannt: !CLAUDE_APPX! >> "%LOGFILE%"
)
)
:: Konfig-Verzeichnis-Fallback: wenn %APPDATA%\Claude\claude_desktop_config.json
:: existiert, ist Claude offensichtlich schon mal installiert/genutzt worden
if "!CLAUDE_FOUND!"=="0" if exist "%APPDATA%\Claude\claude_desktop_config.json" (
echo [INFO] Claude-Konfig vorhanden trotz fehlender exe - Erkennung als 'gefunden' >> "%LOGFILE%"
set "CLAUDE_FOUND=1"
)
if "!CLAUDE_FOUND!"=="1" goto :claude_found
:: v1.7.149 (#1149): der Hinweis erscheint einmal. Danach wird noch einmal gesucht
:: (wer Claude jetzt installiert hat, soll nicht "nicht gefunden" lesen); findet
:: auch die zweite Suche nichts, geht es ohne Claude weiter.
if defined CLAUDE_NOCHMAL goto :claude_found
echo.
echo Claude Desktop wurde nicht gefunden.
echo PBP laeuft auch ohne Claude: das Dashboard im Browser geht immer.
echo Fuer den Chat mit Claude ^(Ersterfassung, Anschreiben, Analysen^)
echo brauchst du Claude Desktop.
echo.
echo Ich oeffne jetzt die Download-Seite.
echo 1. Lade "Claude for Windows" herunter
echo 2. Installiere es
echo 3. Erstelle ein Konto
echo.
echo Druecke danach eine Taste um weiterzumachen.
start https://claude.ai/download
pause >nul
echo.
set "CLAUDE_NOCHMAL=1"
goto :claude_suche
:claude_found
:: Bis v1.7.148 stand hier immer "[OK] Claude Desktop gefunden" - auch nach einer
:: erfolglosen Suche - und der Abschluss wurde gruen. Jetzt nur bei einem Fund.
if "!CLAUDE_FOUND!"=="1" goto :claude_gefunden_ok
echo [--] Claude Desktop nicht gefunden - PBP laeuft trotzdem
echo [WARNUNG] Claude Desktop nicht gefunden >> "%LOGFILE%"
goto :claude_gefunden_weiter
:claude_gefunden_ok
echo [OK] Claude Desktop gefunden
echo [OK] Claude Desktop gefunden >> "%LOGFILE%"
:claude_gefunden_weiter
:: Store Claude path for later opening (#24)
:: v1.7.0-beta.18: erweiterte Pfade synchron zur Erkennung oben
set "CLAUDE_EXE="
if exist "%LOCALAPPDATA%\Programs\claude-desktop\Claude.exe" set "CLAUDE_EXE=%LOCALAPPDATA%\Programs\claude-desktop\Claude.exe"
if exist "%LOCALAPPDATA%\AnthropicClaude\Claude.exe" set "CLAUDE_EXE=%LOCALAPPDATA%\AnthropicClaude\Claude.exe"
if exist "%LOCALAPPDATA%\Programs\Claude\Claude.exe" set "CLAUDE_EXE=%LOCALAPPDATA%\Programs\Claude\Claude.exe"
if exist "%LOCALAPPDATA%\anthropic-claude\Claude.exe" set "CLAUDE_EXE=%LOCALAPPDATA%\anthropic-claude\Claude.exe"
if exist "%ProgramFiles%\Claude\Claude.exe" set "CLAUDE_EXE=%ProgramFiles%\Claude\Claude.exe"
if exist "%ProgramFiles(x86)%\Claude\Claude.exe" set "CLAUDE_EXE=%ProgramFiles(x86)%\Claude\Claude.exe"
if exist "%USERPROFILE%\AppData\Local\Programs\Claude\Claude.exe" set "CLAUDE_EXE=%USERPROFILE%\AppData\Local\Programs\Claude\Claude.exe"
:: Praxisprobe 1.8 (05.10.2026): Die Store-Fassung wird oben oft schon am Konfigurationsordner erkannt (#361). Dann
:: wird die Paket-Abfrage uebersprungen, CLAUDE_APPX bleibt leer - und der Abschluss meldete "Claude Desktop nicht
:: gefunden", obwohl es installiert war. Ohne Programmdatei fragt deshalb immer das Paketsystem.
if not defined CLAUDE_EXE if not defined CLAUDE_APPX (
for /f "usebackq delims=" %%F in (`powershell -NoProfile -Command "$p = Get-AppxPackage -Name '*Claude*' -ErrorAction SilentlyContinue; if ($p) { $p[0].PackageFamilyName }"`) do set "CLAUDE_APPX=%%F"
if defined CLAUDE_APPX echo [INFO] Claude als Store-/MSIX-Paket erkannt ^(Start am Ende^): !CLAUDE_APPX! >> "%LOGFILE%"
)
set "CLAUDE_DIR=%APPDATA%\Claude"
if not exist "%CLAUDE_DIR%" mkdir "%CLAUDE_DIR%"
:: v1.7.0-beta.18: Pruefen ob Claude gerade laeuft — wenn ja, Hinweis zum
:: Beenden, weil Claude die MCP-Konfiguration nur beim Start einliest.
:: Ohne Beenden + Neustart wuerde die neue PBP-Version nicht uebernommen.
tasklist /FI "IMAGENAME eq Claude.exe" 2>nul | findstr /I "Claude.exe" >nul
if !errorlevel! equ 0 (
echo.
echo ----------------------------------------------------
echo HINWEIS: Claude Desktop laeuft gerade.
echo ----------------------------------------------------
echo Claude muss kurz beendet werden, damit die neue
echo PBP-Konfiguration uebernommen wird ^(MCP-Server-Konfig
echo wird nur beim Claude-Start eingelesen^).
echo.
echo Bitte schliesse Claude Desktop jetzt komplett
echo ^(Rechtsklick auf Tray-Icon ^> Beenden^).
echo Danach Enter druecken um fortzufahren.
echo.
pause >nul
echo [INFO] Claude lief vor Konfig-Update >> "%LOGFILE%"
)
echo [DEBUG] Starte _setup_claude.py >> "%LOGFILE%"
:: I15 (#1087 A3): der Abschluss sagt spaeter, ob das hier geklappt hat.
set "CLAUDE_OK=0"
"%PYTHON%" "%BASEDIR%\_setup_claude.py" >> "%LOGFILE%" 2>&1
if !errorlevel! neq 0 goto :claude_config_failed
echo [OK] Claude Desktop konfiguriert
echo [OK] Claude konfiguriert >> "%LOGFILE%"
if "!CLAUDE_FOUND!"=="1" set "CLAUDE_OK=1"
goto :claude_config_done
:claude_config_failed
echo [^^!^^!] Claude-Konfiguration fehlgeschlagen
echo [FEHLER] _setup_claude.py >> "%LOGFILE%"
:claude_config_done
echo.
:: -------------------------------------------
:: Registry-Eintrag fuer Windows Apps & Features (#299)
:: -------------------------------------------
echo [DEBUG] Schreibe Registry-Eintrag >> "%LOGFILE%"
set "REG_PATH=HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PBP"
reg add "%REG_PATH%" /v DisplayName /t REG_SZ /d "PBP - Persoenliches Bewerbungs-Portal" /f >nul 2>&1
reg add "%REG_PATH%" /v DisplayVersion /t REG_SZ /d "%PBP_VERSION%" /f >nul 2>&1
reg add "%REG_PATH%" /v Publisher /t REG_SZ /d "MadGapun (github.com/MadGapun/PBP)" /f >nul 2>&1
reg add "%REG_PATH%" /v InstallLocation /t REG_SZ /d "%APP_DIR%" /f >nul 2>&1
reg add "%REG_PATH%" /v UninstallString /t REG_SZ /d "\"%APP_DIR%\DEINSTALLIEREN.bat\"" /f >nul 2>&1
reg add "%REG_PATH%" /v NoModify /t REG_DWORD /d 1 /f >nul 2>&1
reg add "%REG_PATH%" /v NoRepair /t REG_DWORD /d 1 /f >nul 2>&1
echo [OK] In Windows Apps ^& Features eingetragen
echo [OK] Registry-Eintrag geschrieben >> "%LOGFILE%"
:: -------------------------------------------
:: SCHRITT 4: Startdateien + Test
:: -------------------------------------------
echo [DEBUG] Starte Schritt 4 >> "%LOGFILE%"
echo [4/4] Erstelle Startdateien und teste...
echo [4/4] Startdateien + Test... >> "%LOGFILE%"
:: Desktop-Verknuepfung (zeigt auf APP_DIR - stabil auch nach ZIP-Loeschung, #297)
:: #502: IconLocation auf installiertes pbp.ico setzen, damit die
:: Verknuepfung das PBP-Logo statt dem Standard-Batch-Symbol zeigt.
powershell -ExecutionPolicy Bypass -NoProfile -Command "$ws=New-Object -ComObject WScript.Shell; $d=$env:PBP_DESKTOP; if (-not $d) { $d=[Environment]::GetFolderPath('Desktop') }; $s=$ws.CreateShortcut((Join-Path $d 'PBP Bewerbungs-Portal.lnk')); $s.TargetPath=(Join-Path $env:APP_DIR 'Dashboard starten.bat'); $s.WorkingDirectory=$env:APP_DIR; $s.Description='PBP Dashboard'; $ico=(Join-Path $env:APP_DIR 'pbp.ico'); if (Test-Path -LiteralPath $ico) { $s.IconLocation=($ico + ',0') }; $s.Save()" >nul 2>&1
if !errorlevel! equ 0 echo [OK] Desktop-Verknuepfung erstellt
if !errorlevel! neq 0 echo [--] Desktop-Verknuepfung nicht erstellt
:: Schnelltest
echo [DEBUG] Starte Schnelltest >> "%LOGFILE%"
"%PYTHON%" "%BASEDIR%\_selftest.py" >> "%LOGFILE%" 2>&1
if !errorlevel! equ 0 echo [OK] Funktionstest bestanden
if !errorlevel! neq 0 echo [^^!^^!] Funktionstest nicht bestanden
echo [OK] Installation abgeschlossen >> "%LOGFILE%"
echo.
:: -------------------------------------------
:: FERTIG — v1.7.0-beta.23 ueberarbeitet
:: -------------------------------------------
:: Auto-Start zuerst MIT Health-Check, dann Erfolgsmeldung am Ende.
:: Vorher: Erfolgsmeldung kam VOR dem Start, dann Auto-Start ohne
:: Verifikation. User wusste nicht ob das Dashboard wirklich laeuft —
:: und sah keine eindeutige "FERTIG"-Markierung am Schluss.
echo.
echo ----------------------------------------------------
echo Starte PBP automatisch...
echo ----------------------------------------------------
echo.
:: --- Claude Desktop starten ---
if defined CLAUDE_EXE (
echo [1/3] Claude Desktop starten...
echo [INFO] Starte Claude Desktop: !CLAUDE_EXE! >> "%LOGFILE%"
start "" "!CLAUDE_EXE!"
timeout /t 2 /nobreak >nul
echo [OK] Claude Desktop wurde gestartet.
) else if defined CLAUDE_APPX (
echo [1/3] Claude Desktop starten ^(Store-Version^)...
echo [INFO] Starte Claude ueber AppsFolder: !CLAUDE_APPX! >> "%LOGFILE%"
call :start_claude_appx
timeout /t 2 /nobreak >nul
echo [OK] Claude Desktop wurde gestartet.
) else (
echo [1/3] Claude Desktop nicht gefunden - bitte manuell starten:
echo https://claude.ai/download
)
echo.
:: --- Dashboard im Hintergrund starten ---
echo [2/3] PBP-Dashboard wird gestartet...
echo [INFO] Starte Dashboard >> "%LOGFILE%"
:: Gegenprobe 05.10.2026 (PP15): Das Dashboard oeffnete den Browser selbst, noch bevor es antwortete (Chrome zeigte "Verbindung
:: verweigert"), und unten oeffnet der Installer den Browser ein zweites Mal. Jetzt macht das nur der Installer, nachdem die
:: Pruefung unten bestanden ist. Die Variable gilt nur fuer das hier gestartete Fenster und wird danach geloescht.
set "PBP_KEIN_BROWSER=1"
:: PP20 (#1170): ohne /D erbt das Fenster den Arbeitsordner des Installers (den entpackten Ordner) und haelt ihn fest; das
:: Selbstaufraeumen am Ende laesst dann einen leeren Ordner liegen, solange das Fenster offen ist (dieselbe Klasse wie PP13).
start "PBP-Dashboard" /MIN /D "%APP_DIR%" "%APP_DIR%\Dashboard starten.bat"
set "PBP_KEIN_BROWSER="
:: --- Health-Check: warten bis Port 8200 antwortet (max 30 Sek) ---
echo Warte auf Dashboard auf http://localhost:8200 ...
:: v1.7.149 (#1149): gefragt wird 127.0.0.1 statt localhost. Das Dashboard lauscht nur
:: auf IPv4; mit `localhost` versucht Windows PowerShell zuerst ::1 und brauchte dafuer
:: gemessen mehr als die Sekunde Zeitgrenze - die Pruefung schlug dann bei laufendem
:: Dashboard 30 Mal fehl und der Abschluss wurde gelb. Und es zaehlt der Inhalt:
:: nur ein PBP antwortet auf /api/health mit pbp_version, ein fremdes Programm nicht.
set "DASH_OK=0"
for /L %%i in (1,1,30) do (
timeout /t 1 /nobreak >nul
powershell -NoProfile -Command "try { $r = Invoke-WebRequest -UseBasicParsing -TimeoutSec 1 -Uri 'http://127.0.0.1:8200/api/health'; if ($r.StatusCode -eq 200 -and $r.Content -match 'pbp_version') { 200 } else { 0 } } catch { 0 }" 2>nul | findstr /R "^200$" >nul
if !errorlevel! equ 0 (
set "DASH_OK=1"
goto :dash_ready
)
)
:dash_ready
if "!DASH_OK!"=="1" (
echo [OK] Dashboard laeuft.
echo [3/3] Browser oeffnen...
start "" "http://localhost:8200/"
echo [OK] Browser-Tab oeffnet sich.
) else (
echo [^^!^^!] Dashboard antwortet nicht nach 30 Sekunden.
echo [3/3] Browser oeffnen trotzdem ^(falls alte Instanz laeuft^)...
start "" "http://localhost:8200/"
echo Falls leer: Pruefe das PBP-Dashboard-Fenster auf Fehler.
echo Log: !LOCALAPPDATA!\BewerbungsAssistent\data\logs\pbp.log
)
echo.
:: -------------------------------------------
:: ABSCHLUSS ALS AMPEL (I15, #1087 A3)
:: Bis v1.7.131 stand hier "INSTALLATION ERFOLGREICH" auch dann, wenn die
:: Claude-Konfiguration fehlgeschlagen war. Gruen nur, wenn beides
:: geklappt hat; sonst Gelb mit den konkreten naechsten Schritten.
:: Rot sind die Abbrueche weiter unten (Labels err_*).
:: Keine Klammern in echo-Zeilen innerhalb von Bloecken (#990) - deshalb
:: Sprungmarken statt if-Bloecke.
:: -------------------------------------------
set "AMPEL=GRUEN"
if not "!CLAUDE_OK!"=="1" set "AMPEL=GELB"
if not "!DASH_OK!"=="1" set "AMPEL=GELB"
echo [INFO] Abschluss-Ampel: !AMPEL! CLAUDE_OK=!CLAUDE_OK! DASH_OK=!DASH_OK! >> "%LOGFILE%"
echo.
if "!AMPEL!"=="GRUEN" goto :ampel_gruen
goto :ampel_gelb
:ampel_gruen
echo ##############################################################
echo ## ##
echo ## [GRUEN] I N S T A L L A T I O N E R F O L G R E I C H
echo ## ##
echo ##############################################################
goto :ampel_details
:ampel_gelb
echo ##############################################################
echo ## ##
echo ## [GELB] INSTALLIERT - EIN SCHRITT FEHLT NOCH ##
echo ## ##
echo ##############################################################
echo.
if not "!CLAUDE_OK!"=="1" goto :ampel_gelb_claude
goto :ampel_gelb_dash
:ampel_gelb_claude
if "!CLAUDE_FOUND!"=="1" echo Claude Desktop konnte nicht eingerichtet werden.
if not "!CLAUDE_FOUND!"=="1" echo Claude Desktop wurde nicht gefunden - PBP laeuft trotzdem, das Dashboard geht auch ohne Claude.
echo So geht es weiter:
echo 1. Claude Desktop installieren: https://claude.ai/download
echo 2. Claude Desktop einmal starten und wieder komplett beenden
echo - Rechtsklick auf das Claude-Symbol in der Taskleiste, dann Beenden.
echo 3. INSTALLIEREN.bat noch einmal starten.
echo Details stehen im Installer-Log.
echo.
if "!DASH_OK!"=="1" goto :ampel_details
:ampel_gelb_dash
echo Das Dashboard hat nach 30 Sekunden nicht geantwortet.
echo So geht es weiter: auf dem Desktop "PBP Bewerbungs-Portal"
echo doppelklicken. Oeffnet sich nichts, steht der Grund im Log:
echo %LOCALAPPDATA%\BewerbungsAssistent\data\logs\pbp.log
echo.
:ampel_details
echo.
echo Version: %PBP_VERSION%
echo Daten: %DATA_DIR%
echo App-Code: %APP_DIR%
echo Installer-Log: %LOGFILE%
echo Dashboard: http://localhost:8200/
echo.
echo --------------------------------------------------------------
echo ERSTE SCHRITTE
echo --------------------------------------------------------------
echo.
echo 1. Claude Desktop komplett beenden und neu starten, damit es
echo PBP findet.
echo.
echo 2. Im Dashboard oben links nachsehen: steht dort gruen
echo "Claude Desktop: verbunden", ist alles bereit.
echo.
echo 3. Im Dashboard: Lebenslauf hochladen. Danach in Claude tippen:
echo Starte die Ersterfassung
echo Claude ergaenzt im Gespraech, was im Lebenslauf fehlt.
echo.
echo --------------------------------------------------------------
echo SPAETER WIEDER OEFFNEN
echo --------------------------------------------------------------
echo.
echo - Auf dem Desktop: "PBP Bewerbungs-Portal" doppelklicken
echo - Browser-Direktlink: http://localhost:8200/
echo.
echo ##############################################################
echo.
if "!AMPEL!"=="GRUEN" call :installer_aufraeumen_anbieten
echo Druecke eine beliebige Taste um dieses Fenster zu schliessen.
pause >nul
exit /b 0
:: ===================================================
:: FEHLERBEHANDLUNG
:: Alle Labels hier unten - AUSSERHALB von Klammern!
:: So koennen Sonderzeichen sicher in echo verwendet werden.
:: ===================================================
:err_not_extracted
echo [FEHLER] src-Ordner nicht gefunden - ZIP nicht entpackt >> "%LOGFILE%" 2>nul
echo.
echo ****************************************************
echo * FEHLER: ZIP wurde nicht richtig entpackt! *
echo ****************************************************
echo.
echo Der Ordner "src" fehlt. Das passiert wenn die
echo INSTALLIEREN.bat direkt aus dem ZIP heraus gestartet
echo wird, ohne das ZIP vorher zu entpacken.
echo.
echo SO GEHT ES RICHTIG:
echo 1. Rechtsklick auf die heruntergeladene ZIP-Datei
echo 2. "Alle extrahieren..." / "Extract All..." waehlen
echo 3. Einen Zielordner waehlen ^(z.B. Desktop^)
echo 4. Im ENTPACKTEN Ordner die INSTALLIEREN.bat starten
echo.
echo WICHTIG: Nicht einfach die BAT-Datei aus dem ZIP
echo herausziehen - das ganze ZIP muss entpackt werden!
echo.
call :show_support_info
pause
exit /b 1
:err_setup_helper_missing
echo [FEHLER] Setup-Helper-Skripte fehlen >> "%LOGFILE%" 2>nul
echo.
echo ****************************************************
echo * FEHLER: Setup-Dateien unvollstaendig *
echo ****************************************************
echo.
echo Eine oder mehrere dieser Dateien fehlen:
echo - _setup_claude.py
echo - _selftest.py
echo - _sicherung_vor_update.py
echo - _programm_einrichten.py
echo - _installer_aufraeumen.py
echo - installer\boot\start_dashboard_launcher.py
echo - start_dashboard.py
echo.
echo Vermutlich wurde das ZIP nur teilweise entpackt
echo oder einzelne Dateien sind beim Auspacken verloren
echo gegangen.
echo.
echo SO GEHT ES RICHTIG:
echo 1. Lade die ZIP nochmal komplett herunter
echo 2. Pruefe die Datei auf Vollstaendigkeit
echo 3. Entpacke die GESAMTE ZIP
echo 4. Im entpackten Ordner INSTALLIEREN.bat starten
echo.
call :show_support_info
pause
exit /b 1
:err_32bit
echo [FEHLER] 32-Bit Windows >> "%LOGFILE%"
echo.
echo FEHLER: 32-Bit Windows erkannt!
echo PBP benoetigt 64-Bit Windows.
echo.
call :show_support_info
pause
exit /b 1
:err_download
echo [FEHLER] Python-Download fehlgeschlagen >> "%LOGFILE%"
echo.
echo FEHLER: Python konnte nicht heruntergeladen werden!
echo.
echo Pruefe deine Internetverbindung (oeffne google.de)
echo und starte INSTALLIEREN.bat dann nochmal.
echo.
echo Falls eine Firewall fragt: "Zugriff erlauben" klicken.
echo (Log: %LOGFILE%)
echo.
call :show_support_info
pause
exit /b 1
:err_extract
echo [FEHLER] python.exe nach Entpacken nicht gefunden >> "%LOGFILE%"
echo.
echo FEHLER: Python konnte nicht entpackt werden!
echo Versuche INSTALLIEREN.bat als Administrator auszufuehren.
echo (Rechtsklick, "Als Administrator ausfuehren")
echo (Log: %LOGFILE%)
echo.
call :show_support_info
pause
exit /b 1
:err_getpip
echo [FEHLER] get-pip.py fehlgeschlagen >> "%LOGFILE%"
echo.
echo FEHLER: Paketmanager konnte nicht geladen werden!
echo Pruefe deine Internetverbindung.
echo.
call :show_support_info
pause
exit /b 1
:err_pip
echo [FEHLER] pip install fehlgeschlagen >> "%LOGFILE%"
echo.
echo FEHLER: Paketmanager konnte nicht installiert werden!
echo.
echo Meistens liegt es an der Internetverbindung oder daran, dass
echo ein Virenscanner den Download unterbrochen hat.
echo.
echo SO GEHT ES WEITER:
echo 1. Internetverbindung pruefen ^(oeffne google.de^)
echo 2. INSTALLIEREN.bat nochmal starten - das ist gefahrlos,
echo deine Daten bleiben erhalten
echo (Log: %LOGFILE%)
echo.
call :show_support_info
pause
exit /b 1
:err_python_test
echo [FEHLER] Python-Schnelltest fehlgeschlagen >> "%LOGFILE%"
echo.
echo FEHLER: Python funktioniert nicht!
echo Evtl. blockiert der Virenscanner python.exe.
echo Fuege diesen Ordner als Ausnahme hinzu: %BASEDIR%
echo.
call :show_support_info
pause
exit /b 1
:err_python_existing
echo [FEHLER] Python-Schnelltest fehlgeschlagen >> "%LOGFILE%"
echo.
echo FEHLER: Python konnte nicht gestartet werden.
echo TIPP: Loesche den python-Ordner und starte
echo INSTALLIEREN.bat nochmal - Python wird dann
echo erneut heruntergeladen.
echo (Log: %LOGFILE%)
echo.
call :show_support_info
pause
exit /b 1
:err_packages
echo [FEHLER] Paketinstallation fehlgeschlagen >> "%LOGFILE%"
echo.
echo FEHLER: Pakete konnten nicht installiert werden.
echo.
echo Meistens liegt es an der Internetverbindung oder daran, dass
echo eine Firewall oder ein Virenscanner den Download blockiert.
echo.
echo SO GEHT ES WEITER:
echo 1. Internetverbindung pruefen ^(oeffne google.de^)
echo 2. INSTALLIEREN.bat nochmal starten - das ist gefahrlos,
echo deine Daten bleiben erhalten
echo (Log: %LOGFILE%)
echo.
call :show_support_info
pause
exit /b 1
:internet_retry
echo HINWEIS: Internetverbindung fehlgeschlagen.
echo Falls ein Firewall-Fenster erschien: "Zugriff erlauben"
echo Dann druecke eine Taste zum Wiederholen.
pause >nul
"%PYTHON%" -c "import urllib.request; urllib.request.urlopen('https://pypi.org/simple/', timeout=15); print('OK')" >> "%LOGFILE%" 2>&1
if !errorlevel! neq 0 goto :err_internet
goto :internet_ok
:err_internet
echo.
echo FEHLER: Kein Internet. Bitte pruefe WLAN/LAN.
echo (Log: %LOGFILE%)
echo.
call :show_support_info
pause
exit /b 1
:err_copy_runtime
echo [FEHLER] Runtime-Kopie fehlgeschlagen >> "%LOGFILE%"
echo.
echo FEHLER: Runtime konnte nicht nach %DATA_DIR% kopiert werden.
echo.
echo Das passiert meistens weil Claude Desktop noch laeuft
echo und Python-Dateien sperrt.
echo.
echo LOESUNG:
echo 1. Claude Desktop BEENDEN:
echo Rechtsklick auf das Claude-Symbol unten rechts
echo in der Taskleiste, dann "Quit" / "Beenden"
echo 2. INSTALLIEREN.bat nochmal starten
echo.
echo Falls das nicht hilft: Als Administrator ausfuehren.
echo (Log: %LOGFILE%)
echo.
call :show_support_info
pause
exit /b 1
:: -------------------------------------------
:: Support-Info (wird bei jedem Fehler angezeigt)
:: -------------------------------------------
:installer_aufraeumen_anbieten
:: v1.8.0 (#1093, Anforderung 14): Installationsordner und ZIP werden nach einer GELUNGENEN Installation nicht mehr
:: gebraucht. Die Einstellung installer_aufraeumen (fragen, immer, nie) steht in PBP unter Einstellungen; ohne
:: Datenbank gilt fragen. Geloescht wird nie ungefragt, und nur, was _installer_aufraeumen.py als entpackten
:: Installer erkennt (siehe dort). Gefragt wird ausserhalb jedes Klammerblocks (#990).
:: Der Helfer laeuft mit der Python-Laufzeit im PROGRAMMORDNER: die im Installationsordner waere beim Loeschen gesperrt.
set "AUFRAEUMEN=fragen"
:: Gegenprobe 05.10.2026 (PP18): Der Befehl in den Rueckwaertsstrichen laeuft ueber `cmd /c`. Beginnt er mit einem Anfuehrungszeichen und
:: hat mehr als zwei, schneidet cmd das erste und das letzte ab: "Die Syntax fuer den Dateinamen ... ist falsch" erschien am Ende JEDER
:: gelungenen Installation, und die Einstellung (nie/immer) wurde nie gelesen. Ein zusaetzliches Paar um den ganzen Befehl behebt das.
for /f "usebackq delims=" %%E in (`""%APP_DIR%\python\python.exe" "%BASEDIR%\_installer_aufraeumen.py" einstellung "%DATA_DIR%""`) do set "AUFRAEUMEN=%%E"
echo [INFO] Installer aufraeumen: !AUFRAEUMEN! >> "%LOGFILE%"
if "!AUFRAEUMEN!"=="nie" goto :eof
"%APP_DIR%\python\python.exe" "%BASEDIR%\_installer_aufraeumen.py" plan "%BASEDIR%" "%PBP_VERSION%" "%APP_DIR%" "%DATA_DIR%" >> "%LOGFILE%" 2>&1
if errorlevel 1 goto :eof
if "!AUFRAEUMEN!"=="immer" goto :aufraeumen_ausfuehren
echo.
echo Der Installationsordner und die ZIP-Datei werden nicht mehr gebraucht.
echo Soll ich sie loeschen, sobald du dieses Fenster schliesst?
echo Ordner: %BASEDIR%
echo PBP und deine Daten bleiben dabei unberuehrt.
set "ANTWORT=n"
set /p ANTWORT=" Loeschen? (j/n): "
set "ANTWORT=!ANTWORT:~0,1!"
if /i not "!ANTWORT!"=="j" if /i not "!ANTWORT!"=="y" goto :eof
:aufraeumen_ausfuehren
"%APP_DIR%\python\python.exe" "%BASEDIR%\_installer_aufraeumen.py" loeschen "%BASEDIR%" "%PBP_VERSION%" "%APP_DIR%" "%DATA_DIR%" >> "%LOGFILE%" 2>&1
:: v1.8.0 (#1219): "wird geloescht" steht erst nach einer Probe. Scheitert der Helfer (Temp-Ordner nicht beschreibbar, kein
:: Prozess startbar), endet er mit Exit-Code 1 - dann bleibt der Ordner liegen, und das sagt die Meldung.
if not errorlevel 1 goto :aufraeumen_gestartet
echo.
echo Das Aufraeumen konnte nicht gestartet werden - der Ordner bleibt liegen.
echo Du kannst ihn selbst loeschen, PBP und deine Daten bleiben dabei unberuehrt:
echo !BASEDIR!
echo [WARN] Installer-Aufraeumen nicht gestartet (Exit-Code ungleich 0) >> "%LOGFILE%"
goto :eof
:aufraeumen_gestartet
echo Der Ordner wird geloescht, sobald du dieses Fenster schliesst.
echo [INFO] Installer-Aufraeumen gestartet >> "%LOGFILE%"
goto :eof
:show_support_info
echo.
echo ----------------------------------------------------
echo FEHLER MELDEN:
echo Falls das Problem bestehen bleibt, melde es bitte:
echo.
echo https://github.com/MadGapun/PBP/issues/new
echo.
echo Bitte haenge die Log-Datei an:
echo %LOGFILE%
echo ----------------------------------------------------
echo.
goto :eof
:fix_pip
echo pip wird nachinstalliert...
set "GETPIP_PATH=%PYTHON_DIR%\get-pip.py"
if not exist "!GETPIP_PATH!" curl.exe -sL -o "!GETPIP_PATH!" "%GETPIP_URL%" 2>> "%LOGFILE%"
call :pip_beschaffen
goto :eof
:pip_beschaffen
:: Fuehrt get-pip.py mit einem eigenen Temp-Ordner aus und raeumt ihn danach weg (PP25). Rueckgabe: der Exitcode von get-pip.
set "PIP_TMP=%PYTHON_DIR%\pip-tmp"
rmdir /s /q "!PIP_TMP!" >nul 2>&1
mkdir "!PIP_TMP!" >nul 2>&1
set "PIP_TEMP_VORHER=%TEMP%"
set "PIP_TMP_VORHER=%TMP%"
set "TEMP=!PIP_TMP!"
set "TMP=!PIP_TMP!"
"%PYTHON%" "%GETPIP_PATH%" --no-warn-script-location -q >> "%LOGFILE%" 2>&1
set "PIP_RC=!errorlevel!"
set "TEMP=!PIP_TEMP_VORHER!"
set "TMP=!PIP_TMP_VORHER!"
rmdir /s /q "!PIP_TMP!" >nul 2>&1
exit /b !PIP_RC!
:start_claude_appx
:: #990: Store-Apps starten ueber den AppsFolder, nicht ueber einen Pfad.
:: Die Application-Id kommt aus dem Paketmanifest, nicht aus dem Kopf —
:: Vorschlag des Melders von #990. v1.7.37 hatte hier 'Claude' fest
:: eingetragen; das stimmt heute, wuerde bei einer Umbenennung aber still
:: danebengreifen, und `>nul 2>&1` verschluckt den Fehler auch noch.
:: Der Index [0] statt `Select-Object -First 1` fuer den Fall, dass ein
:: Paket mehrere Anwendungen deklariert — dann waere `$id` ein Array und
:: die Verkettung ergaebe Unsinn. BEWUSST ohne Pipe: ein `|` in einer
:: eingebetteten PowerShell-Zeile ist in Batch eine Fehlerquelle, und ein
:: `^|` kommt hier als literales `^|` bei PowerShell an (gemessen).
powershell -NoProfile -Command "$p = @(Get-AppxPackage -Name '*Claude*' -ErrorAction SilentlyContinue)[0]; if ($p) { $id = @((Get-AppxPackageManifest $p).Package.Applications.Application.Id)[0]; if ($id) { Start-Process ('shell:AppsFolder\' + $p.PackageFamilyName + [char]33 + $id) } }" >nul 2>&1
goto :eof