[英]"SERVICE_CONTROL_SESSIONCHANGE" notification is never received in C++ service application in Windows 10
I have been trying to develop a service application to hook into the login/logout event of windows. My development environment is Windows 10. As it is a service application, based on suggestion from some of the existing posts in Stackoverflow and other dev platform, I have registered the service to get notified in different events.我一直在尝试开发一个服务应用程序来挂钩 windows 的登录/注销事件。我的开发环境是 Windows 10。由于它是一个服务应用程序,因此根据 Stackoverflow 和其他开发平台中一些现有帖子的建议,我已经注册了该服务以在不同事件中得到通知。 Below is the snippet I tried.
下面是我试过的片段。
SERVICE_STATUS_HANDLE gSvcStatusHandle;
VOID WINAPI SvcCtrlHandlerEx(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext)
{
switch (dwControl)
{
case SERVICE_CONTROL_STOP:
writeEventLog(utils.GetDefaultTitle(), L"Service About to end");
ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
// Signal the service to stop.
SetEvent(ghSvcStopEvent);
ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);
applicationLogger.LogWarning("Service stopped.");
break;
return;
case SERVICE_CONTROL_INTERROGATE:
writeEventLog(GetDefaultTitle(), L"Service=interrogate");
applicationLogger.LogWarning("Service Interrogate.");
break;
case SERVICE_CONTROL_PAUSE:
writeEventLog(GetDefaultTitle(), L"Service=paused");
applicationLogger.LogWarning("Service pasued.");
break;
case SERVICE_CONTROL_CONTINUE:
writeEventLog(GetDefaultTitle(), L"Service=continued");
applicationLogger.LogWarning("Service continued.");
break;
case SERVICE_CONTROL_SESSIONCHANGE:
writeEventLog(GetDefaultTitle(), L"Service=Session=Changed");
applicationLogger.LogWarning("Session changed");
if (WTS_SESSION_LOGOFF == (dwEvtype & WTS_SESSION_LOGOFF))
{
WTSSESSION_NOTIFICATION* pSessionNotification = static_cast<WTSSESSION_NOTIFICATION*>(pEvtData);
}
else if (WTS_SESSION_LOGON == (dwEvtype & WTS_SESSION_LOGOFF))
{
WTSSESSION_NOTIFICATION* pSessionNotification = static_cast<WTSSESSION_NOTIFICATION*>(pEvtData);
break;
default:
writeEventLog(GetDefaultTitle(), L"Service=Dfault");
applicationLogger.LogWarning("Service default.");
break;
}
}
VOID WINAPI SvcMain(DWORD dwArgc, LPTSTR* lpszArgv)
{
gSvcStatusHandle = RegisterServiceCtrlHandlerEx(SVCNAME, reinterpret_cast<LPHANDLER_FUNCTION_EX>(SvcCtrlHandlerEx), NULL);
}
For the debug purpose, I am trying to log events name whenever service receives any event notification.出于调试目的,每当服务收到任何事件通知时,我都会尝试记录事件名称。 However, the only notification I receive is then I try to stop the service, "case SERVICE_CONTROL_STOP" will be executed.
但是,我收到的唯一通知是我尝试停止服务,将执行“case SERVICE_CONTROL_STOP”。 I am interested in receiving "SERVICE_CONTROL_SESSIONCHANGE" event so that I can retrive user's login information.
我有兴趣接收“SERVICE_CONTROL_SESSIONCHANGE”事件,以便我可以检索用户的登录信息。
Therefore, can you point the area that I have been doing wrong?因此,你能指出我做错的地方吗? Also is the method inside "SERVICE_CONTROL_SESSIONCHANGE" the correct way to get login/logout event from windows?
“SERVICE_CONTROL_SESSIONCHANGE”中的方法也是从 windows 获取登录/注销事件的正确方法吗? I tried signing in and out in windows10 system, but no logs were written in event viewer.
我试过在windows10系统中登录和注销,但是事件查看器中没有写入日志。
To receive SERVICE_CONTROL_SESSIONCHANGE
notifications in your HandlerEx
callback, you need to call SetServiceStatus()
with the SERVICE_ACCEPT_SESSIONCHANGE
flag enabled in the SERVICE_STATUS::dwControlsAccepted
field.要在
HandlerEx
回调中接收SERVICE_CONTROL_SESSIONCHANGE
通知,您需要调用SetServiceStatus()
并在SERVICE_STATUS::dwControlsAccepted
字段中启用SERVICE_ACCEPT_SESSIONCHANGE
标志。
Control code 控制码
Meaning 意义
SERVICE_ACCEPT_SESSIONCHANGE 0x00000080 SERVICE_ACCEPT_SESSIONCHANGE 0x00000080
The service is notified when the computer's session status has changed. 当计算机的 session 状态发生变化时,该服务会收到通知。 This enables the system to send SERVICE_CONTROL_SESSIONCHANGE notifications to the service.
这使系统能够向服务发送 SERVICE_CONTROL_SESSIONCHANGE 通知。
As for your handler itself, you should not be using operator&
with the dwEventType
parameter, as it is not a bitmask.至于您的处理程序本身,您不应该将
operator&
与dwEventType
参数一起使用,因为它不是位掩码。 Use operator==
instead (or a switch
):使用
operator==
代替(或switch
):
case SERVICE_CONTROL_SESSIONCHANGE:
writeEventLog(GetDefaultTitle(), L"Service=Session=Changed");
applicationLogger.LogWarning("Session changed");
if (dwEventType == WTS_SESSION_LOGOFF)
{
WTSSESSION_NOTIFICATION* pSessionNotification = static_cast<WTSSESSION_NOTIFICATION*>(lpEventData);
// ...
}
else if (dwEventType == WTS_SESSION_LOGON)
{
WTSSESSION_NOTIFICATION* pSessionNotification = static_cast<WTSSESSION_NOTIFICATION*>(lpEventData);
// ...
}
break;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.