0

In My case, I have a WPF app which is responsible for user interactions to and there is a supporting windows service running behind.

I must execute the WPF app only in normal user privilege (non-administrator). Since the application has to start and stop the windows services then and there, I got 'ACCESS LEVEL' exceptions.

I tried using ServiceController class to stop the service,

 public bool StopLibraryService()
    {
        try
        {
            var service = new ServiceController(ServiceName);
            if (service.Status == ServiceControllerStatus.Running)
            {
                service.Stop();
                var timeout = new TimeSpan(0, 0, 5);                     service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);

                if (service.Status != ServiceControllerStatus.Stopped)
                    throw new Exception($"Failed in stopping service {ServiceName}");
            }
        }
        catch (InvalidOperationException exAccess)
        {
            throw;
        }
        catch (Exception exception)
        {

        }
        return true;
    }

If the WPF application is open as administrator, this portion of code executes correctly.

There is a separate class library project in the same solution, which is responsible for accessing the Windows service, I tried to add app.Manifest file and change the role to <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

Since its a library project, I haven't seen any impact of having it.

Also, I have tried using Process,

        var info = new ProcessStartInfo(path)
        {
            CreateNoWindow = true,
            UseShellExecute = false,
            Arguments = command,
            WindowStyle = ProcessWindowStyle.Hidden,
            Verb = "runas"

        };

        Process.Start(info);

but it's just for starting the process, it may not be useful to me.

Alternately I have opted to write a console application to manipulate windows service state, and in the manifest, I set the requestedExecutionLevel level as requireAdministrator and included it in the solution and call it. (am getting UAC every time whenever the code executes) I don't believe it's the best practice to follow.

Is there any better way to stop and start the windows service programmatically with a normal user privilege.

jidh
  • 172
  • 1
  • 6
  • 22

1 Answers1

0

Not sure if this works for non-administrator.

            ConnectionOptions options = new ConnectionOptions();

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

            ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Service");
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);

            ManagementObjectCollection queryCollection = searcher.Get();

            foreach (ManagementObject m in queryCollection)
            {

                    if (m["Started"].Equals(true))
                    {
                        m.InvokeMethod("StopService", null);
                    }

            }