Ctrl K
ComunidadGuías…

INSTALLIEREN.bat

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
@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