如何检查 Windows 服务是否安装在 C # 中

我编写了一个 Windows 服务,它将 WCF 服务公开给安装在同一台计算机上的 GUI。当我运行 GUI 时,如果我不能连接到服务,我需要知道是因为服务应用程序还没有安装,还是因为服务没有运行。如果是前者,我希望安装它(如 给你所述) ; 如果是后者,我希望启动它。

问题是: 如何检测服务是否已安装,然后在检测到服务已安装后,如何启动它?

55853 次浏览

用途:

// add a reference to System.ServiceProcess.dll
using System.ServiceProcess;


// ...
ServiceController ctl = ServiceController.GetServices()
.FirstOrDefault(s => s.ServiceName == "myservice");
if(ctl==null)
Console.WriteLine("Not installed");
else
Console.WriteLine(ctl.Status);

你也可以用下面的方法。

using System.ServiceProcess;
...
var serviceExists = ServiceController.GetServices().Any(s => s.ServiceName == serviceName);

对于非 linq,您可以像下面这样迭代数组:

using System.ServiceProcess;


bool serviceExists = false
foreach (ServiceController sc in ServiceController.GetServices())
{
if (sc.ServiceName == "myServiceName")
{
//service is found
serviceExists = true;
break;
}
}

实际上是这样循环的:

foreach (ServiceController SC in ServiceController.GetServices())

如果运行应用程序的帐户没有查看服务属性的权限,则可能引发访问拒绝异常。另一方面,即使不存在具有此名称的服务,您也可以安全地这样做:

ServiceController SC = new ServiceController("AnyServiceName");

但是如果服务不存在,访问它的属性将导致 InvalidOperationException。因此,这里有一个安全的方法来检查服务是否已经安装:

ServiceController SC = new ServiceController("MyServiceName");
bool ServiceIsInstalled = false;
try
{
// actually we need to try access ANY of service properties
// at least once to trigger an exception
// not neccessarily its name
string ServiceName = SC.DisplayName;
ServiceIsInstalled = true;
}
catch (InvalidOperationException) { }
finally
{
SC.Close();
}

我认为这是这个问题的最佳答案。不需要添加额外的处理来验证服务是否存在,因为如果不存在,它将引发异常。你只需要抓住它。如果使用()包装整个方法,也不需要关闭()连接。

using (ServiceController sc = new ServiceController(ServiceName))
{
try
{
if (sc.Status != ServiceControllerStatus.Running)
{
sc.Start();
sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 10));
//service is now Started
}
else
//Service was already started
}
catch (System.ServiceProcess.TimeoutException)
{
//Service was stopped but could not restart (10 second timeout)
}
catch (InvalidOperationException)
{
//This Service does not exist
}
}
 private bool ServiceExists(string serviceName)
{
ServiceController[] services = ServiceController.GetServices();
var service = services.FirstOrDefault(s => string.Equals(s.ServiceName, serviceName, StringComparison.OrdinalIgnoreCase));
return service != null;
}