リモートデスクトップセッションから起動したプログラムは、そのセッションをサインアウトすると停止し、再起動後も自動では立ち上がりません。ボット、ゲームサーバー、Node.js や Python のアプリケーション、データ収集ツール、トレードツールなどは、Windows の起動とともに自動で立ち上がり、クラッシュしても自動で再起動するように設定すべきです。この記事では、Windows Server でこれを実現する確実な 3 つの方法として、タスクスケジューラ、無料のサービスラッパー NSSM、Windows 標準のサービス回復設定を紹介します。
| 方法 | 向いている用途 | クラッシュ時の再起動 | デスクトップへのログオン |
|---|---|---|---|
| タスクスケジューラ「スタートアップ時」 | スクリプトやコンソールプログラム | あり(再試行の設定) | 不要 |
| NSSM サービス | 長時間動作するコンソールアプリ(Node.js、Python、Java、ゲームサーバー) | あり(即時) | 不要 |
| 自動ログオン + スタートアップフォルダー | ウィンドウ表示や GUI が必要なプログラム | なし | 必要 |
taskschd.msc を開き、(「基本タスクの作成」ではなく)タスクの作成(Create Task)を選択します。
同じタスクを PowerShell で作成する場合は次のとおりです。
$action = New-ScheduledTaskAction -Execute "C:\apps\collector\collector.exe" -WorkingDirectory "C:\apps\collector"
$trigger = New-ScheduledTaskTrigger -AtStartup
$trigger.Delay = "PT30S"
$settings = New-ScheduledTaskSettingsSet -RestartCount 999 -RestartInterval (New-TimeSpan -Minutes 1) `
-ExecutionTimeLimit ([TimeSpan]::Zero) -StartWhenAvailable
Register-ScheduledTask -TaskName "Collector" -Action $action -Trigger $trigger -Settings $settings `
-User "SYSTEM" -RunLevel Highest
Start-ScheduledTask -TaskName "Collector"
Get-ScheduledTaskInfo -TaskName "Collector" # LastTaskResult 0 = success
NSSM(Non-Sucking Service Manager)は、任意の実行ファイルを本物の Windows サービスとしてラップし、プログラムが終了するとすぐに再起動し、コンソール出力をログファイルに書き出すこともできます。nssm.cc からダウンロードし、(win64 フォルダー内の)nssm.exe を C:\Windows\System32 にコピーしてから、次を実行します。
# Example: a Node.js application
nssm install MyApp "C:\Program Files\nodejs\node.exe" "C:\apps\myapp\server.js"
nssm set MyApp AppDirectory C:\apps\myapp
nssm set MyApp AppStdout C:\apps\myapp\logs\out.log
nssm set MyApp AppStderr C:\apps\myapp\logs\error.log
nssm set MyApp AppRotateFiles 1
nssm set MyApp AppRotateBytes 10485760
nssm set MyApp Start SERVICE_AUTO_START
nssm start MyApp
nssm status MyApp
nssm restart MyApp
nssm edit MyApp # graphical editor for all settings
nssm remove MyApp confirm
Python スクリプトの場合は python.exe のパスを指定し、スクリプトを引数にします。Java の場合は java.exe に -jar app.jar を指定します。プログラムがネットワーク共有やユーザープロファイルにアクセスする必要がある場合は、LocalSystem ではなく、Log on タブ(nssm edit で開く設定画面)で実行アカウントを設定してください。
自身をサービスとしてインストールするプログラム(データベース、ゲームサーバー、エージェントなど)の場合は、障害が発生したときに自動で再起動するよう Windows に設定します。
# Restart after 5 seconds on the first three failures; reset the failure counter after one day
sc.exe failure "MyService" reset= 86400 actions= restart/5000/restart/5000/restart/5000
sc.exe failureflag "MyService" 1
sc.exe config "MyService" start= auto
sc.exe qfailure "MyService"
同じ設定は、各サービスのプロパティの回復(Recovery)タブ(services.msc)からも行えます。
サービスは表示可能なデスクトップのない分離されたセッションで実行されるため、ウィンドウを表示する必要がある GUI プログラム(一部のトレード用ターミナル、ゲームクライアント、自動化ツールなど)はサービスとしては動作しません。この場合は、Microsoft の Sysinternals ツール Autologon(パスワードは暗号化して保存されます)で専用ユーザーの自動サインインを有効にし、そのユーザーの shell:startup にプログラムのショートカットを置きます。リモートデスクトップセッションを離れるときは、サインアウトではなく切断してください。また、そのユーザーをセッションの自動サインアウトの時間制限の対象から外しておきます。
開始 (オプション)(Start in)(または NSSM の AppDirectory)が設定されているか確認してください。多くのプログラムは作業ディレクトリを基準に設定ファイルを探します。プログラム自身のログも確認し、NSSM の場合は AppStderr のファイルもあわせて確認してください。
まったく同じコマンドを PowerShell ウィンドウで手動実行して、エラーを確認してください。サービスの場合は、イベント ビューアー → Windows ログ → システム(Event Viewer → Windows Logs → System)とアプリケーション(Application)も確認します。
はい。スタートアップタスクと自動起動のサービスは、再起動のたびに再び起動します。だからこそ、開いたままのリモートデスクトップセッションよりも確実なのです。再起動のタイミングを制御するにはWindows Update の管理を参照してください。
上記の手順で解決しない場合は、サポートチケットを送信して IMIDC の 24 時間 365 日対応テクニカルサポートへご連絡ください。サーバー IP、Windows Server のバージョン、実行したいプログラム、正確なエラーまたはイベントログの内容を添えていただくと、より迅速に調査できます。