# Install or reinstall the Utopia Canteen backend as a Windows Service (requires Administrator). param( [string]$InstallPath = "C:\UtopiaCanteenBackend", [string]$ServiceName = "UtopiaCanteenBackend", [string]$DisplayName = "Utopia Canteen Backend", [ValidateSet("Debug", "Release")] [string]$Configuration = "Release", [switch]$SkipPublish, [switch]$AddUrlAcl, [string]$UrlAclUser = "Everyone" ) $ErrorActionPreference = "Stop" function Test-Administrator { $current = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal($current) return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } if (-not (Test-Administrator)) { Write-Error "Run this script in an elevated PowerShell (Run as administrator)." exit 1 } $ScriptDir = $PSScriptRoot if (-not $SkipPublish) { & (Join-Path $ScriptDir "publish-backend.ps1") -OutputPath $InstallPath -Configuration $Configuration } $ExePath = Join-Path $InstallPath "UtopiaCanteen.BackendService.exe" if (-not (Test-Path $ExePath)) { throw "Executable not found: $ExePath. Run publish-backend.ps1 first." } # HttpListener on http://+:5000/ often needs a URL reservation. if ($AddUrlAcl) { Write-Host "Adding URL ACL for http://+:5000/ (user: $UrlAclUser)" netsh http add urlacl url=http://+:5000/ user=$UrlAclUser 2>$null if ($LASTEXITCODE -ne 0) { Write-Warning "urlacl may already exist or failed (exit $LASTEXITCODE). Continue if the service binds OK." } } $existing = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue if ($existing) { Write-Host "Stopping and removing existing service: $ServiceName" if ($existing.Status -eq "Running") { Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue Start-Sleep -Seconds 2 } sc.exe delete $ServiceName | Out-Null Start-Sleep -Seconds 2 } $binPath = "`"$ExePath`"" Write-Host "Creating service $ServiceName -> $ExePath" sc.exe create $ServiceName binPath= $binPath start= auto DisplayName= $DisplayName if ($LASTEXITCODE -ne 0) { throw "sc create failed with exit code $LASTEXITCODE" } sc.exe description $ServiceName "Central canteen API, SQLite, and HRMS/UIND sync for RFID scanners." sc.exe failure $ServiceName reset= 86400 actions= restart/60000/restart/60000/restart/60000 Write-Host "Starting service..." sc.exe start $ServiceName if ($LASTEXITCODE -ne 0) { Write-Warning "sc start returned $LASTEXITCODE. Check Event Viewer and appsettings.json." } else { Write-Host "Service started. Health check: http://localhost:5000/api/health" } Write-Host @" Installed: Path: $InstallPath Service: $ServiceName (auto-start) Data: %LocalAppData%\UtopiaCanteenBackend\ Firewall: allow inbound TCP 5000 on this PC for scanner clients. "@