如何以编程方式停止Windows服务

26

关于编写Windows服务:如何停止我的Windows服务?

这里是一个非常简单的示例代码(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;
    };
};

所以:我刚刚创建了“我的测试服务”,启动并停止了它。但是当我查看我的Services.msc时,“我的测试服务”仍在运行,并且只有在我点击“停止”链接时才会停止。为什么?-为什么service.Stop()命令没有任何作用?

ServiceController.Stop()也没有任何作用!

如何从Main()方法停止我的服务?


1
请确保以管理员身份运行您的应用程序。 - Icemanind
3个回答

22

Stop函数发送停止信号。它不会等待信号被接收和处理。

你需要等待停止信号完成其工作,你可以通过调用WaitForStatus来实现:

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

了解更多信息,请参见:http://msdn.microsoft.com/nl-nl/library/system.serviceprocess.servicecontroller.waitforstatus(v=vs.71).aspx

Environment.Exit很危险。不要使用它!它会强制终止应用程序,没有执行finally块中的任何清理操作,没有通过GC调用最终器方法,它会终止所有其他前台线程等。我可以想象在停止信号离开您的应用程序之前,您的应用程序已被终止。


12

我在我的项目中使用以下函数:

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

4
当前上下文中不存在“Contracts”这个名称。 - Thompson
1
@Thompson:然后使用services.FirstOrDefault(_ => _.ServiceName == serviceName) - Vinod Srivastav

3
在你的代码示例中,service.Stop()ServiceController.Stop() 命令不起作用,因为它们在服务运行时没有被调用,由于 ServiceBase.Run(service) 是一个阻塞操作,并且只有当服务停止时才返回。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接