如何知道Windows服务是否有活动的交互式会话?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何知道Windows服务是否有活动的交互式会话?相关的知识,希望对你有一定的参考价值。

我正在编写Windows服务,有一点我需要知道是否存在活动的交互式会话。

我尝试使用OnSessionChange()并在变量中保留最后一个SessionChangeReason。当我达到上述要点时,我会比较它是否等于SessionChangeReason.SessionLogOn。这有助于服务延迟启动的不便,因此如果用户在服务开始运行之前登录,则此信息将丢失。

我也看过System.Environment.Interactive属性,但据我所知,这是指当前服务的进程,它不是交互式的,所以它不会给我我需要的信息(我可能会误解这一点)。

有没有办法在不需要注册SessionChangeReason的情况下“按需”获取此信息?

编辑:也许我不清楚这一点。除了知道存在交互式会话之外,我还需要知道它没有被锁定。

答案

P /调用WTSEnumerateSessions以查看是否有其他会话以及它们的连接状态。您显然必须忽略Vista +上的会话0。

您应该只在启动服务时执行此操作,应使用会话更改通知来检测进一步的更改。

另一答案

最后,我已经辞职,明确知道有一个会话而且没有锁定,因此我们将处理是否存在活动会话。

如果只知道有一个活动会话适合您并且您不想使用pInvoke,您可以:

a)搜索资源管理器进程

Process[] ps = Process.GetProcessesByName("explorer");
bool explorerActive = (ps.Length > 0);

b)使用以下WMI查询获取活动会话的UserName:

using System.Management;

ConnectionOptions oConn = new ConnectionOptions();
ManagementScope oMs = new ManagementScope("\\\\localhost", oConn);

ObjectQuery oQuery = new ObjectQuery("select * from Win32_ComputerSystem");
ManagementObjectSearcher oSearcher = new ManagementObjectSearcher(oMs, oQuery);
ManagementObjectCollection oReturnCollection = oSearcher.Get();


foreach (ManagementObject oReturn in oReturnCollection)
{
    if (oReturn["UserName"] == null)
    {
        // No active session
        Console.Write("UserName: null");
    }
    else
    {
        // Active session
        Console.Write("UserName: " + oReturn["UserName"].ToString());
    }                            
}

如果你想使用pInvoke,请参阅Anders的回答。

以上是关于如何知道Windows服务是否有活动的交互式会话?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Windows 上获取 Active Desktop 类型?

创建交互式登录会话 windows 7

是否可以使用 php 查看活动会话?

排查oracle会话非活动状态的语句

如何使用Windows服务弹出应用程序c#

mysql会话超时时间设置