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

时间:2019-04-25 12:21:54

标签: c# windows service windows-services

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

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

我也看到了System.Environment.Interactive属性,但是据我所知,它是指当前服务的过程,该过程不是交互式的,因此不会给我所需的信息(尽管我可能会误解了)。

是否有一种方法可以“按需”获取此信息,而不必保留SessionChangeReason的注册?

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

2 个答案:

答案 0 :(得分:0)

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

仅应在服务启动时执行此操作,会话更改通知应用于检测进一步的更改。

答案 1 :(得分:0)

最后我已辞职,明确知道有一个会话并且没有被锁定,因此我们将研究是否有活动的会话。

如果仅知道有一个活动会话对您有效,并且您不想使用pInvoke,则可以:

a)搜索浏览器进程

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

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

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的答案。