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?
-
15Are you aware that there may be more than one logged on user? Do you want them all? – David Heffernan Mar 07 '11 at 10:55
-
http://stackoverflow.com/questions/4442488/c-net-getting-user-name-of-machine-using-windows-service and http://stackoverflow.com/questions/2727393/get-user-sid-from-logon-id-windows-xp-and-up I think you can also get the logged users by reading the windows registry (those with SID subkey). – Jaroslav Jandek Mar 07 '11 at 11:01
-
ya of course, all logged user. – Raj Mar 07 '11 at 11:02
-
Related: *[How do I get the current username in .NET using C#?](http://stackoverflow.com/questions/1240373)* – Peter Mortensen May 24 '16 at 12:47
8 Answers
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.

- 9,328
- 7
- 39
- 60

- 974
- 7
- 3
-
16People keep forgetting that the usual ways to "get" a username wont work when running a service because of the System Accounts... +1 for being the only answer to take this into account – amartin94 Oct 18 '15 at 18:50
-
14I realize this question is really old, but I found it while Googling the same issue. While this answer is indeed correct, keep in mind, as @xanblax said in his answer, this WMI query will not work in a remote (RDP) session. Just wanted to point that out, and make it more visible, in case anyone else reads this in the future. – CaptainStealthy Oct 12 '16 at 23:07
-
1Old answers are still useful. I stumbled across this _now_, August 2018. – Per Lundberg Aug 03 '18 at 18:32
-
-
Works fine in my service application running under a system account in Windows 10 20H2. Thanks! – Nate Apr 15 '21 at 07:37
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.

- 6,634
- 4
- 38
- 90

- 8,656
- 2
- 30
- 26
-
1
-
40That totally doesn't answer the question. When your application is running as a service, both of those calls will return the service account name. – Aaron C. de Bruyn Sep 19 '15 at 21:03
-
4
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;
}
}

- 276
- 2
- 5
-
4I wanted to use this answer, but I couldn't find the class Processes. – Matt Becker Jan 25 '17 at 16:15
-
This doesn't work if multiple users are logged in at once (e.g. in Windows 10 when you switch to another user) as one instance of explorer.exe is running for each user. – Vitani Jun 18 '19 at 13:48
-
It should be the following: ManagementObjectSearcher Processes = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Process"); – ilCosmico Feb 07 '20 at 10:08
-
to make sure I was getting the correct copy of explorer.exe, I got the current process and took the session ID from that, then I compared that to the SessionID property value from the explorer.exe I found and then got the user information from that one. – David Parvin Apr 25 '23 at 22:45
-
Of course a Windows Service might be in a session without a UI or without explorer.exe running in it's session, so you might have to doing some other way, but I am using this in a windows desktop application and it is working great. – David Parvin Apr 25 '23 at 22:52
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

- 1
- 1

- 119
- 1
- 8
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.

- 1,706
- 4
- 22
- 35
-
2When I try this, I get the error "Unable to cast object of type 'System.DirectoryServices.AccountManagement.GroupPrincipal' to type 'System.DirectoryServices.AccountManagement.UserPrincipal'." – atjoedonahue May 02 '19 at 15:30
You can also try
System.Environment.GetEnvironmentVariable("UserName");
-
1
-
@SearchForKnowledge: It just returns Username - It is equivalent of using the property 'Environment.UserName' – B Bhatnagar Feb 09 '18 at 10:47
Try WindowsIdentity.GetCurrent()
. You need to add reference to System.Security.Principal

- 193
- 2
- 7
-
13I think this will return the user that the service is running as, not all interactive users as seen from the service running under a system account. – Hans Kesting Mar 07 '11 at 11:40
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 "";
}

- 5,062
- 2
- 24
- 42

- 1