我有兴趣听取从会话0中运行的Windows服务注销事件
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]
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);
}
答案 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的注销事件也是如此,所以这两个对你来说太迟了。