简体   繁体   English

“SERVICE_CONTROL_SESSIONCHANGE”通知从未在 Windows 10 中的 C++ 服务申请中收到

[英]"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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM