我正在编码Windows服务,有一点我需要知道是否有活动的交互式会话。
我尝试使用OnSessionChange()并将最后一个SessionChangeReason保留在变量中。当我达到上述要点时,我将比较它是否等于SessionChangeReason.SessionLogOn。这样做的不便之处在于该服务的启动延迟,因此如果用户在该服务开始运行之前登录,该信息就会丢失。
我也看到了System.Environment.Interactive属性,但是据我所知,它是指当前服务的过程,该过程不是交互式的,因此不会给我所需的信息(尽管我可能会误解了)。
是否有一种方法可以“按需”获取此信息,而不必保留SessionChangeReason的注册?
编辑:也许我不清楚这一点。除了知道有一个交互式会话外,我还需要知道它没有被锁定。
答案 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的答案。