检测在Windows服务中注销的用户

时间:2013-06-28 14:43:22

标签: c# .net winapi windows-services winlogon

我有兴趣听取从会话0中运行的Windows服务注销事件

  • 虽然也知道正在注销哪个用户(他们的会话ID)
  • 注意我在这里讨论的是可取消的注销事件,而不是已注销的事件

如何找出正在注销的用户 - 从SessionEndingEventArgs获取会话ID?

protected override void OnStart(string[] args)
    {
        SystemEvents.SessionEnding += SystemEvents_SessionEnding;
    }

private void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
    {
        // SessionEndingEventArgs does not contain SID
        // or other user identifying info?
    }

[我没有测试whether a Windows Service can actually capture the SessionEnding event]


或者SessionChangeDescription可以用来识别即将注销的用户吗?

public ServiceApp()
    {
        CanHandleSessionChangeEvent = true;
    }

protected override void OnSessionChange(SessionChangeDescription changeDescription)
    {
        // Although changeDescription has SessionId property
        // I'm not sure it has the equivalent of session ending event?
        base.OnSessionChange(changeDescription);
    }

其他活动来源?

  • Cassia是否提供此类活动,包括用户帐户信息?
  • 或者我可以把它从某个地方的WMI拉出来吗?
  • 或直接使用某些Win32 API?

1 个答案:

答案 0 :(得分:3)

WM_QUERYENDSESSION将在结束会话中发送到桌面上的所有顶级窗口。但是,由于您的服务通常在不同的会话中运行,因此您通常不会收到通知。在Vista之前,您可以启用interaction with desktop在会话0上与用户共享桌面,但如果在另一个会话中发生注销,则不会收到发送给您的消息。在XP之后,由于session 0 isolatio n,您将无法从用户会话中收到消息。

要通知您的服务此消息,您需要在每个会话中运行代理进程(即,当用户通过开始菜单快捷方式或注册表登录时注册为自动启动)并收听WM_QUERYENDSESSION(在.Net术语中) ,在Windows窗体中运行类似Application.Run的消息泵并订阅SystemEvents.SessionEnding),然后收集会话信息并通过进程间通信方法(如命名管道)将通知发送到您的服务(如果您使用WCF,请使用NetNamedPipeBinding)。如果要获取当前会话,请使用WTSQuerySessionInformation(或.Net术语,Process.GetCurrentProcess()。SessionId)

在用户注销后调用OnSessionChange方法。对于SENS的注销事件也是如此,所以这两个对你来说太迟了。