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
相关产品推荐
相关产品推荐

