web-dev-qa-db-fra.com

Comment puis-je redémarrer un service Windows par programme dans .NET

Comment puis-je redémarrer un service Windows par programme dans .NET?
De plus, je dois effectuer une opération lorsque le redémarrage du service est terminé.

63
Nemo

Jetez un œil à la classe ServiceController .

Pour effectuer l'opération qui doit être effectuée au redémarrage du service, je suppose que vous devez le faire vous-même dans le service (s'il s'agit de votre propre service).
Si vous n'avez pas accès à la source du service, vous pouvez peut-être utiliser la méthode WaitForStatus de ServiceController.

36
Frederik Gheysels

Cet article utilise la classe ServiceController pour écrire des méthodes de démarrage, d'arrêt et de redémarrage des services Windows; il vaut peut-être la peine d'y jeter un coup d'œil.

Extrait de l'article (méthode "Restart Service"):

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
  {
    // ...
  }
}
70
Donut

Un exemple d'utilisation par la classe 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);
    }
}
22
ionat

Vous pouvez également appeler la commande net pour ce faire. Exemple:

System.Diagnostics.Process.Start("net", "stop IISAdmin");
System.Diagnostics.Process.Start("net", "start IISAdmin");
15
Druid

Cette réponse est basée sur @Donut Answer (la réponse la plus votée de cette question), mais avec quelques modifications.

  1. Suppression de la classe ServiceController après chaque utilisation, car elle implémente l'interface IDisposable.
  2. Réduisez les paramètres de la méthode: il n'est pas nécessaire que le paramètre serviceName soit transmis pour chaque méthode, nous pouvons le définir dans le constructeur, et chaque autre méthode utilisera ce nom de service.
    C'est aussi plus OOP friendly.
  3. Gérez l'exception catch de manière à ce que cette classe puisse être utilisée comme composant.
  4. Supprimez le paramètre timeoutMilliseconds de chaque méthode.
  5. Ajoutez deux nouvelles méthodes StartOrRestart et StopServiceIfRunning, qui pourraient être considérées comme un wrapper pour d'autres méthodes de base. Le but de ces méthodes est uniquement d'éviter les exceptions, comme décrit dans le commentaire.

Voici la classe

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;
            }
        }
    }
}
8
Hakan Fıstık

Que diriez-vous

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

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

N'oubliez pas d'ajouter le System.ServiceProcess.dll à votre projet pour que cela fonctionne.

6
Johnno Nolan

Voir ceci article .

Voici un extrait du article .

//[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();
                }
        }
    }
}
2
David Basarab