Как проверить, установлена ли служба windows В C#


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

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

6 68

6 ответов:

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

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

на самом деле цикл, как это:

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

для non-linq, вы можете просто перебирать массив следующим образом:

using System.ServiceProcess;

bool serviceExists = false
foreach (ServiceController sc in ServiceController.GetServices())
{
    if (sc.ServiceName == "myServiceName")
    {
         //service is found
         serviceExists = true;
         break;
    }
}
 private bool ServiceExists(string serviceName)
    {
        ServiceController[] services = ServiceController.GetServices();
        var service = services.FirstOrDefault(s => string.Equals(s.ServiceName, serviceName, StringComparison.OrdinalIgnoreCase));
        return service != null;
    }

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

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