开发者

How do I get the currently-logged username from a Windows service in .NET?

开发者 https://www.devze.com 2023-02-15 10:53 出处:网络
I have a Windows service which needs the currently logged username. I tried System.Environment.开发者_运维技巧UserName, Windows identity and Windows form authentication, but all are returning "Sy

I have a Windows service which needs the currently logged username. I tried System.Environment.开发者_运维技巧UserName, Windows identity and Windows form authentication, but all are returning "System" as the user my service is running as has system privileges. Is there a way to get the currently logged in username without changing my service account type?


This is a WMI query to get the user name:

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

You will need to add System.Management under References manually.


If you are in a network of users, then the username will be different:

Environment.UserName

Will Display format : 'Username', rather than

System.Security.Principal.WindowsIdentity.GetCurrent().Name

Will Display format : 'NetworkName\Username'

Choose the format you want.


ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem") solution worked fine for me. BUT it does not work if the service is started over a Remote Desktop Connection. To work around this, we can ask for the username of the owner of an interactive process that always is running on a PC: explorer.exe. This way, we always get the currently Windows logged-in username from our Windows service:

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;
    }
}


Modified code of Tapas's answer:

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


Just in case someone is looking for user Display Name as opposed to User Name, like me.

Here's the treat :

System.DirectoryServices.AccountManagement.UserPrincipal.Current.DisplayName.

Add Reference to System.DirectoryServices.AccountManagement in your project.


Try WindowsIdentity.GetCurrent(). You need to add reference to System.Security.Principal


You can also try

System.Environment.GetEnvironmentVariable("UserName");


Completing the answer from @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 "";
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号