プリンタの問題切り分けの一例
こんにちは、A尾です。
今回は、技術的に突っ込んだ内容ではないのですが、開発中のプリンタドライバやスプーラ コンポーネント使用時に検出された問題をどのように捌いていけばよいか、お話させていただこうと思います。
と言いましても、開発しているモジュールの仕様や実装内容によって様々な問題が発生いたします。そのため、「どのような問題に対してどのような対策をすればよいか?」といった具体的な内容ではなく、検出した問題に対して「どうすれば早く解決までたどりつけるか?」「どのようなアプローチをしていけばよいか?」という観点から、デバッグ開始前の一次分析時の材料集めの一例を紹介していきたいと思います。
もちろん、これから紹介させていただく方法は状況によっては適切ではない場合もありますし、もっと色々な方法もあるかと思います。また、どの分野においてもそうですが、経験に基づく第六感(?)をアテにして、すぐにデバッグしたほうがいい場合もあるかと思います。そのため、あくまで参考情報として、皆さんの今後の作業にお役立ていただければと思っています。
■プリント プロセッサ
Windows 標準のプリント プロセッサ "WinPrint" を使用している場合にはこれ以上の切り分けはなかなか難しいのですが、独自のプリントプロセッサを開発している場合には、まずは "WinPrint" に変更しても同じ問題が発生するか確認してみるのがいいかと思います。"WinPrint" にも同様の問題が潜在している可能性もありますので注意が必要ですが、"WinPrint" 使用時でも再現する場合にはプリント プロセッサに起因した問題ではない可能性が高いかと思います。
また、WDK サンプル "GenPrint" をベースに開発したプリント プロセッサである場合には、使用するプリント プロセッサを "GenPrint" に変更しても再現するか確認する方法もあります。"GetPrint" で再現しない場合には、"GenPrint" に対してカスタマイズしていく過程にて問題が潜在してしまったと判断していいかと思います。
"GenPrint" はここにあります。
%BASEDIR%\src\print\genprint
■プリンタ ドライバ
まず、モノリシック プリンタ ドライバを開発されている方。
このような方は、プリンタ ドライバの動作やスプーラ サービスとのやり取り等も理解されているかと思いますので、今さら私から申し上げられることはないかと思います。
ただ、あえて言うならば、再現する状況と再現しない状況、再現する印刷設定と再現しない印刷設定など、現象を再現させるための最小限のトリガーを見つけることが一番の近道である場合が多いと思います。現象から問題となっている箇所を絞り込むことはある程度は可能ですが、複雑な実装となっているドライバであればあるほどデバッグが大変になりますので、再現させるための最小限のトリガーを見つけ、デバッグ作業を楽チンにしてあげるのがいいかと思います。
なお、印刷結果の問題であれば、最小の再現データを作成するのもひとつの方法です。また、WDK サンプルの "bitmap" ドライバの印字結果と比較するのもいいかと思います。この "bitmap" ドライバは UniDrv ドライバをベースとした、出力結果を bmp ファイル形式にして出力するものです。
"bitmap" はここにあります。
%BASEDIR%\src\print\oemdll\bitmap
続いて、Windows が提供する UniDrv や PScript 等のプリンタ ドライバ用のプラグイン モジュールを開発されている方。
プラグインの単純なコード上の問題であればいいのですが、そうではない場合には少々厄介です。どのようなアプローチが最適かは正直わかりませんが、プリンタドライバがプラグインに対してどのような呼び出しを行っているのかをきちんとおさえておくべきかと思います。
プラグインのサンプル群はこの配下にあります。
%BASEDIR%\src\print\oemdll\
最後に、GPD ファイルや PPD ファイルと言った機種依存ファイルのみを作成されている方。
もしかしたら、モノリシック ドライバでの切り分けより難しいかもしれません。出来ることとすれば、WDK ドキュメントに記載されている機種依存ファイルのフォーマットの記述をよく読み、その通りの動作となっているか?くらいしか確認できることが無いように思います。逆に言うと、機種依存ファイルの記述に不備がなければ、プリンタドライバやアプリケーション、スプーラ サービス等を疑ってしまっていいかと思います。
■ランゲージ モニタ
ランゲージ モニタが存在しなくてもプリンタ ドライバが動作することが大前提ですが、まずはランゲージモニタを使用しない場合でも問題が発生するか確認してみるのがいいかと思います。ランゲージ モニタなしの場合でも再現すれば、当然ランゲージ モニタ以外の問題だと言えますし、逆にランゲージモニタなしで再現しなければランゲージ モニタに起因した問題であると言えるかと思います。
ちなみにですが、ランゲージ モニタなしの状態とするために、デバイスプロパティの [ポート] タブ上にある [双方向サポートを有効にする] チェックボックスを OFF にする方法を思い浮かべる人もいらっしゃるかと思います。間違いではないのですが、WDK ドキュメントにも記載されている通り、この方法でも依然としてランゲージ モニタの OpenPortEx, ClosePort, SendRecvBidiDataFromPort 関数が呼び出されます。そのため、確実に確認するためには、ランゲージ モニタなしの INF ファイルからプリンタ ドライバを再度インストールするのがいいかと思います。
ランゲージ モニタのサンプル "pjlmon" はここにあります。
%BASEDIR%\src\print\monitors\pjlmon
■ポート モニタ
皆さんご想像の通り、まずは異なるポート(ポート モニタ)にて再現するか確認するのがベストです。ローカルポートを使用するのが一番てっとり早いかと思いますが、状況に応じて適切なポート モニタを使用していただければと思います。
また、WDK サンプル "localmon" をベースに開発したポートモニタである場合には、一度 "localmon" と同じ実装に戻して確認してみるのも手だと思います。
ただ、"localmon" の実装そのままですと、Windows 標準のローカル ポート モニタと競合する部分が出てきてしまいますので、"localmon" をインストールして確認する際には注意が必要です。
"localmon" はここにあります。
%BASEDIR%\src\print\monitors\localmon
%BASEDIR%\src\print\monitors\localui
ここまで長々と書かせていただきましたが、実は特別なことは何ひとつ書いていません。ただ、比較対象や切り分け材料を沢山持っていれば、開発中に検出した問題や評価部門から報告された問題に対して、迅速に対応出来ることは確かだと思います。また、そう意識して作業していくことで、どんどん引き出しの中身が増えていき、さらに効率的に作業を進めていくことが出来ると思います。(そして怪しい第六感も養われていくんだと思います。)
今回、サンプル コードをいくつか挙げさせていただきましたが、次回はそれらも含め、%BASEDIR%\src\print にあるプリンタ ドライバやスプーラ コンポーネントのサンプルについて、それぞれ紹介していこうと思います。