2013-05-01 11 views
15

Über die Programmierung von Windows-Diensten: Wie kann ich meinen Windows-Dienst stoppen?Windows programmgesteuert stoppen

Hier ist ein sehr vereinfachtes Beispiel-Code (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; 
    }; 
}; 

Also: Ich habe gerade erstellt "My Test Service" fing es an und hielt an. Aber wenn ich in meine Services.msc schaue - "Mein Test Service" läuft weiter und stoppt NUR wenn ich auf einen "Stop" Link klicke. Warum? - Warum service.Stop() Befehl tut nichts?

ServiceController.Stop() tut auch nichts!

Wie kann ich meinen Dienst von der Main() Methode stoppen?

+1

Stellen Sie sicher, dass Sie Ihre Anwendung als Administrator ausführen. – Icemanind

Antwort

10

Die Stop -Funktion sendet ein Stoppsignal. Es wartet nicht bis das Signal empfangen und verarbeitet wird.

Sie werden warten müssen, bis das Stoppsignal seine Arbeit erledigt hat.

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

Siehe für weitere Informationen: http://msdn.microsoft.com/nl-nl/library/system.serviceprocess.servicecontroller.waitforstatus(v=vs.71).aspx

Environment.Exit ist eine böse, die Sie können telefonisch WaitForStatus tun. BENUTZE ES NICHT! Es bricht Ihre Anwendung auf die harte Tour ab, ohne in final blocks zu bereinigen, ohne Finalizer-Methoden vom GC aufzurufen, beendet alle anderen forground-Threads usw. Ich kann mir vorstellen, dass Ihre Anwendung abgebrochen wird, bevor das Stop-Signal Ihre Anwendung verlassen hat .

6

I

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

In Ihrem Code Beispiel service.Stop() und ServiceController.Stop() Befehle folgende Funktionen in meinem Projekt verwenden tut nichts, weil sie nicht genannt werden, während Dienst seit ServiceBase.Run(service) läuft Betrieb blockiert und es gibt nur auf Anschlag der Service.

Verwandte Themen