0

就我而言,我有一个 WPF 应用程序,它负责用户交互,并且有一个支持 Windows 服务在后面运行。

我必须仅以普通用户权限(非管理员)执行 WPF 应用程序。由于应用程序必须启动和停止 Windows 服务,所以我得到了“访问级别”异常。

我尝试使用ServiceController类来停止服务,

 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;
    }

如果 WPF 应用程序以管理员身份打开,则这部分代码将正确执行。

在同一个解决方案中有一个单独的类库项目,负责访问Windows服务,我尝试添加app.Manifest文件并将角色更改为<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

由于它是一个图书馆项目,因此我没有看到拥有它的任何影响。

另外,我尝试过使用Process

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

        };

        Process.Start(info);

但这只是为了开始这个过程,它可能对我没有用。

或者,我选择编写一个控制台应用程序来操作 Windows 服务状态,在清单中,我将requestedExecutionLevel级别设置为requireAdministrator并将其包含在解决方案中并调用它。(每次执行代码时都会获得 UAC)我不认为这是最好的做法。

有没有更好的方法来以普通用户权限以编程方式停止和启动 Windows 服务。

4

1 回答 1

0

不确定这是否适用于非管理员。

            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);
                    }

            }
于 2019-03-10T09:53:07.457 回答