@echo off REM ASCII-only batch: reliable under cmd.exe from PowerShell/Python (no UTF-8 BOM issues). chcp 65001 >nul 2>&1 setlocal EnableExtensions EnableDelayedExpansion title Server Manager - build for %%I in ("%~dp0..\..") do set "ROOT=%%~fI" set "SRC=%ROOT%\src" set "RESOURCE_CONFIG=%ROOT%\resources\config" set "APP_NAME=ServerManager" pushd "%SRC%" || ( echo [ERROR] src directory not found: %SRC% exit /b 1 ) echo ============================================================ echo Server Manager - build EXE echo ============================================================ echo. python --version >nul 2>&1 if errorlevel 1 ( echo [ERROR] Python not found. Install Python 3.8+ pause exit /b 1 ) echo [1/6] pip deps... pip install PyQt6 pyinstaller -q 2>nul pip install pymysql Pillow -q 2>nul python -c "import PyQt6" 2>nul if errorlevel 1 ( echo [ERROR] pip install PyQt6 pause exit /b 1 ) python -c "import PyInstaller" 2>nul if errorlevel 1 ( echo [ERROR] pip install pyinstaller pause exit /b 1 ) echo [2/6] icon... python "%ROOT%\resources\icon\convert_icon.py" if not exist "%ROOT%\resources\icon\icon.ico" ( echo [WARN] no icon.ico, using --icon NONE set "ICON_PARAM=--icon NONE" ) else ( set "ICON_PARAM=--icon %ROOT%\resources\icon\icon.ico" ) echo [3/6] clean dist\build... if exist "dist" rd /s /q dist if exist "build" rd /s /q build if exist "*.spec" del /q *.spec 2>nul REM Pre-create work dir for PyInstaller warn file on some Windows setups if not exist "build\%APP_NAME%" mkdir "build\%APP_NAME%" echo [4/6] PyInstaller %APP_NAME% (onedir)... REM Single line: no ^ line-continuation (avoids trailing-space / encoding breakage) pyinstaller --noconfirm --onedir --console --name %APP_NAME% !ICON_PARAM! --add-data "%ROOT%\resources\version.json;." --add-data "%ROOT%\resources\config.json;." --add-data "%ROOT%\resources\icon;icon" --hidden-import PyQt6.QtWidgets --hidden-import PyQt6.QtCore --hidden-import PyQt6.QtGui --hidden-import pymysql --hidden-import entrypoints.cli.main --hidden-import entrypoints.cli.extended --hidden-import entrypoints.gui.bootstrap --hidden-import mcp.server --hidden-import mcp.tools --hidden-import models.app_config --hidden-import services.commands --hidden-import services.server_creator --hidden-import services.hot_update --hidden-import services.rg_search --hidden-import bsdiff4 --collect-all PyQt6 --collect-all bsdiff4 --hidden-import requests entrypoints\main.py if errorlevel 1 ( echo [ERROR] %APP_NAME% PyInstaller failed pause exit /b 1 ) echo [4b/6] copy rg.exe... if exist "%ROOT%\resources\bin\rg.exe" ( copy /y "%ROOT%\resources\bin\rg.exe" "dist\%APP_NAME%\rg.exe" >nul echo copied resources\bin\rg.exe to dist\%APP_NAME%\rg.exe ) else ( echo [WARN] resources\bin\rg.exe missing, search will not use ripgrep ) echo [4c/6] copy resources\config templates to dist\%APP_NAME%\config ^(same as installer {app}\config^)... if exist "%RESOURCE_CONFIG%" ( if not exist "dist\%APP_NAME%\config" mkdir "dist\%APP_NAME%\config" xcopy "%RESOURCE_CONFIG%\*" "dist\%APP_NAME%\config\" /E /I /Y /Q >nul echo copied ..\resources\config to dist\%APP_NAME%\config ) else ( echo [WARN] ..\resources\config missing, Inno install will fail if resources\config is absent at compile time ) echo [5/6] PyInstaller mini_updater... pyinstaller --noconfirm --onefile --windowed --name mini_updater --distpath dist --workpath build_mini --specpath build_mini "%ROOT%\scripts\update\mini_updater.py" if errorlevel 1 ( echo [ERROR] mini_updater PyInstaller failed pause exit /b 1 ) echo [6/6] done. if not exist "dist\%APP_NAME%\config" mkdir "dist\%APP_NAME%\config" if exist "config\user.config" copy /y "config\user.config" "dist\%APP_NAME%\config\user.config" >nul rd /s /q build 2>nul rd /s /q build_mini 2>nul del /q *.spec 2>nul del /q build_mini\*.spec 2>nul echo. echo ============================================================ echo OK: dist\%APP_NAME%\ dist\mini_updater.exe echo ============================================================ echo. if /i not "%~1"=="nopause" pause popd endlocal exit /b 0