服务需要检测工作站是否已锁定,并且屏幕保护程序处于活动状态

我正在开发一项服务,需要检测登录到单台机器的所有用户的用户状态。 具体来说,我想检查屏幕保护程序是否处于活动状态以及其会话是否已锁定。

此代码将在系统级服务下运行,并且没有可见的UI,因此可以排除多个选项(捕获WM消息等)。

除了正常的工作站之外,我还希望能够在有多个用户登录的终端服务器上工作。 由于这些要求,我想知道是否需要涉及多个Win32 API。

关于从哪里开始的任何想法?

最直接的方法是在每个用户的会话中运行一个小应用程序。 此应用程序的每个实例都可以与服务的主要实例进行通信。

Windows会非常努力地将登录会话分开 – 包括服务和交互式桌面之间以及各个终端服务会话之间 – 因此除非您的应用程序在该会话中运行,否则访问有关用户会话的此类信息变得非常棘手首先。

作为服务,您可以使用事件OnSessionChange来捕获所有相关时刻。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceProcess; using System.Diagnostics; namespace MyCode { class MyService : ServiceBase { public MyService() { this.CanHandleSessionChangeEvent = true; } protected override void OnSessionChange(SessionChangeDescription changeDescription) { switch (changeDescription.Reason) { case SessionChangeReason.SessionLogon: Debug.WriteLine(changeDescription.SessionId + " logon"); break; case SessionChangeReason.SessionLogoff: Debug.WriteLine(changeDescription.SessionId + " logoff"); break; case SessionChangeReason.SessionLock: Debug.WriteLine(changeDescription.SessionId + " lock"); break; case SessionChangeReason.SessionUnlock: Debug.WriteLine(changeDescription.SessionId + " unlock"); break; } base.OnSessionChange(changeDescription); } } } 

我确信可以根据changeDescription.SessionId识别用户。 但此刻我不知道如何……

编辑:这应该是可能的

  public static WindowsIdentity GetUserName(int sessionId) { foreach (Process p in Process.GetProcesses()) { if(p.SessionId == sessionId) { return new WindowsIdentity(p.Handle); } } return null; } 

MSDN链接

  • system.serviceprocess.servicebase.onsessionchange
  • system.serviceprocess.sessionchangedescription
  • system.serviceprocess.sessionchangereason

一个更简单的解决方案是使用包装各种TS API的Cassia来检查用户空闲的时间:

 using Cassia; foreach (ITerminalServicesSession session in new TerminalServicesManager().GetSessions()) { if ((session.CurrentTime - session.LastInputTime > TimeSpan.FromMinutes(10)) && (!string.IsNullOrEmpty(session.UserName))) { Console.WriteLine("Session {0} (User {1}) is idle", session.SessionId, session.UserName); } }