問題の概要
Windows サービスの開始は本来、スムーズなプロセスであるべきです。しかし、重い初期化ルーチンが原因で、イライラさせるエラー 1053 ダイアログが表示されることがよくあります。これは通常、カスタムサービスがオペレーティングシステムに「開始」ステータスを報告するのに時間がかかりすぎた場合に発生します。
デフォルトでは、Windows Service Control Manager (SCM) は待機時間が短く設定されています。サービスが実行中であることを通知するのに与えられる時間は、正確に 30,000 ミリ秒(30 秒)です。大規模な設定ファイルの読み込みやリモートデータベースへの接続中にこのタイマーがゼロになると、Windows はプロセスが停止したと判断し、即座に終了させます。
このタイムアウトは、古いハードウェアで実行されている .NET アプリケーションや、起動フェーズで低速なネットワークリソースに依存するサービスで特に一般的です。
ステップ 1:レジストリでサービスのタイムアウト時間を延長する
サービスにさらに余裕が必要な場合は、Windows の待機時間を長く設定できます。グローバルなタイムアウト制限を変更することで、システム上のすべてのサービスに初期化のための追加時間を与えられます。
Win + Rを押し、regedit と入力して Enter キーを押します。- 次のパスに移動します:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
- 右側のペインで **ServicesPipeTimeout** を探します。
- 見つからない場合は、空のスペースを右クリックし、**新規 > DWORD (32 ビット) 値** を選択して、名前を `ServicesPipeTimeout` に設定します。
- エントリを右クリックし、**修正** を選択します。
- **表記** を **10 進数** に設定します。
- 希望する待ち時間をミリ秒単位で入力します。60 秒の場合は `60000`、3 分の場合は `180000` を使用します。
- OK をクリックし、**コンピュータを再起動**して新しい制限を適用します。
## ステップ 2:.NET Framework の依存関係を確認する
互換性の問題により、サービスが開始される前にハングすることがあります。レジストリの調整で解決しない場合、正しいランタイムが見つからないためにサービスがクラッシュしている可能性があります。エラー 1053 は、根本的な .NET 初期化エラーを隠蔽する汎用的なエラーとして表示されることがよくあります。
- サーバーに、サービスが必要とする正確なバージョンの .NET Framework がインストールされていることを確認してください。
- バージョンの不一致をチェックします。サービスが .NET 4.8 をターゲットにしているのに、マシンに .NET 3.5 しかない場合、アプリはサイレント起動フェーズ中にタイムアウトする可能性が高くなります。
- 本番サーバーには、Developer Pack ではなく、常に Microsoft から提供されている **Runtime** バージョンをインストールしてください。
## ステップ 3:欠落している DLL や設定ファイルを確認する
欠落している依存関係を検索している最中に、サービスがタイムアウトすることがあります。サービスにはユーザーインターフェースがないため、「ファイルが見つかりません」という警告を表示できません。Windows によってシャットダウンされるまで、ただ空回りし続けます。
コマンドプロンプトを使用して実行ファイルを直接実行し、これらの隠れたエラーを特定します:
C:\Path\To\Your\Service\YourService.exe
アプリは最終的に Service Controller 経由で開始する必要があるというメッセージを表示して終了しますが、その前に DLL の欠落や `app.config` ファイルの破損に関する重大なエラーが出力される場合があります。
## ステップ 4:SFC でシステムファイルを修復する
Print Spooler などの標準的な Windows サービスでも、システムバイナリの破損によりこのエラーが発生することがあります。組み込みの Windows サービスが失敗している場合は、System File Checker を使用して損傷を修復してください。
- コマンドプロンプトを**管理者**として実行します。
- 次の修復コマンドを実行します:
```
sfc /scannow
- スキャンが 100% に達するまで待ち、コンピュータを再起動します。
動作確認
修正を適用したら、services.msc から再度サービスの開始を試みてください。開始後、イベントビューアー (eventvwr.msc) を開き、Windows ログ > システム に移動します。サービスが正常に実行状態になったことを確認する「情報」エントリを探してください。
開発者向けの最適化チップス
レジストリの調整に頼るのは一時しのぎであり、根本的な解決策ではありません。ソースコードを管理している場合は、タイムアウトを完全に排除するために次の 2 つの戦略を検討してください。
1. OnStart から処理をオフロードする
OnStart メソッドは、レースそのものではなく、号砲として機能すべきです。データベースの移行やファイルのインデックス作成などの重いロジックはバックグラウンドスレッドに移動し、メソッドが即座に Windows に制御を返せるようにします。
protected override void OnStart(string[] args)
{
// バックグラウンドタスクを開始し、即座に制御を返す
Task.Run(() => DoHeavyInitialization());
}
2. RequestAdditionalTime を使用する
長い起動プロセスが避けられない場合は、RequestAdditionalTime メソッドを使用してください。これにより SCM に対して 30 秒のカウントダウンをリセットするように通知し、予期せぬシャットダウンを防ぐことができます。
protected override void OnStart(string[] args)
{
// Windows に 60 秒間の追加の待機を要求する
this.RequestAdditionalTime(60000);
PerformComplexSetup();
}

