[CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateSet('backend', 'worker', 'maintenance')][string]$Role, [Parameter(Mandatory = $true)][string]$ProjectRoot, [Parameter(Mandatory = $true)][string]$PythonPath, [Parameter(Mandatory = $true)][string]$RuntimeDirectory, [Parameter(Mandatory = $true)][string]$ConnectionFile, [int]$ApiPort = 8000 ) . (Join-Path $PSScriptRoot 'TaskHost.Common.ps1') $plan = Get-PayrollTaskPlan -ProjectRoot $ProjectRoot -PythonPath $PythonPath -RuntimeDirectory $RuntimeDirectory ` -ConnectionFile $ConnectionFile -TaskPath '\PayrollManagementSystem\' -ApiPort $ApiPort if (Test-Path -LiteralPath $plan.StopFile) { exit 0 } $env:T_PLUS_STOP_FILE = $plan.StopFile $env:T_PLUS_ENABLED = 'true' $env:T_PLUS_CONNECTION_FILE = $plan.ConnectionFile $logs = Join-Path $plan.RuntimeDirectory 'logs' New-Item -ItemType Directory -Path $logs -Force | Out-Null function Limit-PayrollLog([string]$Path) { # current 供本次运行写入,previous 保留上一次;每分钟任务不再生成无限文件。 $previous = [IO.Path]::ChangeExtension($Path, '.prev.log') if (Test-Path -LiteralPath $Path) { # .NET Framework 的 File.Replace 不接受 PowerShell 5 转换出的空备份路径。 Move-Item -LiteralPath $Path -Destination $previous -Force } } $stdoutLog = Join-Path $logs "$Role.out.log" $stderrLog = Join-Path $logs "$Role.err.log" Limit-PayrollLog $stdoutLog Limit-PayrollLog $stderrLog $arguments = switch ($Role) { 'backend' { '-m uvicorn app.main:app --host 127.0.0.1 --port ' + $ApiPort } 'worker' { '-m app.cli tplus-worker --watch --connection-file ' + (Quote-TaskArgument $plan.ConnectionFile) + ' --stop-file ' + (Quote-TaskArgument $plan.StopFile) } 'maintenance' { '-m app.cli tplus-maintain --once --connection-file ' + (Quote-TaskArgument $plan.ConnectionFile) + ' --stop-file ' + (Quote-TaskArgument $plan.StopFile) } } $process = Start-Process -FilePath $plan.PythonPath -ArgumentList $arguments -WorkingDirectory (Join-Path $plan.ProjectRoot 'backend') ` -WindowStyle Hidden -PassThru -RedirectStandardOutput $stdoutLog ` -RedirectStandardError $stderrLog $processHandle = $process.Handle while (-not $process.HasExited) { if ($Role -eq 'backend' -and (Test-Path -LiteralPath $plan.StopFile)) { Stop-Process -Id $process.Id -ErrorAction Stop } Start-Sleep -Seconds 1 $process.Refresh() } $process.WaitForExit() exit $process.ExitCode