就我而言,我有一个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服务。
答案 0 :(得分: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);
}
}