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

C# 服务需要检测工作站是否已锁定,屏幕保护程序是否处于活动状态,c#,.net,C#,.net,我正在开发一项服务,该服务需要检测登录到单个计算机的所有用户的用户状态。具体来说,我想检查屏幕保护程序是否处于活动状态,以及他们的会话是否被锁定 此代码将在系统级服务下运行,并且没有可见的UI,因此可能会排除几个选项(捕获WM消息等) 除了普通的工作站之外,我想让它在有多个用户登录的终端服务器上工作。由于这些要求,我想知道是否需要涉及几个Win32 API 关于从哪里开始有什么想法吗?最简单的方法是在每个用户的会话中运行一个小应用程序。此应用程序的每个实例都可以与服务的主实例通信 Windows

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

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

除了普通的工作站之外,我想让它在有多个用户登录的终端服务器上工作。由于这些要求,我想知道是否需要涉及几个Win32 API


关于从哪里开始有什么想法吗?

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


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

一个更简单的解决方案是,它包装了各种TS API,以检查用户空闲了多长时间:

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);
    }
}

作为一项服务,您可以使用event 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链接


谢谢,我试试看。也许一个简单的套接字是最好的方法。GetUserName代码对我不起作用(抛出一个异常)。但是,我在这里找到了实现所需功能的代码: