web-dev-qa-db-ja.com

.NETコードから.NET Windowsサービスにカスタムコマンドを送信する方法

次のリンクのように、C#コードを使用してサービスを停止、開始、および「停止してから開始」できます。

http://www.csharp-examples.net/restart-windows-service/

OnStartOnStopを実装する.NETサービスをベイクしました。ただし、停止してから開始するだけではなく、より複雑な「スマートリスタート」機能を実装する必要があります。停止時間をほんの数秒に保つ必要があります(ただし、この場合、Stop + Startはクリーンに実行すると数分かかることがあり、クリーンに実行する必要があります)。他の部分が再起動/更新している間、システムの一部を使用できるようにする必要があります。 。

要するに、このOnSmartRestart機能を実装する前に、別のC#アプリケーションからこの呼び出しを呼び出す簡単な方法があることを確認したいと思います。

この機能は重要ですが、危険です。私はそれをかなり隠し、ある程度安全にし、シンプルに保ち、再起動せずに通常の作業を行っている間、Windowsサービスのパフォーマンスにほとんど影響がないことを確認したいと思います。

ファイルをポーリングするか、ポートを開く必要があり、そのためにCPUを使いすぎている場合、それは良い解決策ではありません。また、これをできるだけシンプルに保ちたいと思います(繰り返し申し訳ありません)。

37
Hamish Grubijan

ServiceController.ExecuteCommand を使用して、サービスに「コマンド」を送信できます。

const int SmartRestart = 222;

var service = new System.ServiceProcess.ServiceController("MyService");
service.ExecuteCommand(SmartRestart);
service.WaitForStatus(ServiceControllerStatus.Running, timeout);

System.ServiceProcess.dllアセンブリへの参照を追加する必要があります。

サービスは ServiceBase.OnCustomCommand をオーバーライドすることでコマンドに反応できます。

protected override void OnCustomCommand(int command)
{
    if (command == SmartRestart)
    {
        // ...
    }
}
59
dtb

Windowsで外部プロセスと通信する通常の方法は次のとおりです。

  1. 名前付きパイプ
  2. ソケット
  3. COMのGetObjectを使用してオブジェクトへの参照を取得し、公開されたインターフェイスでそのメソッドを呼び出します。

最初の2つはWCFとして公開されているので、これが方法です。 3つ目はあなたの状況に関連していないようで、古いです。

同じマシンからコマンドを実行する必要がある場合は、名前付きパイプを使用できますが、ハード化により非常に困難で面倒です。それ以外の場合は、WCFのTCP名前付きバインディングを使用します。

15
Aliostad