fix: Improve Windows build scripts to properly execute electron-builder

- build-client.bat: Use node_modules\.bin\electron-builder.cmd directly
- build-all.ps1: Use direct path to electron-builder instead of npm run
- setup-backend.bat: Add UTF-8 support and use python -m pip

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
egg
2025-12-16 20:40:52 +08:00
parent 7d4fc69071
commit c19b4e8292
3 changed files with 605 additions and 567 deletions

View File

@@ -217,10 +217,20 @@ function Build-Electron {
exit 1 exit 1
} }
# 安裝依賴 # 總是執行 npm install 確保依賴完整
if (-not (Test-Path "node_modules")) { Write-Host " 安裝 npm 依賴..." -ForegroundColor Gray
Write-Host " 安裝 npm 依賴..." -ForegroundColor Gray npm install
npm install if ($LASTEXITCODE -ne 0) {
Write-Err "npm install 失敗"
exit 1
}
# 確認 electron-builder 已安裝
$electronBuilderPath = Join-Path $ClientDir "node_modules\.bin\electron-builder.cmd"
if (-not (Test-Path $electronBuilderPath)) {
Write-Err "electron-builder 未安裝"
Write-Warn "請確認 package.json 中的 devDependencies 包含 electron-builder"
exit 1
} }
# 建立 .env 如果不存在 # 建立 .env 如果不存在
@@ -230,12 +240,19 @@ function Build-Electron {
} }
Write-Host " 執行 electron-builder..." -ForegroundColor Gray Write-Host " 執行 electron-builder..." -ForegroundColor Gray
npm run build -- --win
# 直接執行 node_modules 中的 electron-builder
& $electronBuilderPath --win
if ($LASTEXITCODE -ne 0) {
Write-Err "electron-builder 執行失敗"
exit 1
}
if (Test-Path "dist\*.exe") { if (Test-Path "dist\*.exe") {
Write-OK "Electron 打包完成" Write-OK "Electron 打包完成"
} else { } else {
Write-Err "Electron 打包失敗" Write-Err "Electron 打包失敗 - dist 目錄中找不到 exe 檔案"
exit 1 exit 1
} }
} }

View File

