Search code examples
c#.netwindowsservicewindows-server-2012

Cannot open Service Control Manager on computer


I am trying to write a program that will connect to a remote server and display some status of a service. The service is also written by us (my company).

To do that I wrote a console app and the code is

static void Main(string[] args)
    {
        ConnectionOptions options = new ConnectionOptions();
        options.Password = "mypassword";
        options.Username = "Administrator";
        options.Impersonation =
            System.Management.ImpersonationLevel.Impersonate;

        ManagementScope scope =
            new ManagementScope(
            "\\\\ip_of_the_server\\root\\cimv2", options);
        scope.Connect();

        ServiceController svc = new ServiceController("My_Service_Name", "ip_of_the_server");

        var status = svc.Status.ToString();
        Console.WriteLine(svc.DisplayName + " : " status);

    }

But I can not make it work. The error i get is:

Cannot open Service Control Manager on computer 'ip_of_the_server'. This operation might require other privileges.

inner exception: "Access Denied".

stack trace:

   at System.ServiceProcess.ServiceController.GetDataBaseHandleWithAccess(String     machineName, Int32 serviceControlManaqerAccess)
   at System.ServiceProcess.ServiceController.GetDataBaseHandleWithConnectAccess()
   at System.ServiceProcess.ServiceController.GenerateNames()
   at System.ServiceProcess.ServiceController.get_ServiceName()
   at System.ServiceProcess.ServiceController.GenerateStatus()
   at System.ServiceProcess.ServiceController.get_Status()
   at ServiceConsole.Program.Main(String[] args) in c:\Users\Kandroid\Documents\Visual Studio     2013\Projects\ServiceConsole\ServiceConsole\Program.cs:line 33
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity,   String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

Any idea how to solve it??


Solution

  • As you already did setup an managementscope, just use WQL to query the WMI provider for the correct WMI Object, in this case WIN32_Service, something like this:

    var svc = new ManagementObjectSearcher(
        scope,
        new ObjectQuery("Select Status,State from Win32_Service  where Name='My_Service_Name'"))
            .Get()
            .GetEnumerator();
    
        if (svc.MoveNext())
        {
              var status = svc.Current["Status"].ToString();
              var state = svc.Current["State"].ToString();
              Console.WriteLine("service status {0}", status);
              // if not running, StartService
              if (!String.Equals(state, "running",StringComparison.InvariantCultureIgnoreCase) {
                   ( (ManagementObject) svc.Current ).InvokeMethod("StartService", new object[] {});
              }
        }
        else 
        {
               Console.WriteLine("service not found");
        }
    

    The ManagementObjectSearcher is responsible for retrieving a collection of WMI managedobjects. An ObjectQuery will return instances of classes from the scope. We can execute basic sql select statements to select and project resultsets.

    The iterator returns an ManagementObjectBase that has as Item accessor to retrieve properties from the returned instance.