Public/ps1/Configuration/Service/Install-ApprxrService.ps1

<#
.SYNOPSIS
    Installs Apprxr as a Windows service using NSSM.
.DESCRIPTION
    Downloads NSSM into the configuration folder if not present and configures a Windows service to run Apprxr using NSSM. The service name and entrypoint can be extended with a custom string using the NameExtension parameter. If NameExtension is provided, it is appended to the service name and Start-Apprxr command, and saved to configuration for consistent service management.
.PARAMETER NameExtension
    Optional. A string to append to the service name and Start-Apprxr entrypoint. If provided, the service will be named 'ApprxrService_<NameExtension>' and will run 'Start-Apprxr<NameExtension>'. This value is also saved to configuration for use by other service management commands.
.EXAMPLE
    Install-ApprxrService -NameExtension 'Test'
    # Installs the service as 'ApprxrService_Test' running 'Start-Apprxr_Test', and saves 'Test' as the ServiceNameExtension in configuration.
#>

function Install-ApprxrService {
    [CmdletBinding()]
    param(
        [string]$NameExtension
    )
    $configFolder = Get-ApprxrConfigurationFolder
    $nssmExe = Join-Path $configFolder 'nssm.exe'
    if (-not (Test-Path $nssmExe)) {
        Write-Host "Downloading NSSM..." -ForegroundColor Yellow
        $nssmUrl = 'https://nssm.cc/release/nssm-2.24.zip'
        $zipPath = Join-Path $configFolder 'nssm.zip'
        Invoke-WebRequest -Uri $nssmUrl -OutFile $zipPath
        Add-Type -AssemblyName System.IO.Compression.FileSystem
        [System.IO.Compression.ZipFile]::ExtractToDirectory($zipPath, $configFolder)
        Remove-Item $zipPath
        $nssmExeFound = Get-ChildItem -Path $configFolder -Recurse -Filter nssm.exe | Select-Object -First 1
        if ($nssmExeFound) {
            Copy-Item $nssmExeFound.FullName $nssmExe -Force
        } else {
            throw "NSSM executable not found after extraction."
        }
    }
    $pwshPath = (Get-Command pwsh).Source
    $modulePath = Join-Path $PSScriptRoot '..'
    $modulePath = Join-Path $modulePath '..'
    $modulePath = Join-Path $modulePath '..'
    $modulePath = Join-Path $modulePath 'Apprxr.psm1'
    $modulePath = [System.IO.Path]::GetFullPath($modulePath)
    $serviceSuffix = if ($NameExtension) { "_$NameExtension" } else { '' }
    $ServiceName = "ApprxrService$serviceSuffix"
    $startCommand = "Start-Apprxr$serviceSuffix"
    $arguments = "-NoProfile -Command 'Import-Module ''$modulePath''; $startCommand'"
    & $nssmExe install $ServiceName $pwshPath $arguments
    if ($NameExtension) {
        Set-ApprxrConfigurationValue -Key 'ServiceNameExtension' -Value $NameExtension
    }
    Log-Apprxr "Service '$ServiceName' installed to run $startCommand from module using NSSM."
}