@@ -1,324 +1,344 @@
@echo off @echo off
REM Meeting Assistant Client - Windows 打包腳本 chcp 65001 >nul
REM 將 Electron 應用與 Python Sidecar 打包成免安裝 exe REM Meeting Assistant Client - Windows 打包腳本
REM 將 Electron 應用與 Python Sidecar 打包成免安裝 exe
setlocal enabledelayedexpansion
setlocal enabledelayedexpansion
REM 顏色設定 (Windows 10+)
set "GREEN=[92m" REM 顏色設定 (Windows 10+)
set "YELLOW=[93m" set "GREEN=[92m"
set "RED=[91m" set "YELLOW=[93m"
set "BLUE=[94m" set "RED=[91m"
set "CYAN=[96m" set "BLUE=[94m"
set "NC=[0m" set "CYAN=[96m"
set "NC=[0m"
REM 專案路徑
set "SCRIPT_DIR=%~dp0" REM 專案路徑
set "PROJECT_DIR=%SCRIPT_DIR%.." set "SCRIPT_DIR=%~dp0"
set "CLIENT_DIR=%PROJECT_DIR%\client" set "PROJECT_DIR=%SCRIPT_DIR%.."
set "SIDECAR_DIR=%PROJECT_DIR%\sidecar" set "CLIENT_DIR=%PROJECT_DIR%\client"
set "BUILD_DIR=%PROJECT_DIR%\build" set "SIDECAR_DIR=%PROJECT_DIR%\sidecar"
set "BUILD_DIR=%PROJECT_DIR%\build"
REM 預設配置
set "SKIP_SIDECAR=false" REM 預設配置
set "CLEAN_BUILD=false" set "SKIP_SIDECAR=false"
set "CLEAN_BUILD=false"
REM 解析參數
set "COMMAND=help" REM 解析參數
:parse_args set "COMMAND=help"
if "%~1"=="" goto :main :parse_args
if /i "%~1"=="build" (set "COMMAND=build" & shift & goto :parse_args) if "%~1"=="" goto :main
if /i "%~1"=="sidecar" (set "COMMAND=sidecar" & shift & goto :parse_args) if /i "%~1"=="build" (set "COMMAND=build" & shift & goto :parse_args)
if /i "%~1"=="electron" (set "COMMAND=electron" & shift & goto :parse_args) if /i "%~1"=="sidecar" (set "COMMAND=sidecar" & shift & goto :parse_args)
if /i "%~1"=="clean" (set "COMMAND=clean" & shift & goto :parse_args) if /i "%~1"=="electron" (set "COMMAND=electron" & shift & goto :parse_args)
if /i "%~1"=="help" (set "COMMAND=help" & shift & goto :parse_args) if /i "%~1"=="clean" (set "COMMAND=clean" & shift & goto :parse_args)
if /i "%~1"=="--skip-sidecar" (set "SKIP_SIDECAR=true" & shift & goto :parse_args) if /i "%~1"=="help" (set "COMMAND=help" & shift & goto :parse_args)
if /i "%~1"=="--clean" (set "CLEAN_BUILD=true" & shift & goto :parse_args) if /i "%~1"=="--skip-sidecar" (set "SKIP_SIDECAR=true" & shift & goto :parse_args)
echo %RED%[ERROR]%NC% 未知參數: %~1 if /i "%~1"=="--clean" (set "CLEAN_BUILD=true" & shift & goto :parse_args)
goto :show_help echo %RED%[ERROR]%NC% 未知參數: %~1
goto :show_help
:main
if "%COMMAND%"=="help" goto :show_help :main
if "%COMMAND%"=="build" goto :do_build if "%COMMAND%"=="help" goto :show_help
if "%COMMAND%"=="sidecar" goto :do_sidecar if "%COMMAND%"=="build" goto :do_build
if "%COMMAND%"=="electron" goto :do_electron if "%COMMAND%"=="sidecar" goto :do_sidecar
if "%COMMAND%"=="clean" goto :do_clean if "%COMMAND%"=="electron" goto :do_electron
goto :show_help if "%COMMAND%"=="clean" goto :do_clean
goto :show_help
:show_banner
echo. :show_banner
echo %CYAN%========================================== echo.
echo Meeting Assistant Client Builder echo %CYAN%==========================================
echo 打包 Electron + Sidecar 為免安裝執行檔 echo Meeting Assistant Client Builder
echo ==========================================%NC% echo 打包 Electron + Sidecar 為免安裝執行檔
echo. echo ==========================================%NC%
goto :eof echo.
goto :eof
:check_environment
echo %BLUE%[STEP]%NC% 檢查建置環境... :check_environment
echo %BLUE%[STEP]%NC% 檢查建置環境...
REM 檢查 Node.js
where node >nul 2>&1 REM 檢查 Node.js
if %errorlevel% equ 0 ( where node >nul 2>&1
for /f "tokens=*" %%i in ('node --version') do echo %GREEN%[OK]%NC% Node.js: %%i if %errorlevel% equ 0 (
) else ( for /f "tokens=*" %%i in ('node --version') do echo %GREEN%[OK]%NC% Node.js: %%i
echo %RED%[ERROR]%NC% Node.js 未安裝 ) else (
exit /b 1 echo %RED%[ERROR]%NC% Node.js 未安裝
) exit /b 1
)
REM 檢查 npm
where npm >nul 2>&1 REM 檢查 npm
if %errorlevel% equ 0 ( where npm >nul 2>&1
for /f "tokens=*" %%i in ('npm --version') do echo %GREEN%[OK]%NC% npm: %%i if %errorlevel% equ 0 (
) else ( for /f "tokens=*" %%i in ('npm --version') do echo %GREEN%[OK]%NC% npm: %%i
echo %RED%[ERROR]%NC% npm 未安裝 ) else (
exit /b 1 echo %RED%[ERROR]%NC% npm 未安裝
) exit /b 1
)
REM 檢查 Python
where python >nul 2>&1 REM 檢查 Python
if %errorlevel% equ 0 ( where python >nul 2>&1
for /f "tokens=*" %%i in ('python -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"') do set "PY_VERSION=%%i" if %errorlevel% equ 0 (
for /f "tokens=*" %%i in ('python -c "import sys; print(sys.version_info.major)"') do set "PY_MAJOR=%%i" for /f "tokens=*" %%i in ('python -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"') do set "PY_VERSION=%%i"
for /f "tokens=*" %%i in ('python -c "import sys; print(sys.version_info.minor)"') do set "PY_MINOR=%%i" for /f "tokens=*" %%i in ('python -c "import sys; print(sys.version_info.major)"') do set "PY_MAJOR=%%i"
for /f "tokens=*" %%i in ('python -c "import sys; print(sys.version_info.minor)"') do set "PY_MINOR=%%i"
if !PY_MAJOR! geq 3 if !PY_MINOR! geq 10 (
set "PYTHON_CMD=python" if !PY_MAJOR! geq 3 if !PY_MINOR! geq 10 (
echo %GREEN%[OK]%NC% Python !PY_VERSION! set "PYTHON_CMD=python"
goto :eof echo %GREEN%[OK]%NC% Python !PY_VERSION!
) goto :eof
) )
)
echo %RED%[ERROR]%NC% 需要 Python 3.10 或更高版本
exit /b 1 echo %RED%[ERROR]%NC% 需要 Python 3.10 或更高版本
exit /b 1
:do_clean
echo %BLUE%[STEP]%NC% 清理建置目錄... :do_clean
echo %BLUE%[STEP]%NC% 清理建置目錄...
if exist "%BUILD_DIR%" rmdir /s /q "%BUILD_DIR%"
if exist "%CLIENT_DIR%\dist" rmdir /s /q "%CLIENT_DIR%\dist" if exist "%BUILD_DIR%" rmdir /s /q "%BUILD_DIR%"
if exist "%SIDECAR_DIR%\dist" rmdir /s /q "%SIDECAR_DIR%\dist" if exist "%CLIENT_DIR%\dist" rmdir /s /q "%CLIENT_DIR%\dist"
if exist "%SIDECAR_DIR%\build" rmdir /s /q "%SIDECAR_DIR%\build" if exist "%SIDECAR_DIR%\dist" rmdir /s /q "%SIDECAR_DIR%\dist"
if exist "%SIDECAR_DIR%\*.spec" del /q "%SIDECAR_DIR%\*.spec" if exist "%SIDECAR_DIR%\build" rmdir /s /q "%SIDECAR_DIR%\build"
if exist "%SIDECAR_DIR%\venv" rmdir /s /q "%SIDECAR_DIR%\venv"
echo %GREEN%[OK]%NC% 建置目錄已清理 if exist "%SIDECAR_DIR%\*.spec" del /q "%SIDECAR_DIR%\*.spec"
goto :eof
echo %GREEN%[OK]%NC% 建置目錄已清理
:setup_sidecar_venv goto :eof
echo %BLUE%[STEP]%NC% 設置 Sidecar 建置環境...
:setup_sidecar_venv
cd /d "%SIDECAR_DIR%" echo %BLUE%[STEP]%NC% 設置 Sidecar 建置環境...
if not exist "venv" ( cd /d "%SIDECAR_DIR%"
echo %BLUE%[INFO]%NC% 創建虛擬環境...
%PYTHON_CMD% -m venv venv if not exist "venv" (
) echo %BLUE%[INFO]%NC% 創建虛擬環境...
%PYTHON_CMD% -m venv venv
echo %BLUE%[INFO]%NC% 安裝 Sidecar 依賴... )
call venv\Scripts\activate.bat
pip install --upgrade pip -q echo %BLUE%[INFO]%NC% 安裝 Sidecar 依賴...
pip install -r requirements.txt -q call venv\Scripts\activate.bat
python -m pip install --upgrade pip -q
echo %BLUE%[INFO]%NC% 安裝 PyInstaller... python -m pip install -r requirements.txt -q
pip install pyinstaller -q
echo %BLUE%[INFO]%NC% 安裝 PyInstaller...
echo %GREEN%[OK]%NC% Sidecar 建置環境就緒 python -m pip install pyinstaller -q
goto :eof
echo %GREEN%[OK]%NC% Sidecar 建置環境就緒
:build_sidecar goto :eof
echo %BLUE%[STEP]%NC% 打包 Sidecar (Python → 獨立執行檔)...
:build_sidecar
cd /d "%SIDECAR_DIR%" echo %BLUE%[STEP]%NC% 打包 Sidecar (Python → 獨立執行檔)...
call venv\Scripts\activate.bat cd /d "%SIDECAR_DIR%"
if not exist "dist" mkdir dist call venv\Scripts\activate.bat
echo %BLUE%[INFO]%NC% 執行 PyInstaller... if not exist "dist" mkdir dist
echo %BLUE%[INFO]%NC% 這可能需要幾分鐘...
echo %BLUE%[INFO]%NC% 執行 PyInstaller...
pyinstaller ^ echo %BLUE%[INFO]%NC% 這可能需要幾分鐘...
--onedir ^
--name transcriber ^ pyinstaller ^
--distpath dist ^ --onedir ^
--workpath build ^ --name transcriber ^
--specpath . ^ --distpath dist ^
--noconfirm ^ --workpath build ^
--clean ^ --specpath . ^
--log-level WARN ^ --noconfirm ^
--console ^ --clean ^
--hidden-import=faster_whisper ^ --log-level WARN ^
--hidden-import=ctranslate2 ^ --console ^
--hidden-import=huggingface_hub ^ --hidden-import=faster_whisper ^
--hidden-import=tokenizers ^ --hidden-import=ctranslate2 ^
--hidden-import=onnxruntime ^ --hidden-import=huggingface_hub ^
--hidden-import=opencc ^ --hidden-import=tokenizers ^
--hidden-import=pydub ^ --hidden-import=onnxruntime ^
--hidden-import=numpy ^ --hidden-import=opencc ^
--hidden-import=av ^ --hidden-import=pydub ^
--collect-data=onnxruntime ^ --hidden-import=numpy ^
--collect-data=faster_whisper ^ --hidden-import=av ^
transcriber.py --collect-data=onnxruntime ^
--collect-data=faster_whisper ^
if exist "dist\transcriber" ( transcriber.py
echo %GREEN%[OK]%NC% Sidecar 打包完成: %SIDECAR_DIR%\dist\transcriber
) else ( if exist "dist\transcriber" (
echo %RED%[ERROR]%NC% Sidecar 打包失敗 echo %GREEN%[OK]%NC% Sidecar 打包完成: %SIDECAR_DIR%\dist\transcriber
exit /b 1 ) else (
) echo %RED%[ERROR]%NC% Sidecar 打包失敗
goto :eof exit /b 1
)
:setup_client goto :eof
echo %BLUE%[STEP]%NC% 設置前端建置環境...
:setup_client
cd /d "%CLIENT_DIR%" echo %BLUE%[STEP]%NC% 設置前端建置環境...
if not exist "node_modules" ( cd /d "%CLIENT_DIR%"
echo %BLUE%[INFO]%NC% 安裝前端依賴...
call npm install REM 總是執行 npm install 確保依賴完整
) else ( echo %BLUE%[INFO]%NC% 安裝前端依賴...
echo %BLUE%[INFO]%NC% 前端依賴已安裝 call npm install
) if errorlevel 1 (
echo %RED%[ERROR]%NC% npm install 失敗
if not exist ".env" ( exit /b 1
if exist ".env.example" ( )
copy .env.example .env >nul
echo %YELLOW%[WARN]%NC% 已創建 .env 檔案,請確認設定 REM 確認 electron-builder 已安裝
) if not exist "node_modules\electron-builder" (
) echo %RED%[ERROR]%NC% electron-builder 未安裝
echo %BLUE%[INFO]%NC% 請檢查 package.json 中的 devDependencies
echo %GREEN%[OK]%NC% 前端建置環境就緒 exit /b 1
goto :eof )
:build_electron if not exist ".env" (
echo %BLUE%[STEP]%NC% 打包 Electron 應用... if exist ".env.example" (
copy .env.example .env >nul
cd /d "%CLIENT_DIR%" echo %YELLOW%[WARN]%NC% 已創建 .env 檔案,請確認設定
)
echo %BLUE%[INFO]%NC% 目標平台: Windows (Portable) )
echo %BLUE%[INFO]%NC% 執行 electron-builder...
echo %GREEN%[OK]%NC% 前端建置環境就緒
call npm run build -- --win goto :eof
if exist "dist" ( :build_electron
echo %GREEN%[OK]%NC% Electron 打包完成 echo %BLUE%[STEP]%NC% 打包 Electron 應用...
echo %BLUE%[INFO]%NC% 輸出目錄: %CLIENT_DIR%\dist
) else ( cd /d "%CLIENT_DIR%"
echo %RED%[ERROR]%NC% Electron 打包失敗
exit /b 1 echo %BLUE%[INFO]%NC% 目標平台: Windows (Portable)
) echo %BLUE%[INFO]%NC% 執行 electron-builder...
goto :eof
REM 使用 npm run build 或直接執行 node_modules 中的 electron-builder
:finalize_build if exist "node_modules\.bin\electron-builder.cmd" (
echo %BLUE%[STEP]%NC% 整合建置輸出... call "node_modules\.bin\electron-builder.cmd" --win
) else (
if not exist "%BUILD_DIR%" mkdir "%BUILD_DIR%" call npx electron-builder --win
)
REM 複製 Electron 輸出
if exist "%CLIENT_DIR%\dist" ( if errorlevel 1 (
xcopy /s /e /y "%CLIENT_DIR%\dist\*" "%BUILD_DIR%\" >nul 2>&1 echo %RED%[ERROR]%NC% electron-builder 執行失敗
) exit /b 1
)
echo.
echo %CYAN%========================================== if exist "dist" (
echo 建置完成 echo %GREEN%[OK]%NC% Electron 打包完成
echo ==========================================%NC% echo %BLUE%[INFO]%NC% 輸出目錄: %CLIENT_DIR%\dist
echo. ) else (
echo 輸出目錄: %BUILD_DIR% echo %RED%[ERROR]%NC% Electron 打包失敗 - dist 目錄不存在
echo. exit /b 1
)
dir /b "%BUILD_DIR%" goto :eof
echo. :finalize_build
echo %GREEN%[OK]%NC% 打包完成! echo %BLUE%[STEP]%NC% 整合建置輸出...
echo.
echo Windows 使用說明: if not exist "%BUILD_DIR%" mkdir "%BUILD_DIR%"
echo 1. 找到 build\ 中的 .exe 檔案
echo 2. 直接執行即可,無需安裝 REM 複製 Electron 輸出
echo. if exist "%CLIENT_DIR%\dist" (
goto :eof xcopy /s /e /y "%CLIENT_DIR%\dist\*" "%BUILD_DIR%\" >nul 2>&1
)
:do_build
call :show_banner echo.
call :check_environment echo %CYAN%==========================================
if errorlevel 1 exit /b 1 echo 建置完成
echo ==========================================%NC%
if "%CLEAN_BUILD%"=="true" call :do_clean echo.
echo 輸出目錄: %BUILD_DIR%
if "%SKIP_SIDECAR%"=="false" ( echo.
call :setup_sidecar_venv
call :build_sidecar dir /b "%BUILD_DIR%"
)
echo.
call :setup_client echo %GREEN%[OK]%NC% 打包完成!
call :build_electron echo.
call :finalize_build echo Windows 使用說明:
goto :eof echo 1. 找到 build\ 中的 .exe 檔案
echo 2. 直接執行即可,無需安裝
:do_sidecar echo.
call :show_banner goto :eof
call :check_environment
if errorlevel 1 exit /b 1 :do_build
call :show_banner
if "%CLEAN_BUILD%"=="true" ( call :check_environment
if exist "%SIDECAR_DIR%\dist" rmdir /s /q "%SIDECAR_DIR%\dist" if errorlevel 1 exit /b 1
if exist "%SIDECAR_DIR%\build" rmdir /s /q "%SIDECAR_DIR%\build"
) if "%CLEAN_BUILD%"=="true" call :do_clean
call :setup_sidecar_venv if "%SKIP_SIDECAR%"=="false" (
call :build_sidecar call :setup_sidecar_venv
goto :eof call :build_sidecar
)
:do_electron
call :show_banner call :setup_client
call :check_environment call :build_electron
if errorlevel 1 exit /b 1 call :finalize_build
goto :eof
if not exist "%SIDECAR_DIR%\dist\transcriber" (
if "%SKIP_SIDECAR%"=="false" ( :do_sidecar
echo %YELLOW%[WARN]%NC% Sidecar 尚未打包 call :show_banner
echo %BLUE%[INFO]%NC% 請先執行: %~nx0 sidecar call :check_environment
echo %BLUE%[INFO]%NC% 或使用 --skip-sidecar 跳過 if errorlevel 1 exit /b 1
exit /b 1
) if "%CLEAN_BUILD%"=="true" (
) if exist "%SIDECAR_DIR%\dist" rmdir /s /q "%SIDECAR_DIR%\dist"
if exist "%SIDECAR_DIR%\build" rmdir /s /q "%SIDECAR_DIR%\build"
if "%CLEAN_BUILD%"=="true" ( )
if exist "%CLIENT_DIR%\dist" rmdir /s /q "%CLIENT_DIR%\dist"
) call :setup_sidecar_venv
call :build_sidecar
call :setup_client goto :eof
call :build_electron
call :finalize_build :do_electron
goto :eof call :show_banner
call :check_environment
:show_help if errorlevel 1 exit /b 1
echo.
echo Meeting Assistant Client - Windows 打包腳本 if not exist "%SIDECAR_DIR%\dist\transcriber" (
echo. if "%SKIP_SIDECAR%"=="false" (
echo 用法: %~nx0 [命令] [選項] echo %YELLOW%[WARN]%NC% Sidecar 尚未打包
echo. echo %BLUE%[INFO]%NC% 請先執行: %~nx0 sidecar
echo 命令: echo %BLUE%[INFO]%NC% 或使用 --skip-sidecar 跳過
echo build 完整建置 (Sidecar + Electron) exit /b 1
echo sidecar 僅打包 Sidecar )
echo electron 僅打包 Electron (需先打包 Sidecar) )
echo clean 清理建置目錄
echo help 顯示此幫助訊息 if "%CLEAN_BUILD%"=="true" (
echo. if exist "%CLIENT_DIR%\dist" rmdir /s /q "%CLIENT_DIR%\dist"
echo 選項: )
echo --skip-sidecar 跳過 Sidecar 打包
echo --clean 建置前先清理 call :setup_client
echo. call :build_electron
echo 範例: call :finalize_build
echo %~nx0 build 完整建置 goto :eof
echo %~nx0 sidecar 僅打包 Sidecar
echo %~nx0 electron --skip-sidecar 僅打包 Electron :show_help
echo. echo.
echo 注意: echo Meeting Assistant Client - Windows 打包腳本
echo - 首次打包 Sidecar 需下載 Whisper 模型,可能需要較長時間 echo.
echo - 確保有足夠的磁碟空間 (建議 5GB+) echo 用法: %~nx0 [命令] [選項]
echo. echo.
goto :eof echo 命令:
echo build 完整建置 (Sidecar + Electron)
:end echo sidecar 僅打包 Sidecar
endlocal echo electron 僅打包 Electron (需先打包 Sidecar)
echo clean 清理建置目錄
echo help 顯示此幫助訊息
echo.
echo 選項:
echo --skip-sidecar 跳過 Sidecar 打包
echo --clean 建置前先清理
echo.
echo 範例:
echo %~nx0 build 完整建置
echo %~nx0 sidecar 僅打包 Sidecar
echo %~nx0 electron --skip-sidecar 僅打包 Electron
echo.
echo 注意:
echo - 首次打包 Sidecar 需下載 Whisper 模型,可能需要較長時間
echo - 確保有足夠的磁碟空間 (建議 5GB+)
echo.
goto :eof
:end
endlocal

