C# 如何从.NET中的Windows服务获取当前登录的用户名?
我有一个Windows服务,需要当前登录的用户名。我尝试了C# 如何从.NET中的Windows服务获取当前登录的用户名?,c#,visual-studio-2010,windows-services,C#,Visual Studio 2010,Windows Services,我有一个Windows服务,需要当前登录的用户名。我尝试了System.Environment.UserName、Windows标识和Windows窗体身份验证,但都返回了“System”,因为作为我的服务的用户正在系统特权中运行。有没有办法在不更改我的服务帐户类型的情况下获取当前登录的用户名?请尝试WindowsIdentity.GetCurrent()。您需要添加对System.Security.Principal的引用这是一个查询,用于获取用户名: ManagementObjectSear
System.Environment.UserName
、Windows标识和Windows窗体身份验证,但都返回了“System”,因为作为我的服务的用户正在系统特权中运行。有没有办法在不更改我的服务帐户类型的情况下获取当前登录的用户名?请尝试WindowsIdentity.GetCurrent()
。您需要添加对System.Security.Principal
的引用这是一个查询,用于获取用户名:
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem");
ManagementObjectCollection collection = searcher.Get();
string username = (string)collection.Cast<ManagementBaseObject>().First()["UserName"];
ManagementObjectSearcher searcher=newmanagementobjectsearcher(“从Win32\u计算机系统中选择用户名”);
ManagementObjectCollection集合=searcher.Get();
字符串用户名=(字符串)collection.Cast().First()[“username”];
您需要在“参考”下手动添加System.Management
。修改的代码:
你也可以试试
System.Environment.GetEnvironmentVariable("UserName");
ManagementObjectSearcher(“从Win32\U计算机系统中选择用户名”)解决方案对我来说效果很好。但是,如果通过远程桌面连接启动该服务,它将不起作用。
为了解决这个问题,我们可以询问始终在PC上运行的交互式进程的所有者的用户名:explorer.exe。这样,我们始终可以从Windows服务获取当前登录的Windows用户名:
foreach (System.Management.ManagementObject Process in Processes.Get())
{
if (Process["ExecutablePath"] != null &&
System.IO.Path.GetFileName(Process["ExecutablePath"].ToString()).ToLower() == "explorer.exe" )
{
string[] OwnerInfo = new string[2];
Process.InvokeMethod("GetOwner", (object[])OwnerInfo);
Console.WriteLine(string.Format("Windows Logged-in Interactive UserName={0}", OwnerInfo[0]));
break;
}
}
如果您在用户网络中,则用户名将不同:
Environment.UserName
将显示格式:“用户名”,
而不是
System.Security.Principal.WindowsIdentity.GetCurrent().Name
将显示格式:“NetworkName\Username”
选择所需的格式。以防有人正在查找用户显示名称,而不是像我这样的用户名 这是招待: System.DirectoryServices.AccountManagement.UserPrincipal.Current.DisplayName
在项目中添加对
System.DirectoryServices.AccountManagement的引用。从@xanblax完成答案
private static string getUserName()
{
SelectQuery query = new SelectQuery(@"Select * from Win32_Process");
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
{
foreach (System.Management.ManagementObject Process in searcher.Get())
{
if (Process["ExecutablePath"] != null &&
string.Equals(Path.GetFileName(Process["ExecutablePath"].ToString()), "explorer.exe", StringComparison.OrdinalIgnoreCase))
{
string[] OwnerInfo = new string[2];
Process.InvokeMethod("GetOwner", (object[])OwnerInfo);
return OwnerInfo[0];
}
}
}
return "";
}
您是否知道可能有多个登录用户?你都要吗?我认为您还可以通过读取windows注册表(那些具有SID子项的注册表)来获取已登录用户。当然,是所有已登录用户。相关:我认为这将返回服务正在运行的用户,而不是在系统帐户下运行的服务中看到的所有交互用户。这将显示什么?域\用户名还是用户名?@SearchForKnowledge:它只返回用户名-它相当于使用属性“Environment.Username”,这正是我要找的!这完全不能回答问题。当您的应用程序作为服务运行时,这两个调用都将返回服务帐户名。它将返回当前服务用户,而不是用户。人们总是忘记,由于系统帐户的原因,在运行服务时,“获取”用户名的常用方法不起作用+我意识到这个问题真的很老了,但我在谷歌搜索同一个问题时发现了它。虽然这个答案确实是正确的,但请记住,正如@xanblax在他的回答中所说的,这个WMI查询在远程(RDP)会话中不起作用。我只是想指出这一点,并让它更明显,以防将来有人读到这篇文章。旧的答案仍然有用。现在,2018年8月,我偶然发现了这个问题。@Tapas您能建议如何将其用于标准用户吗?在Windows 10 20H2中运行良好,谢谢。我想使用这个答案,但我找不到类进程。如果多个用户同时登录(例如,在Windows 10中,当您切换到另一个用户时),这将不起作用因为每个用户都在运行explorer.exe的一个实例。它应该如下所示:ManagementObjectSearcher进程=新建ManagementObjectSearcher(“根\\CIMV2”,“从Win32_进程中选择*);尝试此操作时,出现错误“无法将类型为'System.DirectoryServices.AccountManagement.GroupPrincipal'的对象强制转换为类型为'System.DirectoryServices.AccountManagement.UserPrincipal'
private static string getUserName()
{
SelectQuery query = new SelectQuery(@"Select * from Win32_Process");
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
{
foreach (System.Management.ManagementObject Process in searcher.Get())
{
if (Process["ExecutablePath"] != null &&
string.Equals(Path.GetFileName(Process["ExecutablePath"].ToString()), "explorer.exe", StringComparison.OrdinalIgnoreCase))
{
string[] OwnerInfo = new string[2];
Process.InvokeMethod("GetOwner", (object[])OwnerInfo);
return OwnerInfo[0];
}
}
}
return "";
}