Files
Meeting_Assistant/scripts/build-all.ps1
egg c19b4e8292 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>
2025-12-16 20:40:52 +08:00

322 lines
9.0 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#Requires -Version 5.1
<#
.SYNOPSIS
Meeting Assistant - Windows 一鍵打包腳本
.DESCRIPTION
在 Windows 環境下一鍵打包 Sidecar + Electron 成免安裝 exe
.EXAMPLE
.\scripts\build-all.ps1
.\scripts\build-all.ps1 -ApiUrl "http://192.168.1.100:8000/api"
.\scripts\build-all.ps1 -SkipSidecar
.\scripts\build-all.ps1 -Clean
#>
param(
[string]$ApiUrl,
[switch]$SkipSidecar,
[switch]$Clean,
[switch]$Help
)
$ErrorActionPreference = "Stop"
# 顏色輸出函數
function Write-Step { param($msg) Write-Host "[STEP] $msg" -ForegroundColor Cyan }
function Write-OK { param($msg) Write-Host "[OK] $msg" -ForegroundColor Green }
function Write-Warn { param($msg) Write-Host "[WARN] $msg" -ForegroundColor Yellow }
function Write-Err { param($msg) Write-Host "[ERROR] $msg" -ForegroundColor Red }
# 路徑設定
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$ProjectDir = Split-Path -Parent $ScriptDir
$SidecarDir = Join-Path $ProjectDir "sidecar"
$ClientDir = Join-Path $ProjectDir "client"
$BuildDir = Join-Path $ProjectDir "build"
function Show-Banner {
Write-Host ""
Write-Host "==========================================" -ForegroundColor Cyan
Write-Host " Meeting Assistant - Windows Builder" -ForegroundColor Cyan
Write-Host " 一鍵打包 Electron + Sidecar" -ForegroundColor Cyan
Write-Host "==========================================" -ForegroundColor Cyan
Write-Host ""
}
function Show-Help {
Write-Host @"
Meeting Assistant - Windows
: .\build-all.ps1 []
:
-ApiUrl URL API URL (: http://localhost:8000/api)
-SkipSidecar Sidecar
-Clean
-Help
:
.\build-all.ps1 # (使 localhost)
.\build-all.ps1 -ApiUrl "http://192.168.1.100:8000/api" # URL
.\build-all.ps1 -ApiUrl "https://api.example.com/api" # 使
.\build-all.ps1 -Clean #
.\build-all.ps1 -SkipSidecar # Electron
"@
}
function Update-Config {
param([string]$NewApiUrl)
Write-Step "更新設定檔..."
$configPath = Join-Path $ClientDir "config.json"
if (Test-Path $configPath) {
$config = Get-Content $configPath -Raw | ConvertFrom-Json
if ($NewApiUrl) {
$config.apiBaseUrl = $NewApiUrl
Write-Host " API URL: $NewApiUrl" -ForegroundColor Gray
}
$config | ConvertTo-Json -Depth 10 | Set-Content $configPath -Encoding UTF8
Write-OK "設定檔已更新"
} else {
Write-Warn "找不到 config.json使用預設設定"
}
}
function Test-Prerequisites {
Write-Step "檢查建置環境..."
# 檢查 Python
try {
$pyVersion = python --version 2>&1
Write-OK "Python: $pyVersion"
} catch {
Write-Err "Python 未安裝,請安裝 Python 3.10+"
exit 1
}
# 檢查 Node.js
try {
$nodeVersion = node --version 2>&1
Write-OK "Node.js: $nodeVersion"
} catch {
Write-Err "Node.js 未安裝,請安裝 Node.js 18+"
exit 1
}
# 檢查 npm
try {
$npmVersion = npm --version 2>&1
Write-OK "npm: $npmVersion"
} catch {
Write-Err "npm 未安裝"
exit 1
}
}
function Clear-BuildDirs {
Write-Step "清理建置目錄..."
$dirsToClean = @(
$BuildDir,
(Join-Path $ClientDir "dist"),
(Join-Path $SidecarDir "dist"),
(Join-Path $SidecarDir "build")
)
foreach ($dir in $dirsToClean) {
if (Test-Path $dir) {
Remove-Item -Recurse -Force $dir
Write-Host " 已刪除: $dir" -ForegroundColor Gray
}
}
# 刪除 spec 檔案
Get-ChildItem -Path $SidecarDir -Filter "*.spec" | Remove-Item -Force
Write-OK "清理完成"
}
function Build-Sidecar {
Write-Step "打包 Sidecar (Python → exe)..."
Write-Host " 這可能需要 5-10 分鐘..." -ForegroundColor Gray
Push-Location $SidecarDir
try {
# 建立/啟動虛擬環境
if (-not (Test-Path "venv")) {
Write-Host " 建立虛擬環境..." -ForegroundColor Gray
python -m venv venv
}
# 啟動虛擬環境並安裝依賴
& ".\venv\Scripts\Activate.ps1"
Write-Host " 安裝依賴..." -ForegroundColor Gray
pip install --upgrade pip -q
pip install -r requirements.txt -q
pip install pyinstaller -q
# 建立 dist 目錄
if (-not (Test-Path "dist")) {
New-Item -ItemType Directory -Path "dist" | Out-Null
}
Write-Host " 執行 PyInstaller..." -ForegroundColor Gray
# PyInstaller 打包
pyinstaller `
--onedir `
--name transcriber `
--distpath dist `
--workpath build `
--noconfirm `
--clean `
--console `
--hidden-import=faster_whisper `
--hidden-import=ctranslate2 `
--hidden-import=huggingface_hub `
--hidden-import=tokenizers `
--hidden-import=onnxruntime `
--hidden-import=opencc `
--hidden-import=pydub `
--hidden-import=numpy `
--hidden-import=av `
--collect-data=onnxruntime `
--collect-data=faster_whisper `
transcriber.py
if (Test-Path "dist\transcriber\transcriber.exe") {
Write-OK "Sidecar 打包完成"
} else {
Write-Err "Sidecar 打包失敗"
exit 1
}
}
finally {
Pop-Location
}
}
function Build-Electron {
Write-Step "打包 Electron 應用..."
Push-Location $ClientDir
try {
# 檢查 Sidecar 是否存在
$sidecarExe = Join-Path $SidecarDir "dist\transcriber\transcriber.exe"
if (-not (Test-Path $sidecarExe)) {
Write-Err "找不到 Sidecar: $sidecarExe"
Write-Warn "請先執行完整打包或移除 -SkipSidecar 參數"
exit 1
}
# 總是執行 npm install 確保依賴完整
Write-Host " 安裝 npm 依賴..." -ForegroundColor Gray
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 如果不存在
if (-not (Test-Path ".env") -and (Test-Path ".env.example")) {
Copy-Item ".env.example" ".env"
Write-Warn "已建立 .env請確認設定"
}
Write-Host " 執行 electron-builder..." -ForegroundColor Gray
# 直接執行 node_modules 中的 electron-builder
& $electronBuilderPath --win
if ($LASTEXITCODE -ne 0) {
Write-Err "electron-builder 執行失敗"
exit 1
}
if (Test-Path "dist\*.exe") {
Write-OK "Electron 打包完成"
} else {
Write-Err "Electron 打包失敗 - dist 目錄中找不到 exe 檔案"
exit 1
}
}
finally {
Pop-Location
}
}
function Copy-Output {
Write-Step "整合輸出..."
if (-not (Test-Path $BuildDir)) {
New-Item -ItemType Directory -Path $BuildDir | Out-Null
}
# 複製 exe 檔案
$exeFiles = Get-ChildItem -Path (Join-Path $ClientDir "dist") -Filter "*.exe"
foreach ($file in $exeFiles) {
Copy-Item $file.FullName -Destination $BuildDir
Write-Host " 複製: $($file.Name)" -ForegroundColor Gray
}
Write-Host ""
Write-Host "==========================================" -ForegroundColor Cyan
Write-Host " 打包完成!" -ForegroundColor Green
Write-Host "==========================================" -ForegroundColor Cyan
Write-Host ""
Write-Host " 輸出目錄: $BuildDir" -ForegroundColor White
Write-Host ""
# 列出輸出檔案
Get-ChildItem -Path $BuildDir | ForEach-Object {
$size = [math]::Round($_.Length / 1MB, 2)
Write-Host " $($_.Name) ($size MB)" -ForegroundColor Gray
}
Write-Host ""
Write-Host " 使用說明:" -ForegroundColor Yellow
Write-Host " 直接執行 .exe 檔案即可,無需安裝" -ForegroundColor Gray
Write-Host ""
}
# 主程式
if ($Help) {
Show-Help
exit 0
}
Show-Banner
Test-Prerequisites
if ($Clean) {
Clear-BuildDirs
}
# Update config.json if API URL is specified
if ($ApiUrl) {
Update-Config -NewApiUrl $ApiUrl
}
if (-not $SkipSidecar) {
Build-Sidecar
}
Build-Electron
Copy-Output