You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows服务接收关机信号异常:仅重启生效,关机无响应

如何让Windows服务接收关机信号?

当前实现逻辑仅在系统重启时生效,系统关机时服务无响应。

已尝试的方案

  • 修改注册表项Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control下的WaitToKillServiceTimeout键值。
  • 分别单独使用SERVICE_ACCEPT_SHUTDOWN和SERVICE_ACCEPT_PRESHUTDOWN控制码。
  • 使用SERVICE_PRESHUTDOWN_INFO延长超时时间。
  • 尝试适用于控制台程序的SetConsoleCtrlHandler(HandlerRoutine, TRUE);函数。

相关代码片段(基于Qt框架的C++应用)

SVC_MAIN 函数

VOID WINAPI SVC_MAIN( DWORD dw, LPWSTR * lp)
{
    Q_UNUSED(dw);
    Q_UNUSED(lp);

    status_handle=RegisterServiceCtrlHandlerExW(SVCNAME, (LPHANDLER_FUNCTION_EX)HandlerEx, nullptr);

    if(!status_handle)
    {
        Event_Report(LPWSTR("RegisterServiceCtrlHandler"));
        return;
    }

    status.dwServiceType=SERVICE_WIN32_OWN_PROCESS;
    status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PRESHUTDOWN;
    status.dwCurrentState=SERVICE_RUNNING;
    status.dwWin32ExitCode=NO_ERROR;
    status.dwServiceSpecificExitCode=0;
    status.dwCheckPoint=0;

    if (SetServiceStatus(status_handle, &status) == FALSE)
    {
        Event_Report(LPWSTR("[ServiceCtrlHandler] SetServiceStatus returned error"));
    }

    init();
}

init 函数

void init()
{
    int argc=0;
    char *argv={nullptr};
    QCoreApplication a(argc, &argv);
    w=new worker(&a);
    QObject::connect(&a, &QObject::destroyed, w, &QObject::deleteLater);
    a.exec();
}

HandlerEx 函数

BOOL WINAPI HandlerEx(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext)
{
    switch (dwControl)
    {
    // Handle the STOP control code
    case SERVICE_CONTROL_STOP:
    {
        if (status.dwCurrentState != SERVICE_RUNNING)
        {
            return ERROR_CALL_NOT_IMPLEMENTED;
        }

        status.dwCurrentState = SERVICE_STOP_PENDING;
        status.dwWaitHint = 20000;

        if (SetServiceStatus(status_handle, &status) == FALSE)
        {
            w->Log("set service error");
            Event_Report(LPWSTR("[ServiceCtrlHandler] SetServiceStatus returned error"));
        }

        int result=w->shutdown();
        while(!result)
        {

        }

        status.dwCurrentState = SERVICE_STOPPED;
        status.dwWin32ExitCode = 0;
        status.dwCheckPoint = 0;
        status.dwWaitHint = 0;

        if (SetServiceStatus(status_handle, &status) == FALSE)
        {
            w->Log("set service error");
            Event_Report(LPTSTR("[ServiceCtrlHandler] SetServiceStatus returned error"));
        }
        return NO_ERROR;

    }

    case SERVICE_CONTROL_PRESHUTDOWN:
    {
        status.dwCurrentState = SERVICE_STOP_PENDING;
        status.dwWaitHint = 20000;

        if (SetServiceStatus(status_handle, &status) == FALSE)
        {
            w->Log("set service error");
            Event_Report(LPWSTR("[ServiceCtrlHandler] SetServiceStatus returned error"));
        }

        int result=w->shutdown();
        while(!result)
        {

        }

        return NO_ERROR;
    }

    case SERVICE_CONTROL_SHUTDOWN:
    {
        int result=w->shutdown();

        status.dwCurrentState=SERVICE_STOPPED;

        if(SetServiceStatus(status_handle, &status)==FALSE)
        {
            w->Log("set service error");
            Event_Report(LPWSTR("[ServiceCtrlHandler] SetServiceStatus returned error"));
        }
        return NO_ERROR;
    }

    case SERVICE_CONTROL_INTERROGATE:
    {
        return NO_ERROR;
    }

    default:
    {
        break;
    }
    }
    return ERROR_CALL_NOT_IMPLEMENTED;
}

内容的提问来源于stack exchange,提问作者Wasif Raza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 02:35:15