views:

65

answers:

3

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?

A: 

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.

Dewfy
Then you can get the Name property of the WindowsIdentity object returned from the above command.
ewall
-1 This returns the `WindowsIdentity` of the current user, not of a specified service.
Pwninstein
@Pwninstein as usual service is started from SYSTEM or NETWORK credentials - not from "logged in" users. See my edits about this. So clarify you want get system account that starts service (my answer is correct about this) or current logged-in user list, that could use this service?
Dewfy
*Usually* services run as Local System or Network Service, but you can install a service to run under a standard user account (which we do in the project I'm working on).
Pwninstein
@Pwninstein - in this case you will get correct from GetCurrent()
Dewfy
I'm not sure you understand what I'm trying to do: I would like to get the username a particular service is running under. I would like to do this from a completely separate client application (i.e. all of the code to retrieve the username is in the client). Your suggestion to user `GetCurrent()` will not work because, according to MSDN, it "Returns a WindowsIdentity object that represents the current Windows user." In this case it will be the WindowsIdentity of the current Windows user running the CLIENT application, not the WindowsIdentity of the SERVICE.
Pwninstein
+1  A: 

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.

ho1
Thanks! 15chars
Pwninstein
+2  A: 

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.

Riaan
Haven't tried it yet, but this looks like a winner! Thanks!
Pwninstein