如何从.NET中的Windows服务获取当前登录的用户名?

Raj*_*ahu 59 c# windows-services visual-studio-2010

我有一个需要当前登录用户名的Windows服务.我试过System.Environment.UserName,Windows身份和Windows窗体身份验证,但所有都返回" 系统 "作为用户,因为我的服务在系统特权运行.有没有办法在不更改我的服务帐户类型的情况下获取当前登录的用户名?

小智 79

这是一个获取用户名的WMI查询:

ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem");
ManagementObjectCollection collection = searcher.Get();
string username = (string)collection.Cast<ManagementBaseObject>().First()["UserName"];
Run Code Online (Sandbox Code Playgroud)

您需要System.Management手动添加引用.

  • 人们一直忘记在运行服务时"获取"用户名的常用方法因为系统帐户而无法运行... +1是唯一能够将此考虑在内的答案 (14认同)
  • 我意识到这个问题真的很老了,但我在谷歌搜索同样的问题时发现了这个问题.虽然这个答案确实是正确的,但请记住,正如@xanblax在他的回答中所说,这个WMI查询在远程(RDP)会话中不起作用.只是想指出这一点,并使其更加明显,以防其他人在将来阅读此内容. (9认同)

Isr*_*ies 34

如果您在用户网络中,则用户名将不同:

Environment.UserName
Run Code Online (Sandbox Code Playgroud)

将显示格式:'用户名',而不是

System.Security.Principal.WindowsIdentity.GetCurrent().Name
Run Code Online (Sandbox Code Playgroud)

将显示格式:'NetworkName\Username'

选择所需的格式.

  • 这完全没有回答这个问题.当您的应用程序作为服务运行时,这两个调用都将返回服务帐户名称. (29认同)
  • 它将返回当前服务用户,而不是用户 (3认同)

xan*_*lax 19

ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem")解决方案对我来说很好.但是,如果通过远程桌面连接启动服务,则它不起作用.要解决此问题,我们可以要求始终在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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 很聪明:) (5认同)
  • 我想使用这个答案,但我找不到类进程. (3认同)

小智 6

塔帕斯答案的修改代码:

Dim searcher As New ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem")
Dim collection As ManagementObjectCollection = searcher.[Get]()
Dim username As String
For Each oReturn As ManagementObject In collection
    username = oReturn("UserName")
Next
Run Code Online (Sandbox Code Playgroud)