服务处理测试的无响应服务
本文关键字:服务 响应 测试 服务处 处理 | 更新日期: 2023-09-27 18:20:37
我正在尝试编写一个更健壮的Stop-Service cmdlet(PSv3)。基本上,通过让一个函数调用StopService,然后测试服务状态,看看服务是否真的停止了,并最终升级为服务的进程终止。
我正在尝试编写或找到一个不会优雅地停止,但在收到停止通知后往往会停留的服务。
我的"坏"服务只是使用这个:
protected override void OnStop()
{
TheEventLog.WriteEntry("StrongBad in OnStop");
Thread.Sleep(300000);
}
但服务确实会在停止服务允许的任何超时内停止。
PS C:'WINDOWS'system32> Stop-Service -Name StrongBad
WARNING: Waiting for service 'Trogdor (StrongBad)' to stop...
WARNING: Waiting for service 'Trogdor (StrongBad)' to stop...
WARNING: Waiting for service 'Trogdor (StrongBad)' to stop...
WARNING: Waiting for service 'Trogdor (StrongBad)' to stop...
PS C:'WINDOWS'system32> Get-Service StrongBad
Status Name DisplayName
------ ---- -----------
Stopped StrongBad Trogdor
我真的希望(在这种情况下)Stop-Service cmdlet返回一条消息,说明服务未能在分配的时间内停止。
当服务具有依赖关系时,我似乎看到了类似于预期的行为:
PS C:'src'Enterprise'Enterprise'Systems'Scripts'Powershell'Includes> Stop-Service -Name nsi -Force
Stop-Service : Service 'Network Store Interface Service (nsi)' cannot be stopped due to the following error: Cannot stop LanmanWorkstation service on computer '.'.
At line:1 char:1
+ Stop-Service -Name nsi -Force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (System.ServiceProcess.ServiceController:ServiceController) [Stop-Service], ServiceCommandException
+ FullyQualifiedErrorId : CouldNotStopService,Microsoft.PowerShell.Commands.StopServiceCommand
Stop-Service : Collection was modified; enumeration operation may not execute.
At line:1 char:1
+ Stop-Service -Name nsi -Force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Stop-Service], InvalidOperationException
+ FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.PowerShell.Commands.StopServiceCommand
无法使Stop-Service
超时。它很乐意永远等待服务停止(问我怎么知道的)。根据这个答案,你需要启动一个后台作业来停止服务,等待它完成,如果服务没有停止,就终止它:
Start-Job { Stop-Service StrongBad } | Wait-Job -Timeout 30
$svc = Get-Service StrongBad
if( $svc.Status -ne 'Stopped' )
{
# This assumes the process name is strongbad
Stop-Process StrongBad
}
这实际上是一个由两部分组成的问题。第一部分是如何编写一个不会立即关闭的服务,以便测试我更健壮的停止服务。
这一半问题的答案是,当停止时,我需要在服务中设置一个WaitHint:
serviceStatus.dwCurrentState = ServiceState.SERVICE_STOP_PENDING;
serviceStatus.dwWaitHint = 100000;
SetServiceStatus(this.ServiceHandle, ref serviceStatus);
问题的后半部分是@Aaron所说的,我如何使停止服务更健壮,但我将其概括为:
$sb = [scriptblock]::Create("Stop-Service $ServiceName")
$jobid = Start-Job $sb | Wait-Job -Timeout $Timeout