2013-05-01 21 views
15

O programowaniu usług systemu Windows: jak zatrzymać moją usługę Windows?Jak programowo zatrzymać usługę Windows

Oto bardzo uproszczony przykład kodu (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; 
    }; 
}; 

Więc: Właśnie stworzył "Moje usługi Test" zaczął go i zatrzymał się. Ale kiedy patrzę na mój Services.msc - "Moja usługa testowa" działa dalej i zatrzymuje się TYLKO po kliknięciu linku "Zatrzymaj". Czemu? - dlaczego polecenie service.Stop() nic nie robi?

ServiceController.Stop() również nie robi nic!

Jak mogę zatrzymać moją usługę z metody Main()?

+1

Upewnij się, że używasz aplikacji jako administrator. – Icemanind

Odpowiedz

10

- Funkcja Stop wysyła sygnał zatrzymania. Nie czeka, aż sygnał zostanie odebrany i przetworzony.

Będziesz musiał poczekać, aż sygnał zatrzymania wykona swoją pracę. Można to zrobić dzwoniąc WaitForStatus:

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

Zobacz więcej informacji: http://msdn.microsoft.com/nl-nl/library/system.serviceprocess.servicecontroller.waitforstatus(v=vs.71).aspx

Environment.Exit jest paskudny jeden. NIE UŻYWAJ TEGO! Przerywa on twoją aplikację w trudny sposób, bez wykonywania żadnych porządków w blokach końcowych, bez wywoływania metod finalizatora przez GC, kończy wszystkie inne wątki itd. Mogę sobie wyobrazić, że twoja aplikacja zostanie przerwana zanim sygnał stopu nawet opuści twoją aplikację .

6

używam następujących funkcji w moim projekcie

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

W przykładzie kodu service.Stop() i ServiceController.Stop() polecenia nic nie robi, ponieważ nie są one nazywane, gdy usługa jest uruchomiona od ServiceBase.Run(service) jest działanie blokowania i zwraca tylko na przystanku Serwis.

Powiązane problemy