Как проверить, установлена ​​ли служба Windows на С#

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

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

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

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

using System.ServiceProcess;

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

Ответ 4

На самом деле цикл:

foreach (ServiceController SC in ServiceController.GetServices())

может вызывать исключение Access Denied, если учетная запись, под которой работает ваше приложение, не имеет прав на просмотр свойств службы. С другой стороны, вы можете безопасно это сделать, даже если службы с таким именем не существуют:

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

Ответ 5

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

Ответ 6

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

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