23

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

だから:「My Test Service」を作成して開始し、停止しました。しかし、Services.msc を調べていると、「My Test Service」は引き続き実行され、「停止」リンクをクリックした場合にのみ停止します。なんで?- service.Stop()コマンドが何もしないのはなぜですか?

ServiceController.Stop() も何もしません!

Main() メソッドからサービスを停止するにはどうすればよいですか?

4

3 に答える 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厄介なものです。使用しないでください。最終ブロックでクリーンアップを実行せずに、GC によってファイナライザー メソッドを呼び出すことなく、アプリケーションを難しい方法で中止し、他のすべてのフォアグラウンド スレッドを終了します。 .

于 2013-05-01T12:58:47.083 に答える
11

私は自分のプロジェクトで次の機能を使用しています

    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);
    }
于 2013-05-01T13:30:15.790 に答える
3

あなたのコード例service.Stop()ServiceController.Stop()コマンドでは、操作をブロックしているためサービスの実行中に呼び出されずServiceBase.Run(service)、サービスの停止時にのみ返されるため、コマンドは何もしません。

于 2014-07-16T07:54:47.597 に答える