WinForms アプリと Windows サービスの 2 つのアプリケーションがあり、どちらも同じマシンで実行されます。WinForms アプリで、サービスが実行されていることを確実に検出できるようにしたい。両方のアプリケーションの設計と実装を完全に制御できます。
私の最初の考えは、サービスによってインスタンス化され、WinForms アプリによって検出可能なMutexを使用することです。
より良いデザインはありますか?
WinForms アプリと Windows サービスの 2 つのアプリケーションがあり、どちらも同じマシンで実行されます。WinForms アプリで、サービスが実行されていることを確実に検出できるようにしたい。両方のアプリケーションの設計と実装を完全に制御できます。
私の最初の考えは、サービスによってインスタンス化され、WinForms アプリによって検出可能なMutexを使用することです。
より良いデザインはありますか?
K. Scott Allen は、この目的で Mutex を使用することと、GC で遭遇する問題について適切な記事を書いています。
マシン上のすべてのセッションでアプリケーションのインスタンスを 1 つだけ実行したい場合は、名前付きミューテックスをグローバル名前空間にプレフィックス「Global\」を付けて配置できます。
[STAThread]
static void Main()
{
using(Mutex mutex = new Mutex(false, "Global\\" + appGuid))
{
if(!mutex.WaitOne(0, false))
{
MessageBox.Show("Instance already running");
return;
}
Application.Run(new Form1());
}
}
編集:
の代わりにエスケープされたバックスラッシュを使用するように文字列リテラルを変更しまし@
た。SO 構文ハイライターはそのままの文字列を好みませんでした。
ミューテックスは行く方法です。プロセス名などを使用するよりもはるかに脆弱ではありません。
ただし、Mutex がガベージ コレクションされていないことを確認する必要があります。サービス (完了するまで実行される「メイン」メソッドではなく、イベント駆動型) の場合、これを行う最も賢明な方法は、おそらくそれを静的変数に入れることです。
サービスが停止したときにミューテックスを破棄すると、ファイナライズなどを待つ必要がなくなります。
Mutex を使用できますが、ServiceController
代わりにクラスを使用することもできます。これにより、サービスがインストールされているかどうかを確認できます。インストールされているが開始されていない場合は、該当する場合は開始します。
http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicecontroller_members.aspx
サービスにいくつかの「接続テスト」機能を実装できます。ただし、これが要件に適合するかどうかはわかりません。winforms の起動時に、サービスを呼び出してサービスが有効かどうかを確認できます。シンプルな WCF コントラクトでサービスを公開できます。
お役に立てれば...
別の方法として、WinForms アプリで実行中のサービスのリストをチェックして、サービスが実行されているかどうかを確認できます。