何が起きているか
Services.msc、コマンドライン、または再起動後にWindowsサービスを起動しようとして、次のエラーが発生しました:
Windows could not start the service on Local Computer.
Error 1067: The process terminated unexpectedly.
意味:サービスプロセス(.exe)は起動したものの、サービスコントロールマネージャーに「実行中」を報告する前に即座にクラッシュしました。Windowsはプロセスが早すぎて終了したことを検知しましたが、なぜそうなったかはわかりません — プロセスが生き残れなかったという事実だけを認識しています。
1067はあくまで症状であり、診断ではありません。クラッシュの原因を特定しなければ修正できません — その答えはログの中にあります。
ステップ1:まずイベントビューアーを確認する
イベントビューアーにはほぼ必ず実際のエラーが記録されています。1067メッセージは単なるラッパーに過ぎません。クラッシュの本当の原因 — DLLの不足、設定ファイルの異常、ポートの競合 — は別途ログに記録されています。
開く方法:
eventvwr.msc
以下の2か所を確認してください:
- Windowsログ → アプリケーション — サービスプロセス自体からのエラー
- Windowsログ → システム — サービスコントロールマネージャーのイベント(ソース:
Service Control Manager)
サービスを起動しようとした時刻前後の赤い「エラー」イベントでフィルタリングしてください。実際に何が問題だったかを教えてくれるのは、1067メッセージではなく、それらのイベントの説明文です。
よく見られる内容:
The program can't start because VCRUNTIME140.dll was not found→ Visual C++ ランタイムが不足しているFailed to open config file: C:\path\to\config.json→ 作業ディレクトリが間違っているかファイルが見つからないbind: Only one usage of each socket address is normally permitted→ ポートがすでに使用中Access is denied→ ファイルまたはレジストリのアクセス権の問題- サービスコード固有のアプリケーションエラー
ステップ2:サービスの設定を確認する
バイナリパスが正しいこと、およびサービスアカウントが適切であることを確認します:
sc qc "YourServiceName"
次のような出力が表示されます:
SERVICE_NAME: YourServiceName
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\path\to\service.exe --config C:\path\to\config.ini
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Your Service
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
そのパスにバイナリが実際に存在するか確認します:
Test-Path "C:\path\to\service.exe"
False の場合、サービスが存在しなくなったパスに対して登録されていることを意味します — 再インストール後やディレクトリ移動後によくある問題です。修正方法:
sc config "YourServiceName" binpath= "C:\correct\path\to\service.exe"
binpath= の後ろのスペースは必須です — sc の構文はその点について厳格です。
ステップ3:実行ファイルを手動で実行する
管理者としてコマンドプロンプトを開き、サービスのバイナリを直接実行します:
"C:\path\to\service.exe"
または引数を付けて:
"C:\path\to\service.exe" --config "C:\path\to\config.ini"
手動実行することで、サービスコントロールマネージャーがエラーを飲み込んでしまう代わりに、コンソールにエラーが直接出力されます。依存関係の不足、設定値の誤り、アクセス権の問題 — これらはすべて、汎用的な1067ラッパーに隠れてしまうのではなく、バイナリを自分で実行すると即座に表示されます。
バイナリがすぐに終了する場合は、終了コードを確認します:
echo %errorlevel%
-1073741515(16進数:0xC0000135)のような負の終了コードは、DLL依存関係の不足を示す明確なサインです。
ステップ4:根本原因を修正する
DLLまたはランタイムが不足している
イベントビューアーに VCRUNTIME140.dll was not found のような内容が表示される場合は、適切なランタイムをインストールしてください:
VCRUNTIME140.dllなど:Visual C++ 再頒布可能パッケージをインストール- Javaサービスの場合:
JAVA_HOMEが設定されており、正しいJREバージョンがインストールされているか確認 - .NETサービスの場合:
dotnet --list-runtimesでインストール済みランタイムを確認
設定ファイルが見つからない、または無効
多くの人がはまる落とし穴があります:サービスは自分のディレクトリから実行されません。デフォルトの作業ディレクトリは C:\Windows\System32 です。設定内の相対パスは暗黙のうちに間違った場所に解決されます。
サービスの設定には常に絶対パスを使用するか、バイナリパスに設定ファイルの場所を明示的に渡してください:
sc config "YourServiceName" binpath= "\"C:\path\to\service.exe\" --config \"C:\path\to\config.ini\""
サービスアカウントのアクセス権の問題
sc qc の出力で SERVICE_START_NAME を確認してください。LocalSystem ではなく LocalService、NetworkService、またはカスタムドメインアカウントになっている場合、バイナリディレクトリや設定ファイルへの読み取りアクセス権がない可能性があります。
そのアカウントに付与されているアクセス権を確認します:
icacls "C:\path\to\service\directory"
読み取りと実行のアクセス権を付与します:
icacls "C:\path\to\service\directory" /grant "NT AUTHORITY\LocalService:(RX)" /T
サービスがログファイルを書き込む場合、ログディレクトリへの書き込みアクセス権も必要です — そうでなければ、作成できないログファイルを開こうとした瞬間にクラッシュします。
ポートの競合
起動時にポート8080をバインドするサービスは、他の何かがそのポートを既に使用している場合、即座にクラッシュします。原因を特定します:
netstat -ano | findstr :8080
最終列のPIDをメモし、次のコマンドで調べます:
tasklist | findstr 1234
競合しているプロセスを停止するか、サービスの設定ファイルでポートを変更してください。
ステップ5:サービスを再起動して確認する
サービスを起動して状態を確認します:
sc start "YourServiceName"
sc query "YourServiceName"
次のような表示が出れば成功です:
STATE : 4 RUNNING
PowerShellの場合:
Get-Service -Name "YourServiceName" | Select-Object Name, Status, StartType
10〜15秒待ってから再度クエリを実行してください。起動時にクラッシュするサービスは、STOPPED に戻る前に一時的に RUNNING と表示されることがあります。その場合はイベントビューアーに戻ってください — その試みからの新しいエラーがその時間帯のタイムスタンプで記録されています。
教訓
- エラー1067は常に症状です。本当のエラーは別の場所にあります — 通常はイベントビューアーか、サービス自身が書き込んだログファイルです。
- 管理者として
.exeを手動実行することが最も素早いデバッグ手順です。サービスコントロールマネージャーが静かに飲み込んでしまうエラーを表面化させます。 - サービスの設定における相対パスはよくある落とし穴です。サービスは自分のディレクトリから実行されません — 絶対パスを使用してください。
- Windowsの更新やアプリケーションの再インストール後は、サービス設定のバイナリパスが有効な場所を指しているか確認してください。ソフトウェアが移動またはアップグレードされると、レジストリエントリが古くなります。

