スプール ファイルの削除に失敗したことを示すイベント ログについて

こんにちは、Windows プラットフォーム サポートの柴田です。

 

大量の印刷を行っている場合等に、スプール ファイルの削除に失敗したことを示すエラー イベントがイベント ログに記録されることがあります。

 

# 記録されるイベントの例

ログの名前:         Microsoft-Windows-PrintService/Operational

ソース:           Microsoft-Windows-PrintService

日付:            XXXX/XX/XX XX:XX:XX

イベント ID:       812

タスクのカテゴリ:      ファイル操作を実行しています

レベル:           エラー

キーワード:         印刷スプーラー

ユーザー:          SYSTEM

コンピューター:       XXXXXXXXXX

説明:

ファイル C:\Windows\system32\spool\PRINTERS\00170.SPL の削除に失敗しました。エラー コード 0x2。コンテキスト情報については、イベント ユーザー データを参照してください。

 

※この時のエラー イベント 0x2 は、ほかにも次のようなファイル システム関連のエラー コードが含まれていることがございます。

 

・エラー コード 0x5 (ERROR_ACCESS_DENIED)

・エラー コード 0x20 (ERROR_SHARING_VIOLATION)

 

今回は、上記のようなエラー イベントが記録された場合の対処方法をご案内いたします。

(スプール フォルダは既定で <システム ルート ディレクトリ>\System32\Spool\Printers に設定されていますので、ご確認ください。)

 

# ERROR_FILE_NOT_FOUND の場合

既にそのスプール ファイルが削除されていたことが原因ですので、スプール フォルダ内にスプール ファイルが残っていることはありません。

そのため、エラーを無視していただいて問題ありません。

 

# ERROR_SHARING_VIOLATION および ERROR_ACCESS_DENIED の場合

スプール フォルダ内にスプール ファイルが残存している場合があります。

その場合は、システム再起動時等のタイミングで、削除に失敗して残っているスプール ファイルを削除してください。

 

なお、スプール ファイルの削除は、その印刷ジョブの印刷が完了していることが前提で実行されます。

そのため、これらのエラー イベントが記録されたとしても、その他のエラーが記録されていなければ、印刷そのものは正常に実行されておりますのでご安心ください。

 

続いて、本エラー発生に関する spoolsv.exe 内部動作についてお伝えいたします。

 

# spoolsv.exe 内部動作

1. spoolsv.exe 以外のプロセス (アプリケーションやサービス等) から、オープン中のプリンター ハンドルのクローズが行われる。

2. RPC 経由で、spoolsv.exe に対しプリンター ハンドル クローズ (ClosePrinter) のリクエストが送信される。

3. spoolsv.exe から、ClosePrinter を実行するためのスレッド (以下「ClosePrinter 実行スレッド」) が起動される。

4. オープン中のプリンター上に印刷ジョブが残っていなければ、「ClosePrinter 実行スレッド」がその印刷ジョブに紐づくスプール ファイルを削除した上で、プリンター ハンドルをクローズする。

 

上記のとおり spoolsv.exe 内部では、「印刷ジョブを処理するスレッド」と「ClosePrinter 実行スレッド」の間で、スプール ファイル削除処理の同期が行われておりません。

その結果、タイミングによってはどちらかのスレッドから行われたスプール ファイル削除の処理が、ERROR_SHARING_VIOLATION/ERROR_FILE_NOT_FOUND/ERROR_ACCESS_DENIED 等のエラーにより失敗することがあり、エラー イベントとしてイベント ログに記録されます。

 

以上の動作につきましては、現在の spoolsv.exe の設計上、回避できない仕様上の制限事項となります。

設計として好ましい動作ではないと思いますが、このようなエラー イベントが記録された場合には、参考にしていただけると幸いです。