113 lines
4.0 KiB
PowerShell
113 lines
4.0 KiB
PowerShell
[CmdletBinding(SupportsShouldProcess = $true)]
|
|
param(
|
|
[string]$ServiceName = "ScreenJobBackend",
|
|
[string]$DisplayName = "ScreenJob Backend",
|
|
[string]$Description = "Runs the ScreenJob backend (start_backend.ps1) as a Windows service.",
|
|
[ValidateSet("Automatic", "Manual", "Disabled")]
|
|
[string]$StartupType = "Automatic",
|
|
[switch]$DelayedAutoStart,
|
|
[switch]$ForceReinstall,
|
|
[switch]$StartAfterInstall
|
|
)
|
|
|
|
Set-StrictMode -Version Latest
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
function Test-IsAdministrator {
|
|
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
|
|
$principal = New-Object Security.Principal.WindowsPrincipal($identity)
|
|
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
|
}
|
|
|
|
if (-not (Test-IsAdministrator)) {
|
|
throw "Run this script from an elevated PowerShell session (Run as Administrator)."
|
|
}
|
|
|
|
$scriptDir = Split-Path -Parent $PSCommandPath
|
|
$backendScript = Join-Path $scriptDir "start_backend.ps1"
|
|
if (-not (Test-Path -LiteralPath $backendScript)) {
|
|
throw "Backend launcher script not found: $backendScript"
|
|
}
|
|
|
|
$projectFile = Join-Path $scriptDir "service_host\ScreenJob.WindowsServiceHost\ScreenJob.WindowsServiceHost.csproj"
|
|
if (-not (Test-Path -LiteralPath $projectFile)) {
|
|
throw "Windows service host project not found: $projectFile"
|
|
}
|
|
|
|
$dotnetCmd = Get-Command dotnet -ErrorAction SilentlyContinue
|
|
if ($null -eq $dotnetCmd) {
|
|
throw "dotnet SDK was not found in PATH. Install .NET SDK 10+ and retry."
|
|
}
|
|
|
|
$publishDir = Join-Path $scriptDir "service_host\publish"
|
|
$serviceExe = Join-Path $publishDir "ScreenJob.WindowsServiceHost.exe"
|
|
$logDir = Join-Path $scriptDir "screenjob_runs\service"
|
|
|
|
if ($PSCmdlet.ShouldProcess($projectFile, "Publish Windows service host")) {
|
|
& $dotnetCmd.Source publish `
|
|
$projectFile `
|
|
-c Release `
|
|
-r win-x64 `
|
|
--self-contained false `
|
|
-p:PublishSingleFile=true `
|
|
-o $publishDir
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "dotnet publish failed with exit code $LASTEXITCODE."
|
|
}
|
|
}
|
|
|
|
if (-not (Test-Path -LiteralPath $serviceExe)) {
|
|
throw "Published service executable not found: $serviceExe"
|
|
}
|
|
|
|
$binaryPath = "`"$serviceExe`" --backend-script `"$backendScript`" --working-dir `"$scriptDir`" --log-dir `"$logDir`""
|
|
|
|
$existingService = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
|
|
if ($null -ne $existingService) {
|
|
if (-not $ForceReinstall) {
|
|
throw "Service '$ServiceName' already exists. Re-run with -ForceReinstall to replace it."
|
|
}
|
|
|
|
if ($PSCmdlet.ShouldProcess($ServiceName, "Remove existing service")) {
|
|
if ($existingService.Status -ne "Stopped") {
|
|
Stop-Service -Name $ServiceName -Force -ErrorAction Stop
|
|
}
|
|
|
|
& sc.exe delete $ServiceName | Out-Null
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "Failed to delete existing service '$ServiceName' (sc.exe exit code $LASTEXITCODE)."
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($PSCmdlet.ShouldProcess($ServiceName, "Create service")) {
|
|
New-Service `
|
|
-Name $ServiceName `
|
|
-BinaryPathName $binaryPath `
|
|
-DisplayName $DisplayName `
|
|
-Description $Description `
|
|
-StartupType $StartupType
|
|
|
|
if ($StartupType -eq "Automatic" -and $DelayedAutoStart) {
|
|
& sc.exe config $ServiceName start= delayed-auto | Out-Null
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "Failed to enable delayed auto-start for '$ServiceName' (sc.exe exit code $LASTEXITCODE)."
|
|
}
|
|
}
|
|
|
|
# Restart on first/second/subsequent failure after 5 seconds.
|
|
& sc.exe failure $ServiceName reset= 86400 actions= restart/5000/restart/5000/restart/5000 | Out-Null
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "Failed to configure failure actions for '$ServiceName' (sc.exe exit code $LASTEXITCODE)."
|
|
}
|
|
|
|
if ($StartAfterInstall) {
|
|
Start-Service -Name $ServiceName -ErrorAction Stop
|
|
}
|
|
}
|
|
|
|
Write-Host "Service '$ServiceName' installed successfully." -ForegroundColor Green
|
|
Write-Host "Check status with: Get-Service -Name $ServiceName"
|
|
Write-Host "View logs in: $logDir"
|