View File

@@ -1,237 +1,238 @@
@echo off @echo off
REM Meeting Assistant Backend - Windows 一鍵設置與啟動腳本 chcp 65001 >nul
REM 自動安裝依賴、設置環境並啟動後端服務 REM Meeting Assistant Backend - Windows 一鍵設置與啟動腳本
REM 自動安裝依賴、設置環境並啟動後端服務
setlocal enabledelayedexpansion
setlocal enabledelayedexpansion
REM 顏色設定 (Windows 10+)
set "GREEN=[92m" REM 顏色設定 (Windows 10+)
set "YELLOW=[93m" set "GREEN=[92m"
set "RED=[91m" set "YELLOW=[93m"
set "BLUE=[94m" set "RED=[91m"
set "CYAN=[96m" set "BLUE=[94m"
set "NC=[0m" set "CYAN=[96m"
set "NC=[0m"
REM 專案路徑
set "SCRIPT_DIR=%~dp0" REM 專案路徑
set "PROJECT_DIR=%SCRIPT_DIR%.." set "SCRIPT_DIR=%~dp0"
set "BACKEND_DIR=%PROJECT_DIR%\backend" set "PROJECT_DIR=%SCRIPT_DIR%.."
set "SIDECAR_DIR=%PROJECT_DIR%\sidecar" set "BACKEND_DIR=%PROJECT_DIR%\backend"
set "SIDECAR_DIR=%PROJECT_DIR%\sidecar"
REM 預設配置
set "DEFAULT_PORT=8000" REM 預設配置
set "DEFAULT_HOST=0.0.0.0" set "DEFAULT_PORT=8000"
set "DEFAULT_HOST=0.0.0.0"
REM 解析參數
set "COMMAND=start" REM 解析參數
set "PORT=%DEFAULT_PORT%" set "COMMAND=start"
set "HOST=%DEFAULT_HOST%" set "PORT=%DEFAULT_PORT%"
set "NO_SIDECAR=false" set "HOST=%DEFAULT_HOST%"
set "NO_SIDECAR=false"
:parse_args
if "%~1"=="" goto :main :parse_args
if /i "%~1"=="setup" (set "COMMAND=setup" & shift & goto :parse_args) if "%~1"=="" goto :main
if /i "%~1"=="start" (set "COMMAND=start" & shift & goto :parse_args) if /i "%~1"=="setup" (set "COMMAND=setup" & shift & goto :parse_args)
if /i "%~1"=="stop" (set "COMMAND=stop" & shift & goto :parse_args) if /i "%~1"=="start" (set "COMMAND=start" & shift & goto :parse_args)
if /i "%~1"=="help" (set "COMMAND=help" & shift & goto :parse_args) if /i "%~1"=="stop" (set "COMMAND=stop" & shift & goto :parse_args)
if /i "%~1"=="--port" (set "PORT=%~2" & shift & shift & goto :parse_args) if /i "%~1"=="help" (set "COMMAND=help" & shift & goto :parse_args)
if /i "%~1"=="--host" (set "HOST=%~2" & shift & shift & goto :parse_args) if /i "%~1"=="--port" (set "PORT=%~2" & shift & shift & goto :parse_args)
if /i "%~1"=="--no-sidecar" (set "NO_SIDECAR=true" & shift & goto :parse_args) if /i "%~1"=="--host" (set "HOST=%~2" & shift & shift & goto :parse_args)
echo %RED%[ERROR]%NC% 未知參數: %~1 if /i "%~1"=="--no-sidecar" (set "NO_SIDECAR=true" & shift & goto :parse_args)
goto :show_help echo %RED%[ERROR]%NC% 未知參數: %~1
goto :show_help
:main
if "%COMMAND%"=="help" goto :show_help :main
if "%COMMAND%"=="setup" goto :do_setup if "%COMMAND%"=="help" goto :show_help
if "%COMMAND%"=="start" goto :do_start if "%COMMAND%"=="setup" goto :do_setup
if "%COMMAND%"=="stop" goto :do_stop if "%COMMAND%"=="start" goto :do_start
goto :show_help if "%COMMAND%"=="stop" goto :do_stop
goto :show_help
:show_banner
echo. :show_banner
echo %CYAN%========================================== echo.
echo Meeting Assistant Backend Setup echo %CYAN%==========================================
echo Windows 一鍵設置與啟動腳本 echo Meeting Assistant Backend Setup
echo ==========================================%NC% echo Windows 一鍵設置與啟動腳本
echo. echo ==========================================%NC%
goto :eof echo.
goto :eof
:check_python
echo %BLUE%[STEP]%NC% 檢查 Python 環境... :check_python
echo %BLUE%[STEP]%NC% 檢查 Python 環境...
REM 嘗試找到 Python
where python >nul 2>&1 REM 嘗試找到 Python
if %errorlevel% equ 0 ( where python >nul 2>&1
for /f "tokens=*" %%i in ('python -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"') do set "PY_VERSION=%%i" if %errorlevel% equ 0 (
for /f "tokens=*" %%i in ('python -c "import sys; print(sys.version_info.major)"') do set "PY_MAJOR=%%i" for /f "tokens=*" %%i in ('python -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"') do set "PY_VERSION=%%i"
for /f "tokens=*" %%i in ('python -c "import sys; print(sys.version_info.minor)"') do set "PY_MINOR=%%i" for /f "tokens=*" %%i in ('python -c "import sys; print(sys.version_info.major)"') do set "PY_MAJOR=%%i"
for /f "tokens=*" %%i in ('python -c "import sys; print(sys.version_info.minor)"') do set "PY_MINOR=%%i"
if !PY_MAJOR! geq 3 if !PY_MINOR! geq 10 (
set "PYTHON_CMD=python" if !PY_MAJOR! geq 3 if !PY_MINOR! geq 10 (
echo %GREEN%[OK]%NC% Python !PY_VERSION! set "PYTHON_CMD=python"
goto :eof echo %GREEN%[OK]%NC% Python !PY_VERSION!
) goto :eof
) )
)
echo %RED%[ERROR]%NC% 需要 Python 3.10 或更高版本
echo %BLUE%[INFO]%NC% 請安裝 Python: https://www.python.org/downloads/ echo %RED%[ERROR]%NC% 需要 Python 3.10 或更高版本
exit /b 1 echo %BLUE%[INFO]%NC% 請安裝 Python: https://www.python.org/downloads/
exit /b 1
:setup_backend_venv
echo %BLUE%[STEP]%NC% 設置後端虛擬環境... :setup_backend_venv
echo %BLUE%[STEP]%NC% 設置後端虛擬環境...
cd /d "%BACKEND_DIR%"
cd /d "%BACKEND_DIR%"
if not exist "venv" (
echo %BLUE%[INFO]%NC% 創建虛擬環境... if not exist "venv" (
%PYTHON_CMD% -m venv venv echo %BLUE%[INFO]%NC% 創建虛擬環境...
echo %GREEN%[OK]%NC% 虛擬環境已創建 %PYTHON_CMD% -m venv venv
) else ( echo %GREEN%[OK]%NC% 虛擬環境已創建
echo %BLUE%[INFO]%NC% 虛擬環境已存在 ) else (
) echo %BLUE%[INFO]%NC% 虛擬環境已存在
)
echo %BLUE%[INFO]%NC% 安裝後端依賴...
call venv\Scripts\activate.bat echo %BLUE%[INFO]%NC% 安裝後端依賴...
pip install --upgrade pip -q call venv\Scripts\activate.bat
pip install -r requirements.txt -q python -m pip install --upgrade pip -q
echo %GREEN%[OK]%NC% 後端依賴安裝完成 python -m pip install -r requirements.txt -q
goto :eof echo %GREEN%[OK]%NC% 後端依賴安裝完成
goto :eof
:setup_sidecar_venv
echo %BLUE%[STEP]%NC% 設置 Sidecar 虛擬環境... :setup_sidecar_venv
echo %BLUE%[STEP]%NC% 設置 Sidecar 虛擬環境...
cd /d "%SIDECAR_DIR%"
cd /d "%SIDECAR_DIR%"
if not exist "venv" (
echo %BLUE%[INFO]%NC% 創建 Sidecar 虛擬環境... if not exist "venv" (
%PYTHON_CMD% -m venv venv echo %BLUE%[INFO]%NC% 創建 Sidecar 虛擬環境...
echo %GREEN%[OK]%NC% Sidecar 虛擬環境已創建 %PYTHON_CMD% -m venv venv
) else ( echo %GREEN%[OK]%NC% Sidecar 虛擬環境已創建
echo %BLUE%[INFO]%NC% Sidecar 虛擬環境已存在 ) else (
) echo %BLUE%[INFO]%NC% Sidecar 虛擬環境已存在
)
echo %BLUE%[INFO]%NC% 安裝 Sidecar 依賴 (這可能需要幾分鐘)...
call venv\Scripts\activate.bat echo %BLUE%[INFO]%NC% 安裝 Sidecar 依賴 (這可能需要幾分鐘)...
pip install --upgrade pip -q call venv\Scripts\activate.bat
pip install -r requirements.txt -q python -m pip install --upgrade pip -q
echo %GREEN%[OK]%NC% Sidecar 依賴安裝完成 python -m pip install -r requirements.txt -q
goto :eof echo %GREEN%[OK]%NC% Sidecar 依賴安裝完成
goto :eof
:setup_env_file
echo %BLUE%[STEP]%NC% 檢查環境變數配置... :setup_env_file
echo %BLUE%[STEP]%NC% 檢查環境變數配置...
cd /d "%BACKEND_DIR%"
cd /d "%BACKEND_DIR%"
if not exist ".env" (
if exist ".env.example" ( if not exist ".env" (
copy .env.example .env >nul if exist ".env.example" (
echo %YELLOW%[WARN]%NC% 已從 .env.example 創建 .env 檔案 copy .env.example .env >nul
echo %YELLOW%[WARN]%NC% 請編輯 %BACKEND_DIR%\.env 設置資料庫和 API 密鑰 echo %YELLOW%[WARN]%NC% 已從 .env.example 創建 .env 檔案
) else ( echo %YELLOW%[WARN]%NC% 請編輯 %BACKEND_DIR%\.env 設置資料庫和 API 密鑰
echo %RED%[ERROR]%NC% 找不到 .env.example 檔案 ) else (
exit /b 1 echo %RED%[ERROR]%NC% 找不到 .env.example 檔案
) exit /b 1
) else ( )
echo %GREEN%[OK]%NC% 環境變數檔案已存在 ) else (
) echo %GREEN%[OK]%NC% 環境變數檔案已存在
goto :eof )
goto :eof
:start_backend
echo %BLUE%[STEP]%NC% 啟動後端服務... :start_backend
echo %BLUE%[STEP]%NC% 啟動後端服務...
cd /d "%BACKEND_DIR%"
cd /d "%BACKEND_DIR%"
REM 載入環境變數
if exist ".env" ( REM 載入環境變數
for /f "usebackq tokens=1,* delims==" %%a in (".env") do ( if exist ".env" (
set "%%a=%%b" for /f "usebackq tokens=1,* delims==" %%a in (".env") do (
) set "%%a=%%b"
) )
)
REM 使用 .env 中的配置或預設值
if defined BACKEND_HOST set "HOST=%BACKEND_HOST%" REM 使用 .env 中的配置或預設值
if defined BACKEND_PORT set "PORT=%BACKEND_PORT%" if defined BACKEND_HOST set "HOST=%BACKEND_HOST%"
if defined BACKEND_PORT set "PORT=%BACKEND_PORT%"
REM 啟動虛擬環境
call venv\Scripts\activate.bat REM 啟動虛擬環境
call venv\Scripts\activate.bat
echo.
echo %GREEN%[OK]%NC% 後端服務準備就緒! echo.
echo. echo %GREEN%[OK]%NC% 後端服務準備就緒!
echo %CYAN%========================================== echo.
echo 服務資訊 echo %CYAN%==========================================
echo ==========================================%NC% echo 服務資訊
echo. echo ==========================================%NC%
echo API 地址: http://localhost:%PORT% echo.
echo API 文件: http://localhost:%PORT%/docs echo API 地址: http://localhost:%PORT%
echo 健康檢查: http://localhost:%PORT%/api/health echo API 文件: http://localhost:%PORT%/docs
echo. echo 健康檢查: http://localhost:%PORT%/api/health
echo 按 Ctrl+C 停止服務 echo.
echo. echo 按 Ctrl+C 停止服務
echo.
uvicorn app.main:app --host %HOST% --port %PORT% --reload
goto :eof uvicorn app.main:app --host %HOST% --port %PORT% --reload
goto :eof
:do_setup
call :show_banner :do_setup
call :check_python call :show_banner
if errorlevel 1 exit /b 1 call :check_python
call :setup_backend_venv if errorlevel 1 exit /b 1
if "%NO_SIDECAR%"=="false" call :setup_sidecar_venv call :setup_backend_venv
call :setup_env_file if "%NO_SIDECAR%"=="false" call :setup_sidecar_venv
echo. call :setup_env_file
echo %GREEN%[OK]%NC% 環境設置完成! echo.
echo. echo %GREEN%[OK]%NC% 環境設置完成!
echo %BLUE%[INFO]%NC% 啟動服務: %~nx0 start echo.
goto :eof echo %BLUE%[INFO]%NC% 啟動服務: %~nx0 start
goto :eof
:do_start
call :show_banner :do_start
call :check_python call :show_banner
if errorlevel 1 exit /b 1 call :check_python
call :setup_backend_venv if errorlevel 1 exit /b 1
call :setup_env_file call :setup_backend_venv
call :start_backend call :setup_env_file
goto :eof call :start_backend
goto :eof
:do_stop
echo %BLUE%[STEP]%NC% 停止後端服務... :do_stop
echo %BLUE%[STEP]%NC% 停止後端服務...
REM 查找並終止 uvicorn 程序
for /f "tokens=2" %%i in ('tasklist /fi "imagename eq python.exe" /fo list ^| findstr "PID:"') do ( REM 查找並終止 uvicorn 程序
wmic process where "processid=%%i" get commandline 2>nul | findstr /i "uvicorn" >nul for /f "tokens=2" %%i in ('tasklist /fi "imagename eq python.exe" /fo list ^| findstr "PID:"') do (
if not errorlevel 1 ( wmic process where "processid=%%i" get commandline 2>nul | findstr /i "uvicorn" >nul
taskkill /pid %%i /f >nul 2>&1 if not errorlevel 1 (
echo %GREEN%[OK]%NC% 已停止 PID: %%i taskkill /pid %%i /f >nul 2>&1
) echo %GREEN%[OK]%NC% 已停止 PID: %%i
) )
)
echo %GREEN%[OK]%NC% 後端服務已停止
goto :eof echo %GREEN%[OK]%NC% 後端服務已停止
goto :eof
:show_help
echo. :show_help
echo Meeting Assistant Backend - Windows 一鍵設置與啟動腳本 echo.
echo. echo Meeting Assistant Backend - Windows 一鍵設置與啟動腳本
echo 用法: %~nx0 [命令] [選項] echo.
echo. echo 用法: %~nx0 [命令] [選項]
echo 命令: echo.
echo setup 僅設置環境 (安裝依賴) echo 命令:
echo start 設置並啟動後端服務 (預設) echo setup 設置環境 (安裝依賴)
echo stop 停止後端服務 echo start 設置並啟動後端服務 (預設)
echo help 顯示此幫助訊息 echo stop 停止後端服務
echo. echo help 顯示此幫助訊息
echo 選項: echo.
echo --port PORT 服務端口 (預設: %DEFAULT_PORT%) echo 選項:
echo --host HOST 綁定地址 (預設: %DEFAULT_HOST%) echo --port PORT 服務端口 (預設: %DEFAULT_PORT%)
echo --no-sidecar 不安裝 Sidecar 依賴 echo --host HOST 綁定地址 (預設: %DEFAULT_HOST%)
echo. echo --no-sidecar 不安裝 Sidecar 依賴
echo 範例: echo.
echo %~nx0 start 設置並啟動服務 echo 範例:
echo %~nx0 start --port 8080 使用自訂端口 echo %~nx0 start 設置並啟動服務
echo %~nx0 setup 僅安裝依賴 echo %~nx0 start --port 8080 使用自訂端口
echo. echo %~nx0 setup 僅安裝依賴
goto :eof echo.
goto :eof
:end
endlocal :end
endlocal