Как проверить, установлена ​​ли служба Windows в C # - PullRequest
74 голосов
/ 29 декабря 2010

Я написал службу Windows, которая предоставляет службу WCF графическому интерфейсу, установленному на том же компьютере.Когда я запускаю графический интерфейс, если я не могу подключиться к службе, мне нужно знать, связано ли это с тем, что приложение-служба еще не установлено, или потому, что служба не запущена.Если первое, я хочу установить его (как описано здесь );если последнее, я хочу запустить его.

Вопрос: как вы определяете, установлена ​​ли служба, а затем, обнаружив, что она установлена, как вы запускаете ее?

Ответы [ 6 ]

137 голосов
/ 29 декабря 2010

Использование:

// 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);
35 голосов
/ 25 февраля 2013

Вы также можете использовать следующее ..

using System.ServiceProcess; 
... 
var serviceExists = ServiceController.GetServices().Any(s => s.ServiceName == serviceName);
6 голосов
/ 12 декабря 2013

На самом деле цикл выглядит так:

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();
}
2 голосов
/ 03 сентября 2013

Для не linq, вы можете просто перебрать массив так:

using System.ServiceProcess;

bool serviceExists = false
foreach (ServiceController sc in ServiceController.GetServices())
{
    if (sc.ServiceName == "myServiceName")
    {
         //service is found
         serviceExists = true;
         break;
    }
}
1 голос
/ 27 апреля 2016
 private bool ServiceExists(string serviceName)
    {
        ServiceController[] services = ServiceController.GetServices();
        var service = services.FirstOrDefault(s => string.Equals(s.ServiceName, serviceName, StringComparison.OrdinalIgnoreCase));
        return service != null;
    }
0 голосов
/ 12 июня 2014

Я думаю, что это лучший ответ на этот вопрос.Нет необходимости добавлять дополнительную обработку, чтобы проверить, существует ли служба, так как в противном случае она выдаст исключение.Вам просто нужно поймать это.Вам также не нужно закрывать () соединение, если вы используете весь метод с использованием ().

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