确定用户是否登录到VM

时间:2014-07-21 11:29:06

标签: c# .net service virtual-machine

我目前正在编写一个C#服务,基本上确保一组exes正在运行,如果他们没有重新启动它们。

该服务自动启动,因此我遇到了在没有人登录时尝试启动exe的问题。我有一个适用于非VM系统的解决方案,如下所示:

ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem");
ManagementObjectCollection collection = searcher.Get();
string loggedIn = (string)collection.Cast<ManagementBaseObject>().First()["UserName"];

然后我针对null或空格进行检查,然后如果没有用户登录则不检查进程列表。

但是,在VM上运行时,当用户登录时,此部分代码将返回null。因此,我需要一种在标准计算机和VM上检查登录用户的方法。我还需要它适用于XP和Windows 7,以及32位和64位。我正在使用.Net 4。

1 个答案:

答案 0 :(得分:2)

列出会话的官方文档规定使用LsaLogOnSessions枚举它们,有关更多示例,请参阅MSDN或此CodeProject article

如果您只是需要确定至少有一个登录用户,那么您只需检查默认的shell进程即可。将始终为每个会话加载默认shell:

bool loggedInUserExist = Process.GetProcessesByName("explorer").Any();

在此示例中,我是硬编码值,但必须Shell中的字符串值HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\读取它,以防默认shell被覆盖(或者用于服务器核心)当GUI不存在时安装。)

如果您不需要任何其他内容,那么您就完成了。如果您必须过滤特定用户,那么您必须获得进程'所有者。在C#中并不容易,除非您使用WMI查询Win32_Process,在explorer属性中搜索Name,然后调用GetOwner()的{​​{1}}方法(请参阅this post来自SO)。请注意,您可以使用相同的查询来确定是否有任何登录用户以及他是谁。作为替代方案,您可以按照this post中的描述进行P / Invoke for Windows API函数(但在这种情况下,我将返回ManagementObject)。