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

我写了一个Windows服务,将WCF服务公开给安装在同一台机器上的GUI。 当我运行GUI时,如果我无法连接到服务,我需要知道是否因为服务应用程序尚未安装,或者是因为服务未运行。 如果前者,我会想要安装它(如这里所述); 如果后者,我会想要启动它。

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

使用:

// 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()) 

如果您的应用程序正在运行的帐户没有权限查看服务属性,则可能会抛出拒绝访问exception。 另一方面,即使不存在具有这种名称的服务,也可以安全地执行此操作:

 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(); } 
  private bool ServiceExists(string serviceName) { ServiceController[] services = ServiceController.GetServices(); var service = services.FirstOrDefault(s => string.Equals(s.ServiceName, serviceName, StringComparison.OrdinalIgnoreCase)); return service != null; } 

我认为这是这个问题的最好答案。 没有必要添加额外的处理来validation服务是否存在,因为如果服务不存在,它将抛出exception。 你只需要抓住它。 如果使用()包装整个方法,则也不需要closures()连接。

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