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