# G3SB Backman Windows Service Installation Script # Run as Administrator param( [Parameter(Mandatory=$false)] [string]$Action = "install" ) $isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { Write-Host "ERROR: Administrator privileges required" -ForegroundColor Red Write-Host "Please right-click and select 'Run as administrator'" -ForegroundColor Yellow Start-Sleep -Seconds 5 exit 1 } $serviceName = "Backman_Text2sql" $serviceDisplayName = "Backman Text2SQL Service" $serviceDescription = "Backman Text2SQL AI Backend Service" $scriptPath = Split-Path -Parent $MyInvocation.MyCommand.Path # 单文件模式:exe 在 deploy 同级目录 $exePath = Join-Path $scriptPath "Backman_Text2SQL_Server.exe" if (-not (Test-Path $exePath)) { Write-Host "ERROR: Backman_Text2SQL_Server.exe not found" -ForegroundColor Red Write-Host "Path: $exePath" -ForegroundColor Yellow Write-Host "Please run 'pyinstaller --clean main.spec' in project root first" -ForegroundColor Yellow Start-Sleep -Seconds 5 exit 1 } $NSSM_URL = "https://nssm.cc/release/nssm-2.24.zip" $nssmPath = Join-Path $scriptPath "nssm.exe" function Get-NSSM { if (-not (Test-Path $nssmPath)) { Write-Host "Downloading NSSM..." -ForegroundColor Cyan $zipPath = Join-Path $env:TEMP "nssm.zip" try { Invoke-WebRequest -Uri $NSSM_URL -OutFile $zipPath -UseBasicParsing Add-Type -AssemblyName System.IO.Compression.FileSystem [System.IO.Compression.ZipFile]::ExtractToDirectory($zipPath, $env:TEMP) $nssmSource = Get-ChildItem -Path $env:TEMP -Recurse -Filter "nssm.exe" | Where-Object { $_.FullName -like "*win64*" } | Select-Object -First 1 if ($nssmSource) { Copy-Item $nssmSource.FullName -Destination $nssmPath -Force Write-Host "NSSM downloaded to: $nssmPath" -ForegroundColor Green } else { throw "nssm.exe not found" } Remove-Item $zipPath -Force Remove-Item (Join-Path $env:TEMP "nssm-2.24") -Recurse -Force } catch { Write-Host "Failed to download NSSM: $_" -ForegroundColor Red Write-Host "Manual: Visit https://nssm.cc/download and place nssm.exe in this directory" -ForegroundColor Yellow Start-Sleep -Seconds 5 exit 1 } } else { Write-Host "NSSM exists: $nssmPath" -ForegroundColor Green } } function Install-Service { Write-Host "`n=================================" -ForegroundColor Cyan Write-Host "Installing G3SB Backman Service" -ForegroundColor Cyan Write-Host "=================================`n" -ForegroundColor Cyan Get-NSSM $workDir = $scriptPath Write-Host "Creating service: $serviceName" -ForegroundColor Cyan & $nssmPath install $serviceName "$exePath" if ($LASTEXITCODE -eq 0) { & $nssmPath set $serviceName DisplayName $serviceDisplayName & $nssmPath set $serviceName Description $serviceDescription & $nssmPath set $serviceName Start SERVICE_AUTO_START & $nssmPath set $serviceName AppDirectory $workDir $logDir = Join-Path $workDir "logs" if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force | Out-Null } $stdoutLog = Join-Path $logDir "service_stdout.log" $stderrLog = Join-Path $logDir "service_stderr.log" & $nssmPath set $serviceName AppStdout $stdoutLog & $nssmPath set $serviceName AppStderr $stderrLog & $nssmPath set $serviceName AppRestartDelay 1000 & $nssmPath set $serviceName AppExit Default Restart Write-Host "\n[OK] Service installed successfully!" -ForegroundColor Green Write-Host " Service Name: $serviceName" -ForegroundColor White Write-Host " Display Name: $serviceDisplayName" -ForegroundColor White Write-Host " Executable: $exePath" -ForegroundColor White $response = Read-Host "`nStart service now? (Y/n)" if ([string]::IsNullOrWhiteSpace($response) -or $response -match '^[Yy]$') { Start-ServiceAction } Write-Host "`nTips:" -ForegroundColor Yellow Write-Host " Status: .\install_service.ps1 status" -ForegroundColor White Write-Host " Stop: .\install_service.ps1 stop" -ForegroundColor White Write-Host " Start: .\install_service.ps1 start" -ForegroundColor White Write-Host " Uninstall: .\install_service.ps1 uninstall" -ForegroundColor White } else { Write-Host "`n[FAIL] Service installation failed!" -ForegroundColor Red } } function Uninstall-Service { Write-Host "`n=================================" -ForegroundColor Cyan Write-Host "Uninstalling G3SB Backman Service" -ForegroundColor Cyan Write-Host "=================================`n" -ForegroundColor Cyan Stop-ServiceAction Get-NSSM $confirm = Read-Host "Confirm uninstall? (y/N)" if ($confirm -notmatch '^[Yy]$') { Write-Host "Cancelled" -ForegroundColor Yellow return } & $nssmPath remove $serviceName confirm if ($LASTEXITCODE -eq 0) { Write-Host "`n[OK] Service uninstalled!" -ForegroundColor Green } else { Write-Host "`n[FAIL] Uninstall failed!" -ForegroundColor Red } } function Start-ServiceAction { Write-Host "`nStarting service $serviceName ..." -ForegroundColor Cyan try { Start-Service -Name $serviceName -ErrorAction Stop Write-Host "[OK] Service started" -ForegroundColor Green Start-Sleep -Seconds 3 $status = Get-Service -Name $serviceName -ErrorAction SilentlyContinue if ($status.Status -eq 'Running') { Write-Host "[OK] Service running" -ForegroundColor Green } else { Write-Host "[WARN] Service status: $($status.Status)" -ForegroundColor Yellow } } catch { Write-Host "[FAIL] Failed to start: $_" -ForegroundColor Red } } function Stop-ServiceAction { Write-Host "`nStopping service $serviceName ..." -ForegroundColor Cyan try { Stop-Service -Name $serviceName -Force -ErrorAction Stop Write-Host "[OK] Service stopped" -ForegroundColor Green } catch { Write-Host "[WARN] Service not running or failed to stop: $_" -ForegroundColor Yellow } } function Get-ServiceStatus { Write-Host "`n=================================" -ForegroundColor Cyan Write-Host "Service Status" -ForegroundColor Cyan Write-Host "=================================`n" -ForegroundColor Cyan try { $service = Get-Service -Name $serviceName -ErrorAction Stop Write-Host "Service Name: $($service.Name)" -ForegroundColor White Write-Host "Display Name: $($service.DisplayName)" -ForegroundColor White Write-Host "Status: $($service.Status)" -ForegroundColor $(if ($service.Status -eq 'Running') { 'Green' } else { 'Yellow' }) Write-Host "Start Type: $($service.StartType)" -ForegroundColor White if ($service.Status -eq 'Running') { Write-Host "`n[OK] Service is running" -ForegroundColor Green Write-Host "URL: http://localhost:8041" -ForegroundColor Cyan } else { Write-Host "`n[WARN] Service is not running" -ForegroundColor Yellow } } catch { Write-Host "[FAIL] Service not installed" -ForegroundColor Red Write-Host "Install: .\install_service.ps1 install" -ForegroundColor Yellow } Write-Host "" } Write-Host "`nG3SB Backman Service Manager" -ForegroundColor Cyan Write-Host "============================`n" -ForegroundColor Cyan switch ($Action.ToLower()) { "install" { Install-Service } "uninstall" { Uninstall-Service } "start" { Start-ServiceAction } "stop" { Stop-ServiceAction } "status" { Get-ServiceStatus } "restart" { Stop-ServiceAction; Start-Sleep -Seconds 2; Start-ServiceAction } default { Write-Host "Usage: .\install_service.ps1 [action]" -ForegroundColor Yellow Write-Host "Actions: install, uninstall, start, stop, restart, status" -ForegroundColor White } } Write-Host ""