Raj
Raj

Reputation: 4010

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

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?

Upvotes: 70

Views: 159075

Answers (8)

EAquino
EAquino

Reputation: 1

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

Upvotes: 0

B Bhatnagar
B Bhatnagar

Reputation: 1806

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.

Upvotes: 2

Israel Margulies
Israel Margulies

Reputation: 8952

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.

Upvotes: 33

Adith
Adith

Reputation: 177

You can also try

System.Environment.GetEnvironmentVariable("UserName");

Upvotes: 1

Tapas
Tapas

Reputation: 984

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.

Upvotes: 96

Vishal Bedre
Vishal Bedre

Reputation: 119

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

Upvotes: 6

xanblax
xanblax

Reputation: 286

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

Upvotes: 22

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

Upvotes: 1

Related Questions