64 lines
4.1 KiB
PowerShell
64 lines
4.1 KiB
PowerShell
|
|
[CmdletBinding(SupportsShouldProcess = $true)]
|
|||
|
|
param(
|
|||
|
|
[Parameter(Mandatory = $true)][ValidateSet('Check', 'Start', 'Stop')][string]$Action,
|
|||
|
|
[Parameter(Mandatory = $true)][string]$RuntimeDirectory,
|
|||
|
|
[switch]$Apply,
|
|||
|
|
[switch]$Force,
|
|||
|
|
[ValidateRange(0, 600)][int]$GraceSeconds = 30
|
|||
|
|
)
|
|||
|
|
. (Join-Path $PSScriptRoot 'TaskHost.Common.ps1')
|
|||
|
|
$runtime = [IO.Path]::GetFullPath($RuntimeDirectory)
|
|||
|
|
$manifest = Join-Path $runtime 'task-manifest.json'
|
|||
|
|
if (-not (Test-Path -LiteralPath $manifest -PathType Leaf)) { throw '未找到项目安装清单,拒绝管理其他任务。' }
|
|||
|
|
$saved = Get-Content -LiteralPath $manifest -Raw | ConvertFrom-Json
|
|||
|
|
if (-not $saved.PSObject.Properties['ServiceSid'] -or -not $saved.PSObject.Properties['LogonType']) {
|
|||
|
|
throw '安装清单缺少账号核验信息,请管理员核对后重新准备安装。'
|
|||
|
|
}
|
|||
|
|
$plan = Get-PayrollTaskPlan -ProjectRoot $saved.ProjectRoot -PythonPath $saved.PythonPath -RuntimeDirectory $runtime `
|
|||
|
|
-ConnectionFile $saved.ConnectionFile -TaskPath $saved.TaskPath -ApiPort $saved.ApiPort
|
|||
|
|
$tasks = foreach ($expected in $plan.Tasks) {
|
|||
|
|
$actual = Get-ScheduledTask -TaskPath $plan.TaskPath -TaskName $expected.Name -ErrorAction Stop
|
|||
|
|
Assert-PayrollTaskPrincipal -Actual $actual.Principal -Expected $saved
|
|||
|
|
if (@($actual.Actions).Count -ne 1 -or $actual.Actions[0].Execute -ne $expected.Execute -or
|
|||
|
|
$actual.Actions[0].Arguments -ne $expected.Arguments -or $actual.Actions[0].WorkingDirectory -ne $expected.WorkingDirectory) {
|
|||
|
|
throw '任务动作与项目清单不一致,拒绝启动或停止。'
|
|||
|
|
}
|
|||
|
|
$info = Get-ScheduledTaskInfo -TaskPath $plan.TaskPath -TaskName $expected.Name
|
|||
|
|
[pscustomobject]@{ Name = $expected.Name; State = [string]$actual.State;
|
|||
|
|
LastTaskResult = $info.LastTaskResult; LastRunTime = $info.LastRunTime; NextRunTime = $info.NextRunTime;
|
|||
|
|
SettingsValid = ($actual.Settings.MultipleInstances -eq 'IgnoreNew' -and $actual.Settings.RestartCount -eq 3 -and
|
|||
|
|
$actual.Settings.RestartInterval -eq 'PT1M' -and $actual.Settings.ExecutionTimeLimit -eq 'PT0S') }
|
|||
|
|
}
|
|||
|
|
if ($Action -eq 'Check') {
|
|||
|
|
[pscustomobject]@{ TaskPath = $plan.TaskPath; StopRequested = (Test-Path -LiteralPath $plan.StopFile); Tasks = @($tasks) } | ConvertTo-Json -Depth 4
|
|||
|
|
if (@($tasks | Where-Object { -not $_.SettingsValid }).Count) { exit 1 }
|
|||
|
|
exit 0
|
|||
|
|
}
|
|||
|
|
if (-not $Apply -or -not $PSCmdlet.ShouldProcess($plan.TaskPath, $Action)) {
|
|||
|
|
[pscustomobject]@{ Preview = $true; Action = $Action; TaskPath = $plan.TaskPath; Names = @($tasks.Name) } | ConvertTo-Json
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
if (@($tasks | Where-Object { -not $_.SettingsValid }).Count) { throw '任务恢复设置不符合交付约定,拒绝改变运行状态。' }
|
|||
|
|
if ($Action -eq 'Start') {
|
|||
|
|
Assert-PayrollHostAccess -Plan $plan -ServiceSid $saved.ServiceSid
|
|||
|
|
if (Test-Path -LiteralPath $plan.StopFile) { Remove-Item -LiteralPath $plan.StopFile }
|
|||
|
|
foreach ($task in $tasks) { Enable-ScheduledTask -TaskPath $plan.TaskPath -TaskName $task.Name | Out-Null; Start-ScheduledTask -TaskPath $plan.TaskPath -TaskName $task.Name }
|
|||
|
|
Write-Output '托管任务已启动;是否自动排队仍由T_PLUS_AUTOMATION_ENABLED决定。'
|
|||
|
|
} else {
|
|||
|
|
'运维请求停止领取任务' | Set-Content -LiteralPath $plan.StopFile -Encoding UTF8
|
|||
|
|
foreach ($task in $tasks) { Disable-ScheduledTask -TaskPath $plan.TaskPath -TaskName $task.Name | Out-Null }
|
|||
|
|
$deadline = (Get-Date).AddSeconds($GraceSeconds)
|
|||
|
|
do {
|
|||
|
|
$running = @($tasks | Where-Object { (Get-ScheduledTask -TaskPath $plan.TaskPath -TaskName $_.Name).State -eq 'Running' })
|
|||
|
|
if (-not $running.Count) { break }
|
|||
|
|
Start-Sleep -Seconds 1
|
|||
|
|
} while ((Get-Date) -lt $deadline)
|
|||
|
|
if ($running.Count -and $Force) {
|
|||
|
|
foreach ($task in $running) { Stop-ScheduledTask -TaskPath $plan.TaskPath -TaskName $task.Name }
|
|||
|
|
Write-Output '已强制停止明确的项目任务;未结束的采集需在重启后人工核对中断记录。'
|
|||
|
|
} elseif ($running.Count) {
|
|||
|
|
Write-Output '已停止领取新任务,现有长采集尚在退出;未强制终止,可稍后Check。'
|
|||
|
|
exit 2
|
|||
|
|
} else { Write-Output '项目托管任务已停止。' }
|
|||
|
|
}
|