2013-05-01 4 views
15

Giới thiệu về lập trình Dịch vụ Windows: cách dừng dịch vụ windows của tôi?Cách dừng dịch vụ Windows theo chương trình

Dưới đây là một mã rất đơn giản ví dụ (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; 
    }; 
}; 

Vì vậy: Tôi vừa tạo "Dịch vụ thử nghiệm của tôi" bắt đầu nó và dừng lại. Nhưng khi tôi nhìn vào Services.msc của tôi - "Dịch vụ thử nghiệm của tôi" vẫn tiếp tục chạy và dừng CHỈ khi tôi nhấp vào liên kết "Ngừng". Tại sao? - tại sao dịch vụ .Stop() không làm gì?

ServiceController.Stop() cũng không làm gì cả!

Làm thế nào tôi có thể ngừng dịch vụ của mình từ phương thức Main()?

+1

Đảm bảo bạn đang chạy ứng dụng với tư cách quản trị viên. – Icemanind

Trả lời

10

Stop -function gửi tín hiệu dừng. Nó không đợi cho đến khi tín hiệu được nhận và xử lý.

Bạn sẽ phải chờ cho đến khi tín hiệu Dừng đã thực hiện công việc. Bạn có thể làm điều đó bằng cách gọi WaitForStatus:

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

Xem để biết thêm: http://msdn.microsoft.com/nl-nl/library/system.serviceprocess.servicecontroller.waitforstatus(v=vs.71).aspx

Environment.Exit là một trong những khó chịu. ĐỪNG SỬ DỤNG NÓ! Nó hủy bỏ ứng dụng của bạn một cách khó khăn, mà không thực hiện bất kỳ dọn dẹp nào trong các khối cuối cùng, mà không gọi các phương thức finalizer bởi GC, nó chấm dứt tất cả các chủ đề forground khác, v.v .. Tôi có thể tưởng tượng rằng ứng dụng của bạn bị hủy bỏ trước khi tín hiệu dừng .

6

Tôi đang sử dụng các chức năng sau đây trong dự án của tô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

Trong ví dụ mã của bạn service.Stop()ServiceController.Stop() lệnh không làm gì vì họ không được gọi trong khi dịch vụ đang chạy từ ServiceBase.Run(service) chặn hoạt động và nó sẽ trả về chỉ dừng dịch vụ.