webdevqa.jp.net

Windowsサービスをプログラムで自動的に再起動するにはどうすればよいですか?

.NETで堅牢なコードを記述して、Windowsサービス(サーバー2003)がそれ自体を再起動できるようにする必要があります。そのための最善の方法は何ですか?それを行うためのいくつかの.NET APIはありますか?

128
Ron Harlev

障害発生後にサービスを再起動するように設定します(コントロールパネルでサービスをダブルクリックし、それらのタブを確認します-名前を忘れました)。その後、サービスを再起動したいときはいつでも、Environment.Exit(1)(またはゼロ以外の戻り値)を呼び出すだけで、OSがサービスを再起動します。

181
TheSoftwareJedi
Dim proc As New Process()
Dim psi As New ProcessStartInfo()

psi.CreateNoWindow = True
psi.FileName = "cmd.exe"
psi.Arguments = "/C net stop YOURSERVICENAMEHERE && net start YOURSERVICENAMEHERE"
psi.LoadUserProfile = False
psi.UseShellExecute = False
psi.WindowStyle = ProcessWindowStyle.Hidden
proc.StartInfo = psi
proc.Start()
22
Khalid Rahaman

サービスを実行しているユーザーアカウントに、サービスを停止および再起動する権限があるかどうかさえわかりません。

15
Greg Hewgill
const string strCmdText = "/C net stop \"SERVICENAME\"&net start \"SERVICENAME\"";
Process.Start("CMD.exe", strCmdText);

ここで、SERVICENAMEはサービスの名前です(サービス名のスペースを説明するために二重引用符が含まれています。それ以外の場合は省略できます)。

クリーン、自動再起動の構成は不要です。

9
Filip

自分自身を再起動するDOSコマンドプロンプトであるプロセスを作成できます。

 Process process = new Process();
 process.StartInfo.FileName = "cmd";
 process.StartInfo.Arguments = "/c net stop \"servicename\" & net start \"servicename\"";
 process.Start();
9
john

なぜ再起動するかによります。

サービスを定期的に削除する方法を探している場合は、サービスでタイマーを実行して、定期的にパージルーチンを発生させることができます。

障害時に再起動する方法を探している場合-サービスホスト自体は、セットアップ時にその機能を提供できます。

では、なぜサーバーを再起動する必要があるのですか?何を達成しようとしていますか?

5
Brody

バッチファイルまたはEXEへのシェルアウトの問題は、外部アプリを実行するために必要な権限がサービスにある場合とない場合があることです。

私が見つけた最もクリーンな方法は、サービスコントロールマネージャのエントリポイントであるOnStop()メソッドを使用することです。その後、すべてのクリーンアップコードが実行され、停止コードが機能していると仮定して、ハングしたソケットや他のプロセスはありません。

これを行うには、終了する前にOnStopメソッドにエラーコードで終了するように指示するフラグを設定する必要があります。その後、SCMはサービスを再起動する必要があることを認識します。このフラグがないと、SCMからサービスを手動で停止できません。これは、エラーで再起動するようにサービスを設定したことも前提としています。

これが私の停止コードです。

...

bool ABORT;

protected override void OnStop()
{
    Logger.log("Stopping service");
    WorkThreadRun = false;
    WorkThread.Join();
    Logger.stop();
    // if there was a problem, set an exit error code
    // so the service manager will restart this
    if(ABORT)Environment.Exit(1);
}

サービスで問題が発生し、再起動する必要がある場合、SCMからサービスを停止するスレッドを起動します。これにより、サービスは自動的にクリーンアップできます。

...

if(NeedToRestart)
{
    ABORT = true;
    new Thread(RestartThread).Start();
}

void RestartThread()
{
    ServiceController sc = new ServiceController(ServiceName);
    try
    {
        sc.Stop();
    }
    catch (Exception) { }
}
3
user3235770

自己完結型のサービスではできないと思います(Restartを呼び出すと、サービスが停止し、Restartコマンドが中断され、再び開始されることはありません)。 2番目の.exe(ServiceManagerクラスを使用するコンソールアプリ)を追加できる場合は、スタンドアロンの.exeを開始し、サービスを再起動して終了することができます。

考え直して、おそらくサービスに(たとえば、コマンドラインの 'at'コマンドを使用して)スケジュールされたタスクを登録させて、サービスを開始してからサービスを停止させることができます。それはおそらく機能するでしょう。

3
technophile

Windowsスケジューラを使用して、サービスの再起動をスケジュールします。問題は、自分で再起動できないが、自分で停止できることです。 (本質的には、あなたが座っているブランチを切り離しました...私のアナロジーが得られれば)あなたはあなたのために別のプロセスを必要とします。 Windowsスケジューラは適切なものです。ワンタイムタスクをスケジュールして、サービスを(サービス自体からでも)再起動して、すぐに実行します。

そうでなければ、あなたのためにそれを行う「羊飼い」プロセスを作成する必要があります。

2
dviljoen

別のappdomainを作成して、アプリケーションコードをホストします。再起動が必要な場合、プロセス(windowsサービス)の代わりにappdomainをアンロードおよび再ロードできます。これがIISアプリプールの仕組みです。asp.netアプリを直接実行せず、別個のappdmainを使用します。

1
CreativeManix

質問に対する最初の回答は最も簡単な解決策です: "Environment.Exit(1)"これをWindows Server 2008 R2で使用していますが、完全に機能します。サービスは自動的に停止し、O/Sは1分間待機してから再起動します。

1
tangentMan

私はそれができるとは思わない。サービスが「停止」すると、完全にアンロードされます。

まあ、OK、私が思うに常に方法があります。たとえば、分離プロセスを作成してサービスを停止し、再起動して終了することができます。

1
T.E.D.

より良いアプローチは、アプリケーションのラッパーとしてNTサービスを利用することです。 NTサービスが開始されると、アプリケーションはコマンドの開始を待機する(または自動的に開始するように構成される)「アイドル」モードで開始できます。

車のことを考えてみましょう。起動すると、アイドル状態で始まり、コマンドが前進または後退するのを待ちます。これにより、アプリケーションを公開する方法を選択できるため、リモート管理が改善されるなど、他の利点も得られます。

0
plamb

nssmはとても素晴らしいです。これはすべてあなたのために行います

0

このようなrestart.batファイルを作成します

@echo on
set once="C:\Program Files\MyService\once.bat"
set taskname=Restart_MyService
set service=MyService
echo rem %time% >%once%
echo net stop %service% >>%once%
echo net start %service% >>%once%
echo del %once% >>%once%

schtasks /create /ru "System" /tn %taskname% /tr '%once%' /sc onstart /F /V1 /Z
schtasks /run /tn %taskname%

次に、%service%の開始時にタスク%taskname%を削除します

0
Erik Martino

ただ渡す:そして、私はいくつかの余分な情報を追加すると思いました...

また、例外をスローすることもできます。これにより、Windowsサービスが自動的に閉じられ、自動再起動オプションが起動します。これに関する唯一の問題は、PCに開発環境がある場合、JITが起動しようとすることです。デバッグY/Nを示すプロンプトが表示されます。いいえと言うと、閉じてから、適切に再起動します。 (JITのないPCでは、すべて正常に動作します)。制御できない理由は、このJITはWin 7で初めて(XPなどで正常に動作していたため)JITを無効にする方法を見つけようとしているためです。環境を試すことができます。ここで説明した終了メソッドは、それがどのように機能するかを確認します。

クリスチャン:ブリストル、イギリス

0
Kristian