Mark Carpenter
Mark Carpenter

Reputation: 17775

How do I retrieve the username that a Windows service is running under?

Given a service name, I would like to retrieve the username that it runs under (i.e. the username shown in the 'Log On' tab of a service's properties window).

There doesn't appear to be anything in the ServiceController class to retrieve this basic information. Nothing else in System.ServiceProcess looks like it exposes this information either.

Is there a managed solution to this, or am I going to have to drop down into something lower-level?

Upvotes: 21

Views: 26896

Answers (6)

Cocowalla
Cocowalla

Reputation: 14350

You can find this using the Windows Registry, reading the following string value, replacing [SERVICE_NAME] with the name of the Windows Service:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\[SERVICE_NAME]\ObjectName

Upvotes: 4

Abhishek Chauhan
Abhishek Chauhan

Reputation: 1

    public String getUsername() {
    string username = null;
    try {
      ManagementScope ms = new ManagementScope("\\\\.\\root\\cimv2");
      ms.Connect();
      ObjectQuery query = new ObjectQuery
              ("SELECT * FROM Win32_ComputerSystem");
      ManagementObjectSearcher searcher =
              new ManagementObjectSearcher(ms, query);
      foreach (ManagementObject mo in searcher.Get()) {
        username = mo["UserName"].ToString();
      }
      string[] usernameParts = username.Split('\\');
      username = usernameParts[usernameParts.Length - 1];
    } catch (Exception) {
      username = "SYSTEM";
    }
    return username;
  }

Upvotes: 0

Ben
Ben

Reputation: 21

This solution works fine for me:

    ManagementObject wmiService = new ManagementObject("Win32_Service.Name='" + this.ServiceName + "'");
    wmiService.Get();
    string user = wmiService["startname"].ToString();

Upvotes: 2

Riaan
Riaan

Reputation: 1591

Using WMI, with the System.Management you can try the following code:

using System;
namespace WindowsServiceTest
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Management.SelectQuery sQuery = new System.Management.SelectQuery(string.Format("select name, startname from Win32_Service")); // where name = '{0}'", "MCShield.exe"));
            using (System.Management.ManagementObjectSearcher mgmtSearcher  = new System.Management.ManagementObjectSearcher(sQuery))
            {
                foreach (System.Management.ManagementObject service in mgmtSearcher.Get())
                {
                    string servicelogondetails =
                        string.Format("Name: {0} ,  Logon : {1} ", service["Name"].ToString(), service["startname"]).ToString();
                    Console.WriteLine(servicelogondetails);
                }
            }
            Console.ReadLine();
        }
    }
}

You can then later substitute the commented code with your service name, and it should only return the instances of your service process that is running.

Upvotes: 26

Hans Olsson
Hans Olsson

Reputation: 55059

WMI is your friend. Look at Win32_Service, specifically the StartName property. You can access WMI from C# via the System.Management.ManagementClass.

If you've not used WMI before, this article seems to be quite a good tutorial.

Upvotes: 7

Dewfy
Dewfy

Reputation: 23644

Try this:

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

but the most obvious you will get LOCAL SYSTEM or NETWORK. The reason that you cannot show this user - that service can manage multiple users (shared by desktop, attached to current windows session, using shared resource ...) System starts service, but any user can use it.

Upvotes: 1

Related Questions