Как я могу перезапустить службу Windows программно в .NET - PullRequest
60 голосов
/ 21 сентября 2009

Как я могу перезапустить службу Windows программно в .NET?
Кроме того, мне нужно сделать операцию, когда перезапуск службы завершен.

Ответы [ 8 ]

69 голосов
/ 21 сентября 2009

В этой статье используется класс ServiceController для написания методов для запуска, остановки и перезапуска служб Windows; возможно, стоит взглянуть.

Фрагмент статьи (метод «Служба перезапуска»):

public static void RestartService(string serviceName, int timeoutMilliseconds)
{
  ServiceController service = new ServiceController(serviceName);
  try
  {
    int millisec1 = Environment.TickCount;
    TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);

    service.Stop();
    service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);

    // count the rest of the timeout
    int millisec2 = Environment.TickCount;
    timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds - (millisec2-millisec1));

    service.Start();
    service.WaitForStatus(ServiceControllerStatus.Running, timeout);
  }
  catch
  {
    // ...
  }
}
36 голосов
/ 21 сентября 2009

Взгляните на класс ServiceController .

Чтобы выполнить операцию, которая должна быть выполнена при перезапуске службы, я полагаю, вы должны сделать это в Службе самостоятельно (если это ваша собственная служба).
Если у вас нет доступа к источнику службы, возможно, вы можете использовать WaitForStatus метод ServiceController.

22 голосов
/ 03 октября 2013

Пример использования классом ServiceController

private void RestartWindowsService(string serviceName)
{
    ServiceController serviceController = new ServiceController(serviceName);
    try
    {
        if ((serviceController.Status.Equals(ServiceControllerStatus.Running)) || (serviceController.Status.Equals(ServiceControllerStatus.StartPending)))
        {
            serviceController.Stop();
        }
        serviceController.WaitForStatus(ServiceControllerStatus.Stopped);
        serviceController.Start();
        serviceController.WaitForStatus(ServiceControllerStatus.Running);
    }
    catch
    {
        ShowMsg(AppTexts.Information, AppTexts.SystematicError, MessageBox.Icon.WARNING);
    }
}
15 голосов
/ 21 сентября 2009

Вы также можете вызвать команду net, чтобы сделать это. Пример:

System.Diagnostics.Process.Start("net", "stop IISAdmin");
System.Diagnostics.Process.Start("net", "start IISAdmin");
7 голосов
/ 20 мая 2017

Этот ответ основан на ответе @Donut (наиболее часто задаваемый ответ на этот вопрос), но с некоторыми изменениями.

  1. Удаление класса ServiceController после каждого использования, поскольку он реализует интерфейс IDisposable.
  2. Уменьшите параметры метода: нет необходимости передавать параметр serviceName для каждого метода, мы можем установить его в конструкторе, и каждый другой метод будет использовать это имя службы.
    Это также более дружественно к ООП.
  3. Обработайте исключение catch таким образом, чтобы этот класс мог использоваться в качестве компонента.
  4. Удалите параметр timeoutMilliseconds из каждого метода.
  5. Добавьте два новых метода StartOrRestart и StopServiceIfRunning, которые можно рассматривать как оболочку для других базовых методов. Цель этих методов - избежать исключений, как описано в комментарии.

Вот класс

public class WindowsServiceController
{
    private string serviceName;

    public WindowsServiceController(string serviceName)
    {
        this.serviceName = serviceName;
    }

    // this method will throw an exception if the service is NOT in Running status.
    public void RestartService()
    {
        using (ServiceController service = new ServiceController(serviceName))
        {
            try
            {
                service.Stop();
                service.WaitForStatus(ServiceControllerStatus.Stopped);

                service.Start();
                service.WaitForStatus(ServiceControllerStatus.Running);
            }
            catch (Exception ex)
            {
                throw new Exception($"Can not restart the Windows Service {serviceName}", ex);
            }
        }
    }

    // this method will throw an exception if the service is NOT in Running status.
    public void StopService()
    {
        using (ServiceController service = new ServiceController(serviceName))
        {
            try
            {
                service.Stop();
                service.WaitForStatus(ServiceControllerStatus.Stopped);
            }
            catch (Exception ex)
            {
                throw new Exception($"Can not Stop the Windows Service [{serviceName}]", ex);
            }
        }
    }

    // this method will throw an exception if the service is NOT in Stopped status.
    public void StartService()
    {
        using (ServiceController service = new ServiceController(serviceName))
        {
            try
            {
                service.Start();
                service.WaitForStatus(ServiceControllerStatus.Running);
            }
            catch (Exception ex)
            {
                throw new Exception($"Can not Start the Windows Service [{serviceName}]", ex);
            }
        }
    }

    // if service running then restart the service if the service is stopped then start it.
    // this method will not throw an exception.
    public void StartOrRestart()
    {
        if (IsRunningStatus)
            RestartService();
        else if (IsStoppedStatus)
            StartService();
    }

    // stop the service if it is running. if it is already stopped then do nothing.
    // this method will not throw an exception if the service is in Stopped status.
    public void StopServiceIfRunning()
    {
        using (ServiceController service = new ServiceController(serviceName))
        {
            try
            {
                if (!IsRunningStatus)
                    return;

                service.Stop();
                service.WaitForStatus(ServiceControllerStatus.Stopped);
            }
            catch (Exception ex)
            {
                throw new Exception($"Can not Stop the Windows Service [{serviceName}]", ex);
            }
        }
    }

    public bool IsRunningStatus => Status == ServiceControllerStatus.Running;

    public bool IsStoppedStatus => Status == ServiceControllerStatus.Stopped;

    public ServiceControllerStatus Status
    {
        get
        {
            using (ServiceController service = new ServiceController(serviceName))
            {
                return service.Status;
            }
        }
    }
}
6 голосов
/ 21 сентября 2009

Как насчет

var theController = new System.ServiceProcess.ServiceController("IISAdmin");

theController.Stop();
theController.Start();

Не забудьте добавить System.ServiceProcess.dll в ваш проект, чтобы это работало.

2 голосов
/ 21 сентября 2009

См. статью .

Вот фрагмент из статьи .

//[QUICK CODE] FOR THE IMPATIENT
using System;
using System.Collections.Generic;
using System.Text;
// ADD "using System.ServiceProcess;" after you add the 
// Reference to the System.ServiceProcess in the solution Explorer
using System.ServiceProcess;
namespace Using_ServiceController{
    class Program{
        static void Main(string[] args){
            ServiceController myService = new ServiceController();
            myService.ServiceName = "ImapiService";
            string svcStatus = myService.Status.ToString();
                if (svcStatus == "Running"){
                    myService.Stop();
                }else if(svcStatus == "Stopped"){
                    myService.Start();
                }else{
                    myService.Stop();
                }
        }
    }
}
0 голосов
/ 27 ноября 2013

Звоните Environment.Exit с кодом ошибки больше 0, что кажется целесообразным, затем при установке мы настраиваем службу на перезапуск при ошибке.

Environment.Exit(1);

Я сделал то же самое в своем Службе. Работает нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...