param( [string]$ServiceName = "MailPolicySyncWorker", [string]$PhpPath = "php", [string]$ProjectRoot = "D:\laragon\www\MailPolicy", [string]$QueueConnection = "database", [string]$QueueName = "exchange-sync", [string]$ServiceUser = "", [string]$ServicePassword = "", [switch]$StartService ) function Resolve-NssmPath { param([string]$Root) $candidates = @( (Join-Path $Root "scripts\windows\tools\nssm\win64\nssm.exe"), (Join-Path $Root "scripts\windows\tools\nssm\nssm.exe"), (Join-Path $Root "tools\nssm\win64\nssm.exe"), (Join-Path $Root "tools\nssm\nssm.exe") ) foreach ($candidate in $candidates) { if (Test-Path $candidate) { return $candidate } } $command = Get-Command nssm.exe -ErrorAction SilentlyContinue if ($command) { return $command.Source } throw "nssm.exe was not found. Put it under scripts\windows\tools\nssm\win64\nssm.exe or add it to PATH." } $nssm = Resolve-NssmPath -Root $ProjectRoot $artisan = Join-Path $ProjectRoot "artisan" $arguments = "queue:work $QueueConnection --queue=$QueueName --sleep=3 --tries=1 --timeout=900 --no-interaction" $stdoutLog = Join-Path $ProjectRoot "storage\logs\nssm-sync-worker.log" $stderrLog = Join-Path $ProjectRoot "storage\logs\nssm-sync-worker-error.log" if (!(Test-Path $ProjectRoot)) { throw "Project root not found: $ProjectRoot" } if (!(Test-Path $artisan)) { throw "Laravel artisan file not found: $artisan" } $logDirectory = Split-Path $stdoutLog -Parent if (!(Test-Path $logDirectory)) { New-Item -ItemType Directory -Path $logDirectory -Force | Out-Null } $existingService = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue if (-not $existingService) { & $nssm install $ServiceName $PhpPath $artisan $arguments } & $nssm set $ServiceName Application $PhpPath & $nssm set $ServiceName AppParameters "$artisan $arguments" & $nssm set $ServiceName AppDirectory $ProjectRoot & $nssm set $ServiceName AppStdout $stdoutLog & $nssm set $ServiceName AppStderr $stderrLog & $nssm set $ServiceName AppRotateFiles 1 & $nssm set $ServiceName AppRotateOnline 1 & $nssm set $ServiceName Start SERVICE_AUTO_START & $nssm set $ServiceName AppStopMethodSkip 6 if ($ServiceUser -ne "") { if ($ServicePassword -eq "") { throw "ServicePassword is required when ServiceUser is provided." } & $nssm set $ServiceName ObjectName $ServiceUser $ServicePassword } Write-Host "NSSM service '$ServiceName' configured." Write-Host "NSSM path: $nssm" Write-Host "Application: $PhpPath" Write-Host "Arguments: $artisan $arguments" Write-Host "Stdout log: $stdoutLog" Write-Host "Stderr log: $stderrLog" if ($ServiceUser -ne "") { Write-Host "Service account: $ServiceUser" } if ($StartService) { & $nssm start $ServiceName Write-Host "NSSM service '$ServiceName' started." }