服务处理测试的无响应服务

本文关键字:服务 响应 测试 服务处 处理 | 更新日期: 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