À propos de la programmation des services Windows: comment arrêter mon service Windows?
Voici un exemple de code très simplifié (C #):
// Here is my service class (MyTestService.cs).
public class MyTestService:ServiceBase{
// Constructor.
public MyTestService(){
this.ServiceName = "My Test Service";
return;
}
};
// My application class (ApplicationClass.cs).
public static class ApplicationClass{
// Here is main Main() method.
public static void Main(){
// 1. Creating a service instance
// and running it using ServiceBase.
MyTestService service = new MyTestService();
ServiceBase.Run(service);
// 2. Performing a test shutdown of a service.
service.Stop();
Environment.Exit(0);
return;
};
};
Donc: je viens de créer "My Test Service", je l'ai démarré et arrêté. Mais lorsque je regarde dans mon Services.msc - "Mon service de test" continue de fonctionner et s'arrête UNIQUEMENT lorsque je clique sur un lien "Arrêter". Pourquoi? - pourquoi service.Stop () la commande ne fait rien?
ServiceController.Stop () ne fait rien non plus!
Comment puis-je arrêter mon service à partir de la méthode Main ()?
La fonction Stop
- envoie un signal d'arrêt. Il n'attend pas que le signal soit reçu et traité.
Vous devrez attendre que le signal d'arrêt ait fait son travail. Vous pouvez le faire en appelant WaitForStatus
:
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped);
Voir pour plus d'informations: http://msdn.Microsoft.com/nl-nl/library/system.serviceprocess.servicecontroller.waitforstatus (v = vs.71) .aspx
Environment.Exit
est méchant. NE L'UTILISE PAS! Il abandonne votre application à la dure, sans effectuer de nettoyage dans les blocs enfin, sans appeler les méthodes de finalisation par le GC, il termine tous les autres threads forground, etc. Je peux imaginer que votre application est abandonnée avant que le signal d'arrêt quitte même votre application .
J'utilise les fonctions suivantes dans mon projet
public static ServiceController GetService(string serviceName)
{
ServiceController[] services = ServiceController.GetServices();
return services.FirstOrDefault(_ => Contracts.Extensions.CompareStrings(_.ServiceName, serviceName));
}
public static bool IsServiceRunning(string serviceName)
{
ServiceControllerStatus status;
uint counter = 0;
do
{
ServiceController service = GetService(serviceName);
if (service == null)
{
return false;
}
Thread.Sleep(100);
status = service.Status;
} while (!(status == ServiceControllerStatus.Stopped ||
status == ServiceControllerStatus.Running) &&
(++counter < 30));
return status == ServiceControllerStatus.Running;
}
public static bool IsServiceInstalled(string serviceName)
{
return GetService(serviceName) != null;
}
public static void StartService(string serviceName)
{
ServiceController controller = GetService(serviceName);
if (controller == null)
{
return;
}
controller.Start();
controller.WaitForStatus(ServiceControllerStatus.Running);
}
public static void StopService(string serviceName)
{
ServiceController controller = GetService(serviceName);
if (controller == null)
{
return;
}
controller.Stop();
controller.WaitForStatus(ServiceControllerStatus.Stopped);
}
Dans votre exemple de code, les commandes service.Stop()
et ServiceController.Stop()
ne font rien car elles ne sont pas appelées lorsque le service est en cours d'exécution car ServiceBase.Run(service)
bloque l'opération et ne renvoie que lors de l'arrêt du un service.