以下、本発明の実施の形態を、図面を参照して説明する。
以下で引用される Vista Operating Systemの情報の内、特に詳しい説明を付加していないものに関しては、2009年7月22日現在、Microsoft Developer Network (MSDN)のサイト(http://msdn.micWindows(登録商標)rosoft.com/en−us/library/default.aspx)でインターネット上で公開されている情報であるので、必要以上の説明を省略する。
以下において、USBとは、Universal Serial Busを表し、2009年7月22日現在、Universal Serial Busのサイト(http://www.usb.org/home)上で公開されている情報であるので、必要以上の説明を省略する。
以下において、WSDとは、Web Service on Devicesを表し、2009年7月22日現在、Windows(登録商標) Hardware Developer Centralのサイト(http://www.microsoft.com/whdc/connect/rally/rallywsd.mspx)上で公開されている情報であるので、必要以上の説明を省略する。
以下において、WSDのPrint Service Definition Version 1.0は、2009年7月22日現在、Windows(登録商標) Hardware Developer Centralのサイト(http://www.microsoft.com/whdc/connect/rally/wsdspecs.mspx)上で公開されている米国マイクロソフト社が定義したPrint Serviceであるので、必要以上の説明を省略する。
<実施形態1>
図1は本発明に係る情報処理装置及び周辺装置からなる周辺装置制御システムの一実施形態におけるシステムの構成部分を表すブロック図である。同図において、1、2は情報処理装置であり、一般的なパーソナルコンピュータ(以降、PCと略す場合がある)で構成される。PC1、PC2、PC5は図2(a)で後述するようなハードウェアで構成される。PC1とPC2には、OS(オペレーティングシステム)として米国マイクロソフト社のWindows(登録商標) Vista(登録商標)と同等のOSがインストールされている。PC5には、OSとして米国マイクロソフト社のWindows(登録商標) XP(登録商標)と同等のOSがインストールされている。PC1、PC2、PC5はそれぞれEthernet(登録商標)で構成されるネットワーク4に接続されている。7はUSBインタフェースである。3はプリンタであり、カラーインクジェットプリンタで構成され、本発明における周辺装置の一例としている。プリンタ3はABC社製のKmmnというモデル名のプリンタである。尚、本発明における周辺装置としては、プリンタ、複写機、ファクシミリ、スキャナ、デジタルカメラ、及びこれらの複合機能を備える装置等であってもよい。
プリンタ3は図2(b)で後述するようなハードウェアで構成され、PC1とUSBインタフェース7及びネットワーク4を介して接続されており、互いに双方向通信が可能である。30は図4で後述する印刷可能なアプリケーションであり、Windows(登録商標)用の実行可能形式のファイル(*.EXE)で構成される。36は図4に示すようなランゲージモニタである。
図2はPCとプリンタのハードウェア構成の一例を表すブロック図である。PC1、PC2、PC5は同図の(a)に示すようなハードウェアで構成されている。同図の(a)ではPC1の例で説明する。PC1はランダムアクセスメモリ部(RAM201)、記憶部であるハードディスクドライブ部(HDD202)、入力部の一例であるキーボード部(KBD203)、制御部のCPU204、表示部の一例である表示用ディスプレイ(LCD205)、通信制御部の一例であるネットワークボード(NB207)等を有する。
以上のPC1の構成要素はバス206により互いに接続されている。尚、記憶部は、可搬性CD−ROMまたは内部据付のROMなどであってもよい。図3、図4に示す各モジュール(ソフトウェア)は、HDD202に記憶され、必要に応じてRAM201に読み出されてCPU204により実行される。これにより、CPU204が、図3、図4に示す各モジュール(ソフトウェア)の機能を実現する。
プリンタ3は図2(b)に示すようなハードウェア構成を持つ。図2(b)において、15はマイクロプロセッサ等から構成されるCPUであり、プリンタ3の中央処理装置として、ROM16に記憶されているプログラムに従って、RAM17、通信部18、記録部19、操作部20、表示部21を制御する。ROM16にはプリンタドライバ50(図4で後述する)の制御に従ってプリンタ3が記録(印刷)処理や、印刷動作の状態をPC1へ通知する処理を行うプログラムが記憶されている。RAM17は主にPC1から送られて、それをもとに記録部19によって印刷される印字データが一時的に記憶される。通信部18にはUSBインタフェース7やネットワーク4用の接続ポート等が含まれており、USBやEthernet(登録商標)通信を制御する。記録部19は、インクジェット方式の記録ヘッド、各カラーインク、キャリッジ、記録紙搬送機構等から構成される記録ユニットと、前記印字データをもとに前記記録ヘッドにて印字用パルスを発生させる為のASIC等から構成される電気回路とから構成される。印刷可能なアプリケーション上での印刷操作によって、アプリケーションで開かれているファイルの表示内容(画像データ)が、EMF形式のスプールファイルとしてPC1のHDD202に一時的に格納される。そして、プリンタドライバ50を介してプリンタ3制御用コマンドを含む印字データに変換された後、USBインタフェース7またはネットワーク4を介してプリンタ3に送られる。プリンタ3にて受信された印字データは、記録部19で印字用パルスに変換されて、記録紙上に印刷される。20は操作部であり、電源ボタン、リセットボタン等の各種ボタンから構成され、プリンタ3を操作することができる。21は表示部であり、タッチパネルの液晶ディスプレイで構成され、プリンタ3の状態の表示や、各種設定の表示、入力等を行うことができる。
図3はPCのソフトウェア構成を表す図である。同図において、92はEthernet(登録商標)を制御するEthernet(登録商標)制御スタックである。91はIP Networkを制御するIP Network制御スタックである。90はWSDを制御するWSD制御スタックである。89はIHVの独自プロトコルを制御するIHVネイティブプロトコル制御スタックである。88はネットワークのプラグ アンド プレイ(以降、N−PnPと略す場合がある)を制御するN−PnP制御スタックである。尚、ネットワーク接続デバイスに対するサポートを提供する、プラグ アンド プレイの一連の拡張機能としてWindows(登録商標) Vista OSに標準搭載されている機能として、Plug and Play Extensions(PnP−X)が存在するが、本実施例ではこれと同等の機能として前記N−PnPを利用する例で説明する。後述するWSDを制御するWSDAPIsは、WSD制御スタック90に含まれる。後述するIHVの独自プロトコルを制御するAPIsは、IHVネイティブプロトコル制御スタック89に含まれる。85はデバイスドライバ群であり、OSに標準で同梱されている標準ドライバ群87とIHVから提供されるIHV製ドライバ群86から構成される。84はアプリケーション/DDIインタフェースであり、Application Programing Interface(API)、Device Driver Interface(DDI)から構成される。30は図4で後述する印刷可能なアプリケーションである。82はアプリケーション群であり、アプリケーション30等から構成される。この図ではPC1の例で説明したが、例えば、PC5のようにPCにインストールされているOSが米国マイクロソフト社のWindows(登録商標) XPの場合、WSD制御スタック90が存在せず、IHVネイティブプロトコル制御スタック89だけが存在する。この場合、このPCではWSDのPrint Serviceを利用した印刷を行うことができない為、IHVの独自プロトコルを利用して印刷を行う。
図4はPCにおけるプリンタドライバの構成を表す図である。同図において、50はPC1にインストールされているプリンタ3用のプリンタドライバであり、33〜36、39の複数のモジュールから構成される。30は印刷可能なアプリケーションであり、例えば、OSに標準で同梱されているテキストエディタであるNotepad(Notepad.exe)等に相当する。31はGraphics Device Interface(GDI)であり、OSの一部である。32はプリンタキューであり、スプーラ40の一部として構成され、印刷ジョブがキューイングされる。キューイングされた印刷ジョブはプリンタキューフォルダ(図は省略)に表示される。33はプリントプロセッサであり、印刷レイアウトの変更や印刷画像に対する特殊処理が行われる。34はグラフィックスドライバであり、プリンタドライバの画像処理のコアとして、GDI31から送られて来る描画命令をもとに印刷用の画像処理を行い、印刷制御コマンドを作成する。35はUIモジュールであり、プリンタドライバのユーザインタフェースの提供及び制御を行う。36はランゲージモニタであり、データの通信I/Fとしてデータの送受信を制御する。39はステータスモニタであり、プリンタ3のインクの残量や、警告、エラー等の状態を表示する。37はポートモニタであり、ランゲージモニタ36から送られて来るデータを適切なポートに対して送信したり、プリンタ3から送られて来るデータをクラスドライバ38を介して受信したりする処理を行う。特に、USBを制御するポートモニタのことをUSBMon、WSDのPrint Serviceを制御するポートモニタのことをWSDMonと呼ぶ。38はクラスドライバであり、最もポートに近いローレベルのモジュールである。本発明ではWSDやIHVの独自プロトコルのプリンタクラスのドライバに相当し、ポート(本発明ではUSBまたはネットワークポート)を制御する。プリンタドライバ50はプリンタ3の製造元であるABC社製のものである。
図5は印刷時のコーリングシーケンスを表す図である。同図は従来例を表す図である。
今、プリンタ3は複数の印刷ジョブを受け付けることができず、1つの印刷ジョブだけを受け付けることができる、と仮定する。同図において、ユーザがアプリケーション30から印刷を開始すると(S501)、OSはスプーラ40のStartPrintJob( )関数をコールする。この関数内において(S502)、まず、スプーラ40はランゲージモニタ36のLM_StartDocPort( )関数をコールする(S503)。この関数内において(S504)、ランゲージモニタ36はポートモニタ37のPM_StartDocPort( )関数をコールする(S505)。この関数内において(S506)、ポートモニタ37は必要に応じて適当な処理を行い(S507)、戻り値pmRetにその処理の結果を代入してこの関数を終了し、呼び出し元に戻る(S508)。通常、正常に処理された場合はpmRetにTRUEが代入され、それ以外の場合はpmRetにFALSEが代入される。ランゲージモニタ36は、PM_StartDocPort( )関数の戻り値を戻り値lmRetに代入して(S505)、LM_StartDocPort( )関数を終了し、呼び出し元に戻る(S509)。スプーラ40は、このLM_StartDocPort( )関数の戻り値をspRetに代入する(S503)。spRetがTRUEではない(FALSEである)場合(S510)、S503に戻り、スプーラ40はランゲージモニタ36のLM_StartDocPort( )関数をコールする。S510においてspRetがTRUEの場合、次に、スプーラ40はランゲージモニタ36のLM_WritePort( )関数をコールする(S511)。この関数内において(S512)、ランゲージモニタ36はポートモニタ37のPM_WritePort( )関数をコールする(S513)。この関数内において(S514)、ポートモニタ37はWSDを制御するWSDAPIsのCreatePrintJob( )関数をコールする(S515)。この関数内において、PC1はWSDのPrint ServiceのCreatePrintJobRequestをプリンタ3に発行する。このCreatePrintJobRequestの中に、この印刷ジョブに関する詳細情報が含まれている。このCreatePrintJobRequestに対して、プリンタ3はCreatePrintJobResponseまたは拒絶応答であるFault(ServerErrorNotAcceptingJobs)をPC1に返す(S516)。例えば、プリンタ3が印刷ジョブを受け付けることができ、その印刷ジョブを受け付けた場合、プリンタ3はCreatePrintJobResponseをPC1に返す。プリンタ3が印刷ジョブを受け付けることができない場合、プリンタ3はFault(ServerErrorNotAcceptingJobs)をPC1に返す。PC1がCreatePrintJobResponseを受け取ると、CreatePrintJob( )関数の戻り値にTRUEが代入されて、呼び出し元に戻る(S515)。PC1がFault(ServerErrorNotAcceptingJobs)を受け取ると、CreatePrintJob( )関数の戻り値にFALSEが代入されて、呼び出し元に戻る(S515)。ポートモニタ37は、戻り値pmRetにCreatePrintJob( )関数の戻り値を代入して(S515)、PM_WritePort( )関数を終了し、呼び出し元に戻る(S517)。ランゲージモニタ36は、PM_WritePort( )関数の戻り値を戻り値lmRetに代入して(S513)、LM_WritePort( )関数を終了し、呼び出し元に戻る(S518)。スプーラ40は、このLM_WritePort( )関数の戻り値をspRetに代入する(S511)。spRetがTRUEではない(FALSEである)場合(S519)、S511に戻り、スプーラ40はランゲージモニタ36のLM_WritePort( )関数をコールする。S519においてspRetがTRUEの場合、スプーラ40は引き続き図7に示す印刷データの送信処理を行う。最後に、スプーラ40はランゲージモニタ36のLM_EndDocPort( )関数をコールする(S520)。この関数内において(S521)、ランゲージモニタ36はポートモニタ37のPM_EndDocPort( )関数をコールする(S522)。この関数内において(S523)、ポートモニタ37は必要に応じて適当な処理を行い(S524)、戻り値pmRetにその処理の結果を代入してこの関数を終了し、呼び出し元に戻る(S525)。通常、正常に処理された場合はpmRetにTRUEが代入され、それ以外の場合はpmRetにFALSEが代入される。ランゲージモニタ36は、PM_EndDocPort( )関数の戻り値を戻り値lmRetに代入して(S522)、LM_EndDocPort( )関数を終了し、呼び出し元に戻る(S526)。スプーラ40は、このLM_EndDocPort( )関数の戻り値をspRetに代入し(S520)、StartPrintJob( )関数を終了し、呼び出し元に戻る(S527)。このように、従来例では、複数のPCから発行された印刷ジョブ全てを、プリンタ3が、印刷ジョブが発行された順に受け付けることができないので、後から発行された印刷ジョブが先に印刷されてしまう、というようなケースが発生し、問題となっている。
図6、図16は印刷時のコーリングシーケンスを表す図である。これらの図は本発明の特徴を最もよく表す図の内の1つである。今、プリンタ3は、1つの印刷ジョブだけを処理して印刷を実行することができる、というような廉価版のプリンタであるものの、複数の印刷ジョブを受け付けることができ、その内の1つの印刷ジョブを処理して印刷を実行することができる、と仮定する。
図6において、ユーザがアプリケーション30から印刷を開始すると(S601)、OSはスプーラ40のStartPrintJob( )関数をコールする。この関数内において(S602)、まず、スプーラ40はランゲージモニタ36のLM_StartDocPort( )関数をコールする(S603)。この関数内において(S604)、ランゲージモニタ36はlmMultipleJobsにFALSEを代入して初期化する(S605)。このlmMultipleJobsはランゲージモニタ36内で使用されるフラグであり、プリンタ3が複数の印刷ジョブを受け付けて順次処理する機能を備えている場合にTRUEがセットされ、それ以外の場合にFALSEがセットされる。ランゲージモニタ36はlmRetryに0を代入して初期化する(S606)。このlmRetryはランゲージモニタ36内で使用される変数であり、PC1がプリンタ3に発行する印刷ジョブ要求のリトライ回数を表す。ランゲージモニタ36はlmReceivedIdに“None”を代入して初期化する(S607)。このlmReceivedIdには、図16で後述するS1607、S1623において、プリンタ3が印刷ジョブ要求の予約を受け付けた時に発行する印刷予約IDが代入される。その後、ランゲージモニタ36は図5のS505〜S509と同じ処理を行う。スプーラ40は、S509と同じ処理で返されたLM_StartDocPort( )関数の戻り値をspRetに代入する(S603)。spRetがTRUEではない(FALSEである)場合(S608)、S603に戻り、スプーラ40はランゲージモニタ36のLM_StartDocPort( )関数をコールする。次に、S608においてspRetがTRUEの場合、図16のS1601へ進む。図16において、印刷ジョブ要求の発行、予約処理に関して後述する。最後に、スプーラ40はランゲージモニタ36のLM_EndDocPort( )関数をコールする(S609)。この関数内において(S610)、ランゲージモニタ36はlmMultipleJobsにFALSEを代入して初期化する(S611)。ランゲージモニタ36はlmRetryに0を代入して初期化する(S612)。ランゲージモニタ36はlmReceivedIdに“None”を代入して初期化する(S613)。その後、ランゲージモニタ36は図5のS522〜S525と同じ処理を行う。ランゲージモニタ36はLM_EndDocPort( )関数を終了し、呼び出し元に戻る(S614)。この時、ランゲージモニタ36は、S522と同じ処理により、PM_EndDocPort( )関数の戻り値をlmRetに代入し、このlmRetの値をLM_EndDocPort( )関数の戻り値として返す(S614)。スプーラ40は、このLM_EndDocPort( )関数の戻り値をspRetに代入し(S609)、StartPrintJob( )関数を終了し、呼び出し元に戻る(S615)。
図16において、スプーラ40はランゲージモニタ36のLM_WritePort( )関数をコールする(S1602)。この関数内において(S1603)、ランゲージモニタ36はlmRetryとlmMultipleJobsの値を確認(S1604)する。lmRetryが0より大きく、かつ、lmMultipleJobsがTRUEの場合、S1605へ進む。lmRetryが0またはlmMultipleJobsがTRUEではない(FALSEである)場合、S1609へ進む。S1605において、ランゲージモニタ36は、引数にans:ABCCommandをセットして、WSDを制御するWSDAPIsのGetPrinterElements( )関数をコールする。この関数内において、PC1はWSDのPrint ServiceのGetPrinterElementsRequestをプリンタ3に発行する。このGetPrinterElementsRequestに対して、プリンタ3はGetPrinterElementsResponseをPC1に返す(S1606)。PC1がGetPrinterElementsResponseを受け取ると、GetPrinterElements( )関数の戻り値にTRUEが代入されて、呼び出し元に戻る(S1605)。PC1がプリンタ3に対してGetPrinterElementsRequestを発行してからある一定時間の間に、GetPrinterElementsResponseを受け取らなかった場合、GetPrinterElements( )関数の戻り値にFALSEが代入されて、呼び出し元に戻る(S1605)。S1605において、ランゲージモニタ36はGetPrinterElements( )関数の戻り値をlmRetに代入する。尚、ここでは、GetPrinterElements( )関数の戻り値としてFALSEが返されるようなエラーケースの説明は省略する。S1605でPC1が発行するGetPrinterElementsRequestと、それに対してプリンタ3が返すGetPrinterElementsResponseの詳細に関しては図9、図10で説明する。ランゲージモニタ36は、S1605のGetPrinterElements( )関数の引数として渡されたGetPrinterElementsResponse内の<ans:ReceivedId>要素912または1011にセットされている値を、lmReceivedIdに代入する(S1607)。ランゲージモニタ36は、lmReceivedIdの値を確認し、「None」の場合(S1627)、lmRetryに0を代入して印刷ジョブ要求のリトライ回数を初期化する(S1628)。lmReceivedIdの値が「None」ではない場合(S1629)、ランゲージモニタ36は、lmRetryに1を足した値をlmRetryに代入して、印刷ジョブ要求のリトライ回数を更新する(S1608)。S1609において、ランゲージモニタ36はポートモニタ37のPM_WritePort( )関数をコールする。この関数内において(S1610)、ポートモニタ37はWSDを制御するWSDAPIsのCreatePrintJob( )関数をコールする(S1611)。この関数内において、PC1はWSDのPrint ServiceのCreatePrintJobRequestをプリンタ3に発行する。このCreatePrintJobRequestの中に、この印刷ジョブに関する詳細情報が含まれている。このCreatePrintJobRequestに対して、プリンタ3はCreatePrintJobResponseまたは拒絶応答であるFault(ServerErrorNotAcceptingJobs)をPC1に返す(S1612)。例えば、プリンタ3が印刷ジョブを受け付けて、この印刷ジョブを実行することができる状態の時に、その印刷ジョブを受け付けた場合、プリンタ3はCreatePrintJobResponseをPC1に返す。プリンタ3が印刷ジョブを受け付けることはできるが、この印刷ジョブを実行することができない状態の時に、その印刷ジョブを受け付けた場合、プリンタ3はFault(ServerErrorNotAcceptingJobs)をPC1に返す。また、プリンタ3が印刷ジョブを受け付けることができない場合も、プリンタ3はFault(ServerErrorNotAcceptingJobs)をPC1に返す。PC1がCreatePrintJobResponseを受け取ると、CreatePrintJob( )関数の戻り値にTRUEが代入されて、呼び出し元に戻る(S1613)。PC1がFault(ServerErrorNotAcceptingJobs)を受け取ると、CreatePrintJob( )関数の戻り値にFALSEが代入されて、呼び出し元に戻る(S1611)。ポートモニタ37は、戻り値pmRetにCreatePrintJob( )関数の戻り値を代入して(S1611)、PM_WritePort( )関数を終了し、呼び出し元に戻る(S1613)。ランゲージモニタ36は、PM_WritePort( )関数の戻り値を戻り値lmRetに代入する(S1609)。ランゲージモニタ36は、lmRetの値を確認し(S1614)、TRUEの場合、S1625へ進み、TRUEではない(FALSEである)場合、lmRetryの値を確認する(S1615)。S1615において、lmRetryが0の場合、ランゲージモニタ36は、引数にwprt:PrinterDescriptionをセットして、WSDを制御するWSDAPIsのGetPrinterElements( )関数をコールする(S1616)。この関数内において、PC1はWSDのPrint ServiceのGetPrinterElementsRequestをプリンタ3に発行する。このGetPrinterElementsRequestの中に、プリンタ3が複数の印刷ジョブを受け付けることができるか否かを表す<ans:MultipleJobsControl>要素802(図8(b)で後述)を取得する為に必要な<wprt:Name>wprt:PrinterDescription</wprt:Name>要素801(図8(a)で後述)が含まれている。このGetPrinterElementsRequestに対して、プリンタ3はGetPrinterElementsResponseをPC1に返す(S1617)。PC1がGetPrinterElementsResponseを受け取ると、GetPrinterElements( )関数の戻り値にTRUEが代入されて、呼び出し元に戻る(S1616)。PC1がプリンタ3に対してGetPrinterElementsRequestを発行してからある一定時間の間に、GetPrinterElementsResponseを受け取らなかった場合、GetPrinterElements( )関数の戻り値にFALSEが代入されて、呼び出し元に戻る(S1616)。S1616において、ランゲージモニタ36はGetPrinterElements( )関数の戻り値をlmRetに代入する。尚、ここでは、GetPrinterElements( )関数の戻り値としてFALSEが返されるようなエラーケースの説明は省略する。
ランゲージモニタ36は、GetPrinterElements( )関数の引数として渡されたGetPrinterElementsResponse内の<ans:MultipleJobsControl>要素802にセットされている値を確認する(S1618)。S1618において、<ans:MultipleJobsControl>要素802に「true」がセットされている場合、lmMultipleJobsにTRUEを代入する(S1619)。S1615において、lmRetryが0以外(S1608、S1624でlmRetryに代入される値は0以上の整数なので、実際には0より大きい整数)の場合、S1620へ進む。S1620において、lmMultipleJobsがTRUEの場合、ランゲージモニタ36は、引数にans:ABCCommandをセットして、WSDを制御するWSDAPIsのGetPrinterElements( )関数をコールする(S1621)。この関数内において、PC1はWSDのPrint ServiceのGetPrinterElementsRequestをプリンタ3に発行する。このGetPrinterElementsRequestに対して、プリンタ3はGetPrinterElementsResponseをPC1に返す(S1622)。PC1がGetPrinterElementsResponseを受け取ると、GetPrinterElements( )関数の戻り値にTRUEが代入されて、呼び出し元に戻る(S1621)。PC1がプリンタ3に対してGetPrinterElementsRequestを発行してからある一定時間の間に、GetPrinterElementsResponseを受け取らなかった場合、GetPrinterElements( )関数の戻り値にFALSEが代入されて、呼び出し元に戻る(S1621)。S1621において、ランゲージモニタ36はGetPrinterElements( )関数の戻り値をlmRetに代入する。尚、ここでは、GetPrinterElements( )関数の戻り値としてFALSEが返されるようなエラーケースの説明は省略する。S1621でPC1が発行するGetPrinterElementsRequestと、それに対してプリンタ3が返すGetPrinterElementsResponseの詳細に関しては図9、図10で説明する。ランゲージモニタ36は、S621のGetPrinterElements( )関数の引数として渡されたGetPrinterElementsResponse内の<ans:ReceivedId>要素912または1011にセットされている値、すなわち印刷予約IDを、lmReceivedIdに代入する(S1623)。ランゲージモニタ36は、lmReceivedIdの値を確認し、「None」の場合(S1630)、lmRetryに0を代入して印刷ジョブ要求のリトライ回数を初期化する(S1631)。lmReceivedIdの値が「None」ではない場合(S1632)、ランゲージモニタ36は、lmRetryに1を足した値をlmRetryに代入して、印刷ジョブ要求のリトライ回数を更新する(S1624)。S1620において、lmMultipleJobsがTRUEではない(FALSEである)場合、S1625へ進む。
S1625において、ランゲージモニタ36はLM_WritePort( )関数を終了し、呼び出し元に戻る。この時、このLM_WritePort( )関数の戻り値として、lmRetの値が返される。スプーラ40は、このLM_WritePort( )関数の戻り値をspRetに代入する(S1602)。spRetがTRUEではない(FALSEである)場合(S1626)、S1602に戻り、スプーラ40はランゲージモニタ36のLM_WritePort( )関数をコールする。S1626においてspRetがTRUEの場合、スプーラ40は引き続き図7に示す印刷データの送信処理を行う。このように、本発明によれば、たとえプリンタが1つの印刷ジョブだけを処理して印刷を実行するような廉価版のプリンタであっても、複数のPCから発行された印刷ジョブをこのプリンタが順次受け付け、受け付けた順序で印刷を実行することができるので、後から発行された印刷ジョブが先に印刷されてしまう、というようなケース(問題)が発生することが無い。これにより、印刷ジョブが発行された順序に従って正しく印刷される、優れた周辺装置制御システムを実現することができる。
図7は印刷時のコーリングシーケンスを表す図である。図5のS519または図16のS1626において、spRetがTRUEの場合、図7において、スプーラ40はランゲージモニタ36のLM_WritePort( )関数をコールする(S701)。この関数内において(S702)、ランゲージモニタ36はポートモニタ37のPM_WritePort( )関数をコールする(S703)。この関数内において(S704)、ポートモニタ37はWSDを制御するWSDAPIsのSendDocument( )関数をコールする(S705)。この関数内において、PC1はWSDのPrint ServiceのSendDocumentRequestをプリンタ3に発行し、MTOM(Message Transmission Optimization Mechanism)メッセージエンコーディングを使って、印刷制御コマンドで構成された印刷データを、SOAPメッセージを使用して未処理のバイトとしてプリンタ3に送信する。プリンタ3は、SendDocumentRequestに対してSendDocumentResponseをPC1に返す(S706)。PC1がSendDocumentResponseを受け取り、全ての印刷データをプリンタ3に送信し終わると、SendDocument( )関数の戻り値にTRUEが代入されて、呼び出し元に戻る(S705)。PC1がSendDocumentRequestを発行した時、あるいはSendDocumentResponseを受け取った時に、何らかのエラーが発生した場合、SendDocument( )関数の戻り値にFALSEが代入されて、呼び出し元に戻る(S705)。ポートモニタ37は、戻り値pmRetにSendDocument( )関数の戻り値を代入して(S705)、PM_WritePort( )関数を終了し、呼び出し元に戻る(S707)。ランゲージモニタ36は、PM_WritePort( )関数の戻り値を戻り値lmRetに代入して(S703)、LM_WritePort( )関数を終了し、呼び出し元に戻る(S708)。スプーラ40は、このLM_WritePort( )関数の戻り値をspRetに代入する(S701)。spRetがTRUEではない(FALSEである)場合(S709)、S701に戻り、スプーラ40はランゲージモニタ36のLM_WritePort( )関数をコールする。S709においてspRetがTRUEの場合、図5のS520または図6のS609へ進む。
図20はランゲージモニタ36におけるLM_WritePort( )関数の処理を表すフローチャートである。同図は本発明の特徴を最もよく表す図の内の1つである。図20のフローに係るプログラムは、HDD202に記憶されており、RAM201に読み出され、CPU204により実行される。図16において、スプーラ40がランゲージモニタ36のLM_WritePort( )関数をコールすると、図20において、ランゲージモニタ36がLM_WritePort( )関数の処理を開始する(S2001)。ランゲージモニタ36はlmRetryとlmMultipleJobsの値を確認し(S2002)、lmRetryが0より大きく、かつ、lmMultipleJobsがTRUEの場合ステップS2004へ進み、lmRetryが0またはlmMultipleJobsがTRUEではない(FALSEである)場合ステップS2009へ進む(S2003)。ステップS2004において、ランゲージモニタ36は、引数にans:ABCCommandをセットして、WSDを制御するWSDAPIsのGetPrinterElements( )関数をコールする。この関数内において、PC1はWSDのPrint ServiceのGetPrinterElementsRequestをプリンタ3に発行する(S2004)。このGetPrinterElementsRequestに対して、プリンタ3はGetPrinterElementsResponseをPC1に返す(図16のS1606、図13のステップS1319)。PC1がGetPrinterElementsResponseを受け取ると、GetPrinterElements( )関数の戻り値にTRUEが代入されて、呼び出し元であるランゲージモニタ36に戻る(S2004)。PC1がプリンタ3に対してGetPrinterElementsRequestを発行してからある一定時間の間に、GetPrinterElementsResponseを受け取らなかった場合、GetPrinterElements( )関数の戻り値にFALSEが代入されて、呼び出し元であるランゲージモニタ36に戻る(S2004)。ランゲージモニタ36はGetPrinterElements( )関数の戻り値をlmRetに代入する(S2004)。尚、ここでは、GetPrinterElements( )関数の戻り値としてFALSEが返されるようなエラーケースの説明は省略する。S2004でPC1が発行するGetPrinterElementsRequestと、それに対してプリンタ3が返すGetPrinterElementsResponseの詳細に関しては図9、図10で説明する。ランゲージモニタ36は、S2004のGetPrinterElements( )関数の引数として渡されたGetPrinterElementsResponse内の<ans:ReceivedId>要素912または1011にセットされている値を、lmReceivedIdに代入する(S2005)。ランゲージモニタ36は、lmReceivedIdの値を確認し(S2006)、「None」の場合ステップS2007へ進み、「None」ではない場合ステップS2008へ進む。ステップS2007において、ランゲージモニタ36は、lmRetryに0を代入して印刷ジョブ要求のリトライ回数を初期化する。ステップS2008において、ランゲージモニタ36は、lmRetryに1を足した値をlmRetryに代入して、印刷ジョブ要求のリトライ回数を更新する。S2009において、ランゲージモニタ36はポートモニタ37のPM_WritePort( )関数をコールする。この関数内におけるポートモニタ37の処理は、図21の(a)で後述する。ランゲージモニタ36は、PM_WritePort( )関数の戻り値を戻り値lmRetに代入する(S2009)。ランゲージモニタ36は、lmRetの値を確認し(S2010)、TRUEの場合ステップS2021へ進み、TRUEではない(FALSEである)場合ステップS2011へ進む。
ステップS2011において、ランゲージモニタ36は、lmRetryの値を確認し、0の場合ステップS2012へ進み、0以外(S2008、S2020でlmRetryに代入される値は0以上の整数なので、実際には0より大きい整数)の場合ステップS2015へ進む。ステップS2112において、ランゲージモニタ36は、引数にwprt:PrinterDescriptionをセットして、WSDを制御するWSDAPIsのGetPrinterElements( )関数をコールする。この関数内において、PC1はWSDのPrint ServiceのGetPrinterElementsRequestをプリンタ3に発行する(S2012)。このGetPrinterElementsRequestの中に、プリンタ3が複数の印刷ジョブを受け付けることができるか否かを表す<ans:MultipleJobsControl>要素802(図8(b)で後述)を取得する為に必要な<wprt:Name>wprt:PrinterDescription</wprt:Name>要素801(図8(a)で後述)が含まれている。このGetPrinterElementsRequestに対して、プリンタ3はGetPrinterElementsResponseをPC1に返す(図16のS1617、図13のステップS1319)。PC1がGetPrinterElementsResponseを受け取ると、GetPrinterElements( )関数の戻り値にTRUEが代入されて、呼び出し元であるランゲージモニタ36に戻る(S2012)。PC1がプリンタ3に対してGetPrinterElementsRequestを発行してからある一定時間の間に、GetPrinterElementsResponseを受け取らなかった場合、GetPrinterElements( )関数の戻り値にFALSEが代入されて、呼び出し元であるランゲージモニタ36に戻る(S2012)。ランゲージモニタ36はGetPrinterElements( )関数の戻り値をlmRetに代入する(2012)。尚、ここでは、GetPrinterElements( )関数の戻り値としてFALSEが返されるようなエラーケースの説明は省略する。ランゲージモニタ36は、GetPrinterElements( )関数の引数として渡されたGetPrinterElementsResponse内の<ans:MultipleJobsControl>要素802にセットされている値を確認する(S2013)。S2013において、<ans:MultipleJobsControl>要素802に「true」がセットされている場合ステップS2014へ進み、それ以外の場合ステップS2015へ進む。ステップS2014において、ランゲージモニタ36はlmMultipleJobsにTRUEを代入する。ステップS2015において、ランゲージモニタ34はlmMultipleJobsの値を確認し、TRUEの場合ステップS2016へ進み、TRUEではない(FALSEである)場合ステップS2021へ進む。ステップS2016において、ランゲージモニタ36は、引数にans:ABCCommandをセットして、WSDを制御するWSDAPIsのGetPrinterElements( )関数をコールする。この関数内において、PC1はWSDのPrint ServiceのGetPrinterElementsRequestをプリンタ3に発行する。このGetPrinterElementsRequestに対して、プリンタ3はGetPrinterElementsResponseをPC1に返す(図16のS1622、図13のステップS1319)。PC1がGetPrinterElementsResponseを受け取ると、GetPrinterElements( )関数の戻り値にTRUEが代入されて、呼び出し元であるランゲージモニタ36に戻る(S2016)。PC1がプリンタ3に対してGetPrinterElementsRequestを発行してからある一定時間の間に、GetPrinterElementsResponseを受け取らなかった場合、GetPrinterElements( )関数の戻り値にFALSEが代入されて、呼び出し元であるランゲージモニタ36に戻る(S2016)。ランゲージモニタ36はGetPrinterElements( )関数の戻り値をlmRetに代入する(S2016)。尚、ここでは、GetPrinterElements( )関数の戻り値としてFALSEが返されるようなエラーケースの説明は省略する。ステップS2016でPC1が発行するGetPrinterElementsRequestと、それに対してプリンタ3が返すGetPrinterElementsResponseの詳細に関しては図9、図10で説明する。ランゲージモニタ36は、ステップS2016のGetPrinterElements( )関数の引数として渡されたGetPrinterElementsResponse内の<ans:ReceivedId>要素912または1011にセットされている値、すなわち印刷予約IDを、lmReceivedIdに代入する(S2017)。ランゲージモニタ36は、lmReceivedIdの値を確認し(S2018)、「None」の場合ステップS2019へ進み、「None」ではない場合ステップS2020へ進む。ステップS2019において、ランゲージモニタ36は、lmRetryに0を代入して印刷ジョブ要求のリトライ回数を初期化する。ステップS2020において、ランゲージモニタ36は、lmRetryに1を足した値をlmRetryに代入して、印刷ジョブ要求のリトライ回数を更新する。ステップS2021において、ランゲージモニタ36は、LM_WritePort( )関数の戻り値として、lmRetをスプーラ40にリターンして返し、LM_WritePort( )関数の処理を終了して、呼び出し元であるスプーラ40に戻る(S2022)。
図21はポートモニタ37におけるPM_WritePort( )関数の処理を表すフローチャートである。図21のフローに係るプログラムは、HDD202に記憶されており、RAM201に読み出され、CPU204により実行される。図20のステップS2009において、ランゲージモニタ36がポートモニタ37のPM_WritePort( )関数をコールすると、図21の(a)において、ポートモニタ37がPM_WritePort( )関数の処理を開始する(S2101)。ポートモニタ37がCreatePrintJobの状況を確認し(S2102)、CreatePrintJobRequestを発行して、それに対する応答としてCreatePrintJobResponseを既に受信済みの場合(S2103)、ステップS2105へ進み、それ以外の場合、ステップS2104へ進む。ステップS2105において、ポートモニタ37は戻り値pmRetにTRUEを代入する。ステップS2104において、ポートモニタ37はWSDを制御するWSDAPIsのCreatePrintJob( )関数をコールする。この関数内において、PC1はWSDのPrint ServiceのCreatePrintJobRequestをプリンタ3に発行する(S2104)。このCreatePrintJobRequestの中に、この印刷ジョブに関する詳細情報が含まれている。このCreatePrintJobRequestに対して、プリンタ3はCreatePrintJobResponseまたは拒絶応答であるFault(ServerErrorNotAcceptingJobs)をPC1に返す(図16のS1612)。例えば、プリンタ3が印刷ジョブを受け付けて、この印刷ジョブを実行することができる状態の時に、その印刷ジョブを受け付けた場合、プリンタ3はCreatePrintJobResponseをPC1に返す(図16のS1612)。プリンタ3が印刷ジョブを受け付けることはできるが、この印刷ジョブを実行することができない状態の時に、その印刷ジョブを受け付けた場合、プリンタ3はFault(ServerErrorNotAcceptingJobs)をPC1に返す(図16のS1612)。
また、プリンタ3が印刷ジョブを受け付けることができない場合も、プリンタ3はFault(ServerErrorNotAcceptingJobs)をPC1に返す(図16のS1612)。PC1がCreatePrintJobResponseを受け取ると、CreatePrintJob( )関数の戻り値にTRUEが代入されて、呼び出し元であるポートモニタ37に戻る(S2104)。PC1がFault(ServerErrorNotAcceptingJobs)を受け取ると、CreatePrintJob( )関数の戻り値にFALSEが代入されて、呼び出し元であるポートモニタ37に戻る(S2104)。ポートモニタ37は、戻り値pmRetにCreatePrintJob( )関数の戻り値を代入する(S2104)。ポートモニタ37は、PM_WritePort( )関数の戻り値として、pmRetをランゲージモニタ36にリターンして返し(S2106)、PM_WritePort( )関数の処理を終了して、呼び出し元であるランゲージモニタ36に戻る(S2107)。
図7のS703において、ランゲージモニタ36がポートモニタ37のPM_WritePort( )関数をコールすると、図21の(b)において、ポートモニタ37がPM_WritePort( )関数の処理を開始する(S2108)。ポートモニタ37がSendDocumentの状況を確認し(S2109)、SendDocumentRequestを発行して、それに対する応答としてSendDocumentResponseを既に受信済みの場合(S2110)、ステップS2112へ進み、それ以外の場合、ステップS2111へ進む。ステップS2112において、ポートモニタ37は戻り値pmRetにTRUEを代入する。ステップS2111において、ポートモニタ37はWSDを制御するWSDAPIsのSendDocument( )関数をコールする(図7のS705)。この関数内において、PC1はWSDのPrint ServiceのSendDocumentRequestをプリンタ3に発行し、MTOM(Message Transmission Optimization Mechanism)メッセージエンコーディングを使って、印刷制御コマンドで構成された印刷データを、SOAPメッセージを使用して未処理のバイトとしてプリンタ3に送信する(S2111)。プリンタ3は、SendDocumentRequestに対してSendDocumentResponseをPC1に返す(図7のS706)。PC1がSendDocumentRequestを発行した時、あるいはSendDocumentResponseを受け取った時に、何らかのエラーが発生した場合、SendDocument( )関数の戻り値にFALSEが代入されて、呼び出し元に戻る(S2111)。ポートモニタ37は、戻り値pmRetにSendDocument( )関数の戻り値を代入する(S2111)。PC1がSendDocumentResponseを受け取り、全ての印刷データをプリンタ3に送信し終わると、SendDocument( )関数の戻り値にTRUEが代入されて、呼び出し元であるポートモニタ37に戻る(S2113)。ポートモニタ37は、戻り値pmRetにSendDocument( )関数の戻り値を代入する(S2113)。ポートモニタ37は、PM_WritePort( )関数の戻り値として、pmRetをランゲージモニタ36にリターンして返し(S2114)、PM_WritePort( )関数の処理を終了して、呼び出し元であるランゲージモニタ36に戻る(S2115)。
図8〜図10はGetPrinterElementsの内容を表す図、図11はCreatePrintJobの内容を表す図である。GetPrinterElementsオペレーションは、通常、プリンタに関する情報を取得する為に利用される。CreatePrintJobオペレーションは、印刷ジョブの開始要求である。以降において、GetPrinterElements、CreatePrintJobの一般的な内容に関しては、WSDのPrint Service Definition Version 1.0で定義されているので、ここではその説明を省略する。
図11はCreatePrintJobの内容を表す図であり、(a)はジョブ要求であるCreatePrintJobRequest、(b)はCreatePrintJobResponseをそれぞれ表す。
図11(a)はCreatePrintJobRequestを表す図である。同図に示すCreatePrintJobRequestは、PC1からプリンタ3に発行されるものの一例である。同図において、1105は、WSDのPrint Serviceの名前空間を名前空間名wprtと定義している記述である。名前空間名wprtの有効範囲内は、WSDのPrint Service Definition Version 1.0で定義されているパブリック情報である。以降の図においても、名前空間名wprtは同様な取り扱いとなり、名前空間名wprtの有効範囲内は、WSDのPrint Service Definition Version 1.0で定義されているパブリック情報を表す。1101は<wprt:JobDescription>要素であり、前記パブリック情報であり、この中に印刷ジョブに関する情報が含まれている。1102は<wprt:JobName>要素であり、前記パブリック情報であり、印刷ジョブ名がセットされる。この例では、「Photo2」という印刷ジョブ名がセットされている状態を表す。1103は<wprt:JobOriginatingUserName>要素であり、前記パブリック情報であり、この印刷ジョブを発行したユーザ名がセットされる。この例では、「Natsu」というユーザ名がセットされている状態を表す。
図11(b)はCreatePrintJobResponseを表す図である。同図に示すCreatePrintJobResponseは、プリンタ3からPC1に返されるものの一例である。同図において、1104は<wprt:JobId>要素であり、前記パブリック情報であり、PC1から発行されたCreatePrintJobRequestで要求された印刷ジョブに対して、プリンタ3がこの印刷ジョブを受け付けた時に、この印刷ジョブを識別する為にプリンタ3が発行したジョブIDがセットされる。
この例では、「1234」というジョブIDがセットされている状態を表す。
図8はGetPrinterElementsの内容を表す図であり、(a)はGetPrinterElementsRequest、(b)はGetPrinterElementsResponseをそれぞれ表す。
図8(a)はGetPrinterElementsRequestを表す図である。
同図に示すGetPrinterElementsRequestは、PC1からプリンタ3に発行されるものの一例である。同図において、801は<wprt:Name>要素であり、前記パブリック情報であり、その値としてwprt:PrinterDescriptionがセットされている。
図8(b)はGetPrinterElementsResponseを表す図である。同図に示すGetPrinterElementsResponseは、プリンタ3からPC1に返されるものの一例である。プリンタ3は、wprt:PrinterDescriptionがセットされた<wprt:Name>要素801を含むGetPrinterElementsRequestを受け取った時、GetPrinterElementsResponseでwprt:PrinterDescriptionをPC1に返す。同図において、806は、ABC社のWSDを利用したPrint Serviceの名前空間を名前空間名ansと定義している記述である。名前空間名ansの有効範囲内は、ABC社のWSDを利用したPrint Serviceで定義されているプライベート情報である。以降の図においても、名前空間名ansは同様な取り扱いとなり、名前空間名ansの有効範囲内は、ABC社のWSDを利用したPrint Serviceで定義されているプライベート情報を表す。803は<wprt:ElementData>要素であり、前記パブリック情報であり、Name属性として前記パブリック情報のwprt:PrinterDescriptionがセットされている。これは、このGetPrinterElementsResponseが、<wprt:Name>要素801で指定されたwprt:PrinterDescriptionを含んでいることを表す。805は<wprt:PrinterDescription>要素であり、前記パブリック情報であり、プリンタ3に搭載されている機能等に関する情報が、この中に含まれている。804は<wprt:DeviceId>要素であり、前記パブリック情報であり、IEEE 1284−2000のDevice IDで定義されたデータ(文字列)がセットされている。これは、プリンタ3のDevice IDを表す。
この例では、「MFG:ABC;CMD:ABCCommand;MDL:Kmmn;CLS:PRINTER;DES:ABC Kmmn;VER:1.00;INFO:000;」というDevice IDがセットされている状態を表す。802は<ans:MultipleJobsControl>要素であり、前記プライベート情報であり、プリンタ3が複数印刷ジョブ制御機能を備えるプリンタであるか否かを表す。この複数印刷ジョブ制御機能とは、そのプリンタが複数の印刷ジョブを受け付けることができ、その内の1つの印刷ジョブを処理して印刷を実行することができる、という機能である。プリンタがこの機能を備える場合は「true」が、この機能を備えない場合は「false」が、この要素にセットされる。この例では、「true」がセットされている状態を表す。
図9はGetPrinterElementsの内容を表す図であり、(a)は予約要求であるGetPrinterElementsRequest、(b)はGetPrinterElementsResponseをそれぞれ表す。
図9(a)はGetPrinterElementsRequestを表す図である。
同図は本発明の特徴を最もよく表す図の内の1つである。同図に示すGetPrinterElementsRequestは、PC1からプリンタ3に発行されるものの一例である。同図において、903は<wprt:Name>要素であり、前記パブリック情報であり、その値としてans:ABCCommandがセットされている。このans:ABCCommandは、前記プライベート情報である。904は<ans:ABCCommand>要素であり、前記プライベート情報であり、この中に、<ans:SplJobId>要素905、<ans:ReceivedId>要素906、<ans:Retry>要素901、<ans:OSVersion>要素907、<ans:DateTime>要素908が含まれている。要素905、906、901、907、908は全て前記プライベート情報であり、ランゲージモニタ36がGetPrinterElementsRequest内のこれらの要素に、それぞれ適切な値をセットする。ランゲージモニタ36は、図5のS503や図6のS603でスプーラ40がLM_StartDocPort( )関数をコールした時に渡される第3引数JobIdにセットされている値(ジョブID)を、<ans:SplJobId>要素905にセットする。スプーラ40からランゲージモニタ36に渡されたこのジョブIDは、PC1内のOSから発行されたものであるので、<ans:SplJobId>要素905にセットされる値は、プリンタ3から発行されて<wprt:JobId>要素1104にセットされるジョブIDとは全く異なるものである。この例では、「5」という値がセットされている状態を表す。LM_StartDocPort( )関数の仕様は次に示す通りである。
BOOL WINAPI LM_StartDocPort(
HANDLE hPort,
LPWSTR pPrinterName,
DWORD JobId,
DWORD Level,
LPBYTE pDocInfo
);
− Parameters −
hPort:Caller−supplied port handle.
pPrinterName:Caller−supplied pointer to a string containing the printer name.
JobId:Caller−supplied,spooler−assigned job identifier.Level:Caller−supplied value indicating the type of structure pointed to by pDocInfo.Possible values are as follows:
Level pDocInfo
1 DOC_INFO_1
2 DOC_INFO_2
pDocInfo:Caller−supplied pointer to a DOC_INFO_1 or DOC_INFO_2 structure.These structures are described in the Microsoft Windows(登録商標) SDK documentation.
− Return Value −
If the operation succeeds,the function should return TRUE.Otherwise it should return FALSE.
ランゲージモニタ36とポートモニタ37のインタフェースであるPM_WritePort( )関数の仕様は次に示す通りである。
BOOL WINAPI PM_WritePort(
HANDLE hPort,
LPBYTE pBuffer,
DWORD cbBuf,
LPDWORD pcbWritten
);
− Parameters −
hPort:Caller−supplied port handle.
pBuffer:Caller−supplied pointer to a buffer containing data to be written to the port.
cbBuf:Caller−supplied size,in bytes, of
pBuffer.
pcbWritten:Caller−supplied pointer to a location to receive the number of bytes successfully written to the port.
− Return Value −
If the operation succeeds,the function should return TRUE. Otherwise it should return FALSE.
ポートモニタ37は、図5のS515や図16のS1611(図21の(a)のステップS2102)において、WSDを制御するWSDAPIsのCreatePrintJob( )をコールするが、この関数の引数として参照できる図11に示す<wprt:JobName>要素1102、<wprt:JobOriginatingUserName>要素1103、<wprt:JobId>要素1104にセットされている値は、PM_WritePort( )関数の引数として渡されない為、ランゲージモニタ36がこれらの要素1102、1103、1104にセットされている値を参照したり、ランゲージモニタ36がこれらの値を変更したりすることはできない。同じ理由により、ランゲージモニタ36が、ポートモニタ37から発行されるCreatePrintJobオペレーションを使って、CreatePrintJobRequestに前記プライベート情報である要素905、906、901、907、908を追加することもできない。
<ans:ReceivedId>要素906には、プリンタ3が印刷ジョブ要求の予約を受け付けた時に発行する印刷予約IDがセットされる。この例では、プリンタ3から印刷予約IDがまだ発行されていないので、「None」という値がセットされている状態を表す。ランゲージモニタ36は、PC1がプリンタ3に印刷ジョブ要求を発行する為のトリガとなる、印刷制御コマンドで構成された印刷データの先頭データをプリンタ3に初めて送信しようとする時の初期値として、「None」を<ans:ReceivedId>要素906にセットする。それ以外の場合は、プリンタ3からPC1に最後に送られてきたGetPrinterElementsResponseの<ans:ReceivedId>要素912にセットされている値を、ランゲージモニタ36がlmReceivedに保存しておき、ランゲージモニタ36がこの値を<ans:ReceivedId>要素906にセットする。<ans:Retry>要素901には、PC1がプリンタ3に発行する印刷ジョブ要求のリトライ回数がセットされる。この例では、PC1がプリンタ3に印刷ジョブ要求を初めて送信するケースを表す「0」という値がセットされている状態を表す。ランゲージモニタ36は、PC1がプリンタ3に印刷ジョブ要求を発行する為のトリガとなる、印刷制御コマンドで構成された印刷データの先頭データの送信を試みる度に、このリトライ回数を1ずつ更新して、その値を<ans:Retry>要素901にセットする。<ans:OSVersion>要素907には、PC1のOSのバージョンがセットされる。ランゲージモニタ36は、OSのAPIであるGetVersionEx( )関数をコールして、その引数で返されるOSのバージョン情報を、<ans:OSVersion>要素907にセットする。この例では、OSがWindows(登録商標) Vistaであることを表す「6.0」という値がセットされている状態を表す。プリンタ3は、この<ans:OSVersion>要素907にセットされている値を確認し、PCのOSがWindows(登録商標) Vistaの場合と、それ以外のOSの場合とで、制御を切り換えることが可能である。例えば、Windows(登録商標) Vistaから将来のWindows(登録商標) OSにかけて、WSDのプロトコル等のタイミングや制御に変更が入った場合、プリンタ3がそれに合わせてWSDのプロトコル等のタイミングや制御を切り換えることにより、PCにインストールされているOS毎に最適化された安定した制御を行うことができ、誤動作等を防止することができる。<ans:DateTime>要素908には、このGetPrinterElementsRequestを発行する時の日時がセットされる。ランゲージモニタ36は、OSのAPIをコールして、日付と時刻を取得し、この日付と時刻を用いて<ans:DateTime>要素908に日時をセットする。この例では、「2009−01−01T00:08:00」という値がセットされている状態を表す。ネットワーク4内に接続されているPC、プリンタ、様々なデバイスの状況に応じて、複数のPC(PC1、PC2及びその他のPC(不図示))からプリンタ3に対して順に発行されたGetPrinterElementsRequestを、プリンタ3が発行された順に受信するとは限らない。その為、プリンタ3は<ans:DateTime>要素908をもとに、GetPrinterElementsRequestを処理する順序を決定し、その順序に従って、GetPrinterElementsRequestに対する応答として、その発行元のPCに対して図9(b)で後述するGetPrinterElementsResponseを返す。
図9(b)はGetPrinterElementsResponseを表す図である。同図は本発明の特徴を最もよく表す図の内の1つである。同図に示すGetPrinterElementsResponseは、PC1からプリンタ3に発行されるものの一例である。プリンタ3は、ans:ABCCommandがセットされた<wprt:Name>要素903を含むGetPrinterElementsRequestを受け取った時、GetPrinterElementsResponseでans:ABCCommandをPC1に返す。同図において、909は<wprt:ElementData>要素であり、前記パブリック情報であり、Name属性として前記プライベート情報のans:ABCCommandがセットされている。これは、このGetPrinterElementsResponseが、<wprt:Name>要素903で指定されたans:ABCCommandを含んでいることを表す。910は<ans:ABCCommand>要素であり、前記プライベート情報であり、この中に、<ans:SplJobId>要素911、<ans:ReceivedId>要素912、<ans:Retry>要素902、<ans:OSVersion>要素913、<ans:DateTime>要素914が含まれている。要素911、912、902、913、914は全て前記プライベート情報である。プリンタ3は、<ans:SplJobId>要素905にセットされている値をそのまま<ans:SplJobId>要素911にセットする。この例では、「5」という値がセットされている状態を表す。プリンタ3は、図13で後述するように<ans:ReceivedId>要素912に適切な値をセットする。この例では、「00000202」という値がセットされている状態を表す。プリンタ3は、<ans:Retry>要素901にセットされている値を確認し、「0」がセットされている場合は、新規に発行された印刷ジョブに対するGetPrinterElementsRequestであると判断する。「0」以外の値がセットされている場合は、プリンタ3が予約を受け付けた印刷ジョブの再開始要求に対するGetPrinterElementsRequestであると判断する。プリンタ3は、<ans:Retry>要素901にセットされていた値をそのまま<ans:Retry>要素902にセットする。この例では、ランゲージモニタ36が、PC1がプリンタ3に印刷ジョブ要求を発行する為のトリガとなる、印刷制御コマンドで構成された印刷データの先頭データをプリンタ3に初めて送信しようとしたケースを表す「0」という値がセットされている状態を表す。<ans:OSVersion>要素913は、PC(PC1)のOSのバージョン情報を表す。プリンタ3は、<ans:OSVersion>要素907にセットされていた値をそのまま<ans:OSVersion>要素913にセットする。この例では、OSがWindows(登録商標) Vistaであることを表す「6.0」という値がセットされている状態を表す。<ans:DateTime>要素914には、このGetPrinterElementsResponseを発行する時の日時がセットされる。プリンタ3は、内部に装備されているリアルタイムクロックから日付と時刻を取得し、この日付と時刻を用いて<ans:DateTime>要素914に日時をセットする。この例では、「2009−01−01T00:08:01」という値がセットされている状態を表す。PC1は、<ans:DateTime>要素908と<ans:DateTime>要素914との時間差から、GetPrinterElementsRequestを発行してからGetPrinterElementsResponseを受信する迄の時間を取得することができる。PC1は、これを利用してネットワーク4の通信速度やトラフィックを計算して予想することができ、この時間をもとにWSDのプロトコルの通信やタイミングの制御を最適化することができる。また、PC1はAPIを使ってOS内部のタイマーをコールし、このタイマーから計算されたGetPrinterElementsRequestの発行からGetPrinterElementsResponseの返信を受け取る迄の時間と、前記<ans:DateTime>要素908と<ans:DateTime>要素914との時間差から計算された時間を比較することもできる。この比較結果をもとに、PC1はプリンタ3のリアルタイムクロックの日付や時刻を補正したり、PC1内の日付や時刻を補正したりすることができる。図9(a)の説明の中で前述した通り、ポートモニタ37は、図5のS515や図6のS1611(図21の(a)のステップS2102)において、WSDを制御するWSDAPIsのCreatePrintJob( )をコールするが、この関数の引数として参照できる図11に示す<wprt:JobName>要素1102、<wprt:JobOriginatingUserName>要素1103、<wprt:JobId>要素1104にセットされている値は、PM_WritePort( )関数の引数として渡されない為、ランゲージモニタ36がこれらの要素1102、1103、1104にセットされている値を参照したり、ランゲージモニタ36がこれらの値を変更したりすることはできない。同じ理由により、ランゲージモニタ36が、ポートモニタ37から発行されるCreatePrintJobオペレーションを使って、CreatePrintJobResponseから前記プライベート情報である要素911、912、902、913、914を参照することもできない。
図10はGetPrinterElementsの内容を表す図であり、(a)は予約要求であるGetPrinterElementsRequest、(b)はGetPrinterElementsResponseをそれぞれ表す。
図10(a)はGetPrinterElementsRequestを表す図である。同図は本発明の特徴を最もよく表す図の内の1つである。同図に示すGetPrinterElementsRequestは、PC1からプリンタ3に発行されるものの一例である。同図において、図9(a)と同様な内容に関しては、その詳細説明を省略する。
1001は<wprt:Name>要素であり、前記パブリック情報であり、その値としてans:ABCCommandがセットされている。このans:ABCCommandは、前記プライベート情報である。1002は<ans:ABCCommand>要素であり、前記プライベート情報であり、この中に、<ans:SplJobId>要素1003、<ans:ReceivedId>要素1004、<ans:Retry>要素1005、<ans:OSVersion>要素1006、<ans:DateTime>要素1007が含まれている。要素1003、1004、1005、1006、1007は全て前記プライベート情報であり、ランゲージモニタ36がGetPrinterElementsRequest内のこれらの要素に、それぞれ適切な値をセットする。ランゲージモニタ36は、図5のS503や図6のS603でスプーラ40がLM_StartDocPort( )関数をコールした時に渡される第3引数JobIdにセットされている値を、<ans:SplJobId>要素1003にセットする。この例では、「5」という値がセットされている状態を表す。<ans:ReceivedId>要素1004には、プリンタ3が印刷ジョブ要求の予約を受け付けた時に発行する印刷予約IDがセットされる。この例では、プリンタ3がこの印刷ジョブ要求の予約を既に受け付けていて、受け付けた時に発行された「00000202」という値がセットされている状態を表す。<ans:Retry>要素1005には、PC1がプリンタ3に発行する印刷ジョブ要求のリトライ回数がセットされる。この例では、PC1がプリンタ3に印刷ジョブ要求を1回目のリトライとして送信するケースを表す「1」という値がセットされている状態を表す。ランゲージモニタ36は、PC1がプリンタ3に印刷ジョブ要求を発行する為のトリガとなる、最初の印刷制御コマンドで構成された印刷データの送信を試みる度に、このリトライ回数を1ずつ更新して、その値を<ans:Retry>要素1005にセットする。<ans:OSVersion>要素1006には、PC1のOSのバージョンがセットされる。この例では、OSがWindows(登録商標) Vistaであることを表す「6.0」という値がセットされている状態を表す。<ans:DateTime>要素1007には、このGetPrinterElementsRequestを発行する時の日時がセットされる。この例では、「2009−01−01T00:08:04」という値がセットされている状態を表す。
図10(b)はGetPrinterElementsResponseを表す図である。同図は本発明の特徴を最もよく表す図の内の1つである。同図に示すGetPrinterElementsResponseは、PC1からプリンタ3に発行されるものの一例である。プリンタ3は、ans:ABCCommandがセットされた<wprt:Name>要素1001を含むGetPrinterElementsRequestを受け取った時、GetPrinterElementsResponseでans:ABCCommandをPC1に返す。同図において、図9(b)と同様な内容に関しては、その詳細説明を省略する。1008は<wprt:ElementData>要素であり、前記パブリック情報であり、Name属性として前記プライベート情報のans:ABCCommandがセットされている。これは、このGetPrinterElementsResponseが、<wprt:Name>要素1001で指定されたans:ABCCommandを含んでいることを表す。1009は<ans:ABCCommand>要素であり、前記プライベート情報であり、この中に、<ans:SplJobId>要素1010、<ans:ReceivedId>要素1011、<ans:Retry>要素1012、<ans:OSVersion>要素1013、<ans:DateTime>要素1014が含まれている。要素1010、1011、1012、1013、1014は全て前記プライベート情報である。プリンタ3は、<ans:SplJobId>要素1003にセットされている値をそのまま<ans:SplJobId>要素1010にセットする。この例では、「5」という値がセットされている状態を表す。プリンタ3は、図13で後述するように<ans:ReceivedId>要素1011に適切な値をセットする。この例では、「00000202」という値がセットされている状態を表す。プリンタ3は、<ans:Retry>要素1005にセットされていた値をそのまま<ans:Retry>要素1012にセットする。この例では、「1」という値がセットされている状態を表す。プリンタ3は、<ans:OSVersion>要素1006にセットされていた値をそのまま<ans:OSVersion>要素1013にセットする。この例では、「6.0」という値がセットされている状態を表す。プリンタ3は、内部に装備されているリアルタイムクロックから日付と時刻を取得し、この日付と時刻を用いて<ans:DateTime>要素1014に日時をセットする。この例では、「2009−01−01T00:08:05」という値がセットされている状態を表す。
図18はStartJobの内容を表す図であり、(a)はジョブ予約であるStartJobRequest、(b)はStartJobResponseをそれぞれ表す。
図18(a)はStartJobRequestを表す図である。これは印刷ジョブの開始要求である。同図に示すStartJobRequestは、PC5からプリンタ3に発行されるものの一例である。同図において、1801は、ABC社のIHVの独自プロトコルを利用したABC Print Serviceの名前空間を名前空間名lansと定義している記述である。この名前空間を、図8の806に記載されているABC社のWSDを利用したPrint Serviceの名前空間と比較した場合、バージョンを表す情報が、それぞれv002とv100となっており、ABC社のIHVの独自プロトコルを利用したABC Print Serviceの名前空間の方がバージョンが古いものであることがわかる。名前空間名lansの有効範囲内は、ABC社のABC Print Serviceで定義されているプライベート情報である。以降の図においても、名前空間名lansは同様な取り扱いとなり、名前空間名lansの有効範囲内は、ABC社のABC Print Serviceで定義されているプライベート情報を表す。1802は<wsa:Action>要素であり、この情報がStartJobオペレーションであることを表す。1803は<lans:StartJobRequest>要素であり、この中に、<lans:ComputerName>要素1804、<lans:TimeStamp>要素1805、<lans:Retry>要素1806、<lans:DateTime>要素1807が含まれている。要素1803、1804、1805、1806、1807は全て前記プライベート情報であり、ランゲージモニタがそれぞれ適切な値をセットする。1804は<lans:ComputerName>要素であり、この情報の発行元のコンピュータ名として、その値にPC5がセットされている。<lans:TimeStamp>要素1805には、プリンタ3が印刷ジョブ要求の予約を受け付けた時に発行するタイムスタンプがセットされる。この例では、プリンタ3からタイムスタンプがまだ発行されていないので、「None」という値がセットされている状態を表す。ランゲージモニタは、PC5がプリンタ3に印刷ジョブの開始要求を発行する為のトリガとなる、印刷制御コマンドで構成された印刷データの先頭データをプリンタ3に初めて送信しようとする時の初期値として、「None」を<lans:TimeStamp>要素1805にセットする。それ以外の場合は、プリンタ3からPC5に最後に送られてきたStartJobResponseの<lans:TimeStamp>要素1810にセットされている値を、ランゲージモニタが保存しておき、ランゲージモニタがこの値を<lans:TimeStamp>要素1805にセットする。
<lans:Retry>要素1806には、PC5がプリンタ3に発行する印刷ジョブの開始要求のリトライ回数がセットされる。この例では、PC5がプリンタ3に印刷ジョブの開始要求を初めて送信するケースを表す「0」という値がセットされている状態を表す。ランゲージモニタは、PC5がプリンタ3に印刷ジョブの開始要求を発行する為のトリガとなる、印刷制御コマンドで構成された印刷データの先頭データの送信を試みる度に、このリトライ回数を1ずつ更新して、その値を<lans:Retry>要素1806にセットする。<lans:DateTime>要素1807には、このStartJobRequestを発行する時の日時がセットされる。ランゲージモニタは、OSのAPIをコールして、日付と時刻を取得し、この日付と時刻を用いて<lans:DateTime>要素1807に日時をセットする。この例では、「2009−01−01T22:01:30」という値がセットされている状態を表す。ネットワーク4内に接続されているPC、プリンタ、様々なデバイスの状況に応じて、複数のPC(PC5及びその他のPC(不図示))からプリンタ3に対して順に発行されたStartJobRequestを、プリンタ3が発行された順に受信するとは限らない。その為、プリンタ3は<lans:DateTime>要素1807をもとに、StartJobRequestを処理する順序を決定し、その順序に従って、StartJobRequestに対する応答として、その発行元のPCに対して図18(b)で後述するStartJobResponseを返す。
図18(b)はStartJobResponseを表す図である。同図に示すStartJobResponseは、PC5からプリンタ3に発行されるものの一例である。
プリンタ3は、図18(a)に示すStartJobRequestを受け取った時、StartJobResponseをPC5に返す。同図において、1808は<lans:StartJobResponse>要素であり、この中に、<lans:ComputerName>要素1809、<lans:TimeStamp>要素1810、<lans:Retry>要素1811、<lans:DateTime>要素1812が含まれている。要素1808、要素1809、1810、1811、1812は全て前記プライベート情報である。プリンタ3は、<lans:ComputerName>要素1804にセットされている値をそのまま<lans:ComputerName>要素1809にセットする。この例では、「PC5」という値がセットされている状態を表す。
プリンタ3は、図14に示す印刷キューデータベースにセットされている情報に基づいて、<lans:TimeStamp>要素1810に適切な値をセットする。この例では、「00000301」という値がセットされている状態を表す。プリンタ3は、<lans:Retry>要素1806にセットされている値を確認し、「0」がセットされている場合は、新規に発行された印刷ジョブに対するStartJobRequestであると判断する。「0」以外の値がセットされている場合は、プリンタ3が予約を受け付けた印刷ジョブの再開始要求に対するStartJobRequestであると判断する。
プリンタ3は、<lans:Retry>要素1806にセットされていた値をそのまま<lans:Retry>要素1811にセットする。この例では、ランゲージモニタが、PC5がプリンタ3に印刷ジョブの開始要求を発行する為のトリガとなる、印刷制御コマンドで構成された印刷データの先頭データをプリンタ3に初めて送信しようとしたケースを表す「0」という値がセットされている状態を表す。<lans:DateTime>要素1812には、このStartJobResponseを発行する時の日時がセットされる。プリンタ3は、内部に装備されているリアルタイムクロックから日付と時刻を取得し、この日付と時刻を用いて<lans:DateTime>要素1812に日時をセットする。この例では、「2009−01−01T22:01:31」という値がセットされている状態を表す。PC5は、<lans:DateTime>要素1807と<lans:DateTime>要素1812との時間差から、StartJobRequestを発行してからStartJobResponseを受信する迄の時間を取得することができる。PC5は、これを利用してネットワーク4の通信速度やトラフィックを計算して予想することができ、この時間をもとにIHVの独自プロトコルの通信やタイミングの制御を最適化することができる。また、PC5はAPIを使ってOS内部のタイマーをコールし、このタイマーから計算されたStartJobRequestの発行からStartJobResponseの返信を受け取る迄の時間と、前記<lans:DateTime>要素1807と<lans:DateTime>要素1812との時間差から計算された時間を比較することもできる。この比較結果をもとに、PC5はプリンタ3のリアルタイムクロックの日付や時刻を補正したり、PC5内の日付や時刻を補正したりすることができる。
図14はプリンタ3が受け付けて予約した印刷ジョブ要求を管理する印刷キューデータベースを表す図である。同図は本発明の特徴を最もよく表す図の内の1つである。図14(a)は、複数の印刷ジョブを受け付けることができず、1つの印刷ジョブだけを受け付けることができるようなプリンタにおいて、このプリンタ内に装備された、WSDだけを利用したネットワーク印刷を制御する為の印刷キューデータベースを表す図である。図14(b)は、4つの印刷ジョブを受け付けることができるようなプリンタにおいて、このプリンタ内に装備された、WSDとIHVの独自プロトコルの両プロトコルが混在したネットワーク印刷を制御する為の印刷キューデータベースを表す図である。図14(c)は、図14(b)の印刷キューデータベースを、さらに拡張して、USBインタフェース7を介した印刷ジョブや印刷ジョブ要求も同時に管理することができる、ネットワーク印刷とローカル(USB)印刷を統合して制御する為の印刷キューデータベースを表す図である。図14(a)、図14(b)、図14(c)において、「Null」はデータが存在しない空領域であることを表し、「−」はデータが不定(利用不可)であることを表す。
図14(a)において、「No.」欄は、実行中の印刷ジョブ、または予約されている印刷ジョブ要求の順番を表す。1は現在印刷を実行中の印刷ジョブ、2〜8は印刷ジョブ要求の予約を表す。2〜8において、2は次に印刷を実行する予定の最優先の印刷ジョブ要求の予約、8は最後に印刷を実行する予定の最も優先順位の低い印刷ジョブ要求の予約を表す。本実施例では、プリンタ3が実行できる印刷ジョブの数が1つ、予約できる印刷ジョブ要求の数が7つの、合計8つの印刷キューの例を表している。図14(b)、図14(c)において、「No.」欄は、実行中の印刷ジョブ、または予約されている印刷ジョブ要求の順番を表す。1は現在印刷を実行中の印刷ジョブ、2〜4は受け付けが完了してジョブID(「wprt:JobId」欄参照)が発行済みで印刷待機中の印刷ジョブ、5〜8は印刷ジョブ要求の予約を表す。2〜4において、2は次に印刷を実行する予定の最優先の印刷ジョブ、3は2の次に優先順位の高い印刷ジョブ、4は3の次に優先順位の高い印刷ジョブを表す。5〜8において、5は4の次に優先順位の高い印刷ジョブ要求の予約、8は最後に印刷を実行する予定の最も優先順位の低い印刷ジョブ要求の予約を表す。本実施例では、プリンタ3が実行できる印刷ジョブの数が1つ、受け付けることができる印刷ジョブの数が前記実行できる印刷ジョブも含めて合計4つ、予約できる印刷ジョブ要求の数が4つの、合計8つの印刷キューの例を表している。図14(a)、図14(b)、図14(c)において、「Computer Name」欄は、印刷ジョブ要求を発行したPCのコンピュータ名を表す。「wprt:JobName」欄は、<wprt:JobName>要素(例えば1102)にセットされている印刷ジョブ名を表す。「wprt:JobOriginatingUserName」欄は、<wprt:JobOriginatingUserName>要素(例えば1103)にセットされているユーザ名を表す。「wprt:JobId」欄は、<wprt:JobId>要素(例えば1104)にセットされている、プリンタ3から発行されたジョブIDを表す。例えば、図14(a)のNo.1の行の「wprt:JobId」欄には、「888」というジョブIDがセットされている。これは、プリンタ3がこの印刷ジョブの印刷を実行していて、ジョブIDを発行済みの状態であることを表している。図14(a)のNo.2〜8の行の「wprt:JobId」欄には、「Null」がセットされている。これは、プリンタ3がこの印刷ジョブ要求の予約を受け付けただけで、印刷が実行されていないので、ジョブIDを発行していない状態であることを表している。例えば、図14(b)のNo.1の行の「wprt:JobId」欄には、「888」というジョブIDがセットされている。これは、プリンタ3がこの印刷ジョブの印刷を実行していて、ジョブIDを発行済みの状態であることを表している。図14(b)のNo.2〜4の行の「wprt:JobId」欄には、「888」、「−」、「890」、「1001」という値がそれぞれセットされている。これは、プリンタ3がこれらの印刷ジョブを受け付けていて、ジョブIDを発行済みの状態であることを表している。図14(b)のNo.5〜8の行の「wprt:JobId」欄には、「−」、「Null」、「Null」、「−」という値がそれぞれセットされている。これは、プリンタ3がこれらの印刷ジョブ要求の予約を受け付けただけで、印刷が実行されていないので、ジョブIDを発行していない状態であることを表している。尚、図14(b)のNo.2、5、8行の「wprt:JobId」欄には「−」がセットされているが、これは、IHVの独自プロトコルにおいては、<wprt:JobId>要素が存在しないので、不定(利用不可)であることを表している。
図14(a)、図14(b)、図14(c)の「ans:SplJobId」欄は、<ans:SplJobId>要素(例えば905、1003)にセットされている、スプーラ40から発行されたジョブIDを表す。例えば、1台のPCからあるユーザが同じドキュメントを何度も繰り返して連続印刷するようなケースにおいて、スプーラ40がこれらの印刷ジョブを複数のスレッド等により並列処理できる場合、これら複数の印刷ジョブ要求、すなわち複数のCreatePrintJobRequest内の<wprt:JobName>要素(例えば1102)にセットされている印刷ジョブ名と<wprt:JobOriginatingUserName>要素(例えば1103)にセットされているユーザ名が、各印刷ジョブ要求間で同一の印刷ジョブ名とユーザ名になってしまう為、これらの印刷ジョブ要求を区別することができない、という問題がある。このような問題に対して、スプーラ40から発行されたジョブIDを印刷キューデータベース内に保持する情報に含めることで、これらの印刷ジョブを識別することができ、前記問題を解決することができる。図14(a)、図14(b)、図14(c)の「Time」欄は、PCから発行された印刷ジョブ要求または印刷ジョブ要求の予約確認要求を、プリンタ3が受け付けた時刻を表すタイムカウント値を表す。図14(a)において、「ans:ReceivedId」欄は、<ans:ReceivedId>要素(例えば912、1011)にセットされている印刷予約IDを表す。図14(b)において、「Protocol」欄は、PCとプリンタ3との間のネットワーク通信に使用される通信プロトコルを表す。本実施例では、WSDあるいはIHVの独自プロトコル(IHV Native)の何れかがセットされる。図14(c)において、「Protocol」欄は、PCとプリンタ3との間のネットワーク通信またはPC1とプリンタ3との間のローカル(USB)通信に使用される通信プロトコルを表す。本実施例では、WSD、ネットワーク用のIHVの独自プロトコル(IHV Native)、あるいはローカル(USB)用のIHVの独自プロトコル(IHV Native 2)の何れかがセットされる。図14(b)、図14(c)の「ans:ReceivedId/lans:TimeStamp」欄は、<ans:ReceivedId>要素(例えば912、1011)にセットされている印刷予約ID、またはプリンタ3がIHVの独自プロトコルを使ってPCに発行する<lans:TimeStamp>要素(例えば1810)にセットされているタイムスタンプを表す。このタイムスタンプは、IHVの独自プロトコルにおいて、前記印刷予約IDに相当するものであり、それぞれの印刷ジョブ要求に対して一意の値として割り振られるものである。言い換えれば、プリンタ3は、このタイムスタンプを、WSDの<wprt:JobId>要素のジョブIDに相当するようなジョブIDとして利用することもできる。この実施例のように印刷予約IDとタイムスタンプを同じ形式で定義することで、印刷ジョブ要求の予約を一元管理して、容易に管理及び制御することができる。ランゲージモニタ(ランゲージモニタ36)は、IHVの独自プロトコルを制御する為のAPIsを利用することにより、IHVの独自プロトコルを利用してプリンタ3に任意の情報を送信したり、プリンタ3から任意の情報を受信したりすることができる。従って、IHVの独自プロトコルを利用した場合、WSDのように、図16のS1611(図21の(a)のステップS2102)のCreatePrintJobオペレーションと図16のS1621(図20のステップS2016)のGetPrinterElementsオペレーションを組み合わせた2つ(複数)のオペレーションによって1つの印刷ジョブ要求を発行して、印刷ジョブ要求の予約を行うような仕組みは必要ない。その為、IHVの独自プロトコルを利用した場合、WSDで例えると図5のS515のCreatePrintJobオペレーションに相当するような、印刷ジョブの開始要求だけによって1つの印刷ジョブ要求を発行することができる。すなわち、図18に示すStartJobオペレーションだけによって、1つの印刷ジョブ要求を発行することができる。
例えば、PC1にはWindows(登録商標) VistaのOSがインストールされていて、ネットワーク4上の他のPCにはWindows(登録商標) XPのOSがインストールされている場合、それぞれのPCから発行される印刷ジョブとして、WSDのプロトコルを利用したものとIHVの独自プロトコルを利用したものとが混在することになる。このような、複数のプロトコルの印刷ジョブが混在している環境においても、図14(b)のような印刷キューデータベースを利用することで、各PCから発行された印刷ジョブが発行された順序に従って正しく印刷される、優れた周辺装置制御システムを実現することができる。
さらに、USBインタフェース7を使った印刷においても、USB用のIHVの独自プロトコルを実装し、図14(c)のような印刷キューデータベースを利用することで、各PCからネットワーク4を介して発行された印刷ジョブ、及びPC1からUSBインタフェース7を介して発行されて印刷ジョブが、発行された順序に従って正しく印刷される、優れた周辺装置制御システムを実現することもできる。
図15はPCのポートとDevice IDのINFO情報の関係を示す表である。図15(a)では、プリンタ3がUSBインタフェース7とネットワーク4を完全に排他的に制御する例を示す。図15(a)において、「印刷中のPC1のポート」欄は、PC1が印刷中の時に、その印刷に使用しているポートの情報を表す。「印刷待ちのPC2のポート」欄は、PC2が印刷待ちの時に、その待機している印刷に使用するポートの情報を表す。「印刷中のPC1のポート」欄、「印刷待ちのPC2のポート」欄において、USBは、USBインタフェース7を介して印刷するUSBポートを、WSDは、ネットワーク4を介してWSDで印刷するネットワークポートを、IHV Nativeは、ネットワーク4を介してIHVの独自プロトコルで印刷するネットワークポートを、それぞれ表す。「Device IDのINFO」欄は、Device IDのINFO情報にセットされている値を表し、PC1以外のPC(この例ではPC2)から見た場合のプリンタ3の状態を表す情報を含んでいる。プリンタ3が電源オンでスタンバイ(オンライン)状態の時は、INFO:000というように「000」がDevice IDのINFO情報にセットされる。以下において、Device IDのINFO情報にセットされる値とその意味は次に示す通りである。
INFO:意味
000 プリンタ3が電源オンでスタンバイ(オンライン)状態
101 他のインタフェースで使用中の状態
102 他のコンピュータで使用中の状態
PC2はこれらの情報をもとに、プリンタ3の状態をモニタして表示するステータスモニタのようなアプリケーション上に、次のようなメッセージを表示してユーザの操作性を向上することができる。
INFO:メッセージ
000 オンライン
101 他のインタフェースで使用中
102 他のコンピュータで使用中
PC1からプリンタ3で印刷している時、「印刷中のPC1のポート」がUSBで「印刷待ちのPC2のポート」がIHV Nativeの場合、PC2がプリンタ3からIHVの独自プロトコルを用いてDevice IDを取得すると、INFO情報に「101」がセットされたDevice IDがプリンタ3から返される。PC1からプリンタ3で印刷している時、「印刷中のPC1のポート」がUSBで「印刷待ちのPC2のポート」がWSDの場合、PC2がプリンタ3からGetPrinterElements(wprt:PrinterDescription)を用いてDevice IDを取得すると、INFO情報に「101」がセットされたDevice IDがプリンタ3から返される。PC1からプリンタ3で印刷している時、「印刷中のPC1のポート」がIHV Nativeで「印刷待ちのPC2のポート」がIHV Nativeの場合、PC2がプリンタ3からIHVの独自プロトコルを用いてDevice IDを取得すると、INFO情報に「102」がセットされたDevice IDがプリンタ3から返される。
PC1からプリンタ3で印刷している時、「印刷中のPC1のポート」がIHV Nativeで「印刷待ちのPC2のポート」がWSDの場合、PC2がプリンタ3からGetPrinterElements(wprt:PrinterDescription)を用いてDevice IDを取得すると、INFO情報に「102」がセットされたDevice IDがプリンタ3から返される。PC1からプリンタ3で印刷している時、「印刷中のPC1のポート」がWSDで「印刷待ちのPC2のポート」がIHV Nativeの場合、PC2がプリンタ3からIHVの独自プロトコルを用いてDevice IDを取得すると、INFO情報に「102」がセットされたDevice IDがプリンタ3から返される。PC1からプリンタ3で印刷している時、「印刷中のPC1のポート」がWSDで「印刷待ちのPC2のポート」がWSDの場合、PC2がプリンタ3からGetPrinterElements(wprt:PrinterDescription)を用いてDevice IDを取得すると、INFO情報に「102」がセットされたDevice IDがプリンタ3から返される。
図15(a)では、PC1からプリンタ3にUSBインタフェース7を介して印刷中に、PC2上のステータスモニタに「他のインタフェースで使用中」というようなメッセージを表示することができたが、このケースにおいて、PC2上のステータスモニタに表示されるメッセージとして最も適切なメッセージは「他のコンピュータで使用中」である。
図15(b)では、プリンタ3がUSBインタフェース7とネットワーク4を包括的に制御する例を示す。図15(b)において、図15(a)と同様な内容に関する説明は省略する。PC1からプリンタ3で印刷している時、「印刷中のPC1のポート」がUSBで「印刷待ちのPC2のポート」がIHV Nativeの場合、PC2がプリンタ3からIHVの独自プロトコルを用いてDevice IDを取得すると、INFO情報に「102」がセットされたDevice IDがプリンタ3から返される。PC1からプリンタ3で印刷している時、「印刷中のPC1のポート」がUSBで「印刷待ちのPC2のポート」がWSDの場合、PC2がプリンタ3からGetPrinterElements(wprt:PrinterDescription)を用いてDevice IDを取得すると、INFO情報に「102」がセットされたDevice IDがプリンタ3から返される。ここでは一例として、USBインタフェース7を介してプリンタ3を制御する印刷制御コマンド及びDevice IDと、ネットワーク4を介してプリンタ3を制御する印刷制御コマンド及びDevice IDを同一コマンドとし、そのコマンドが含まれるプロトコルだけを変えることで、このような制御を実現している。
図12はプリンタ3におけるCreatePrintJobの処理を表すフローチャートである。同図は本発明の特徴を最もよく表す図の内の1つである。図12のフローに係るプログラムは、ROM16に記憶されており、RAM17に読み出され、CPU15により実行される。プリンタ3は、起動時にnew_jobフラグを「0」で初期化しているものとする。PC(PC1)からプリンタ3にCreatePrintJobRequest(例えば図11(a))が発行されて、プリンタ3がこれを受け付けると、同図のステップS1201が開始される。プリンタ3は、前記CreatePrintJobRequestを受信した時(S1202)、プリンタ3に内蔵されているタイマーから時刻や経過時間を計算可能なカウント値を取得してTime1に保存する(S1203)。
このカウント値の単位は「秒」である。プリンタ3は、前記CreatePrintJobRequestから<wprt:JobName>要素1102にセットされている印刷ジョブ名と、<wprt:JobOriginatingUserName>要素1103にセットされているユーザ名を取得する(S1204)。プリンタ3はPC1のコンピュータ名(Computer Name)を取得する(S1205)。本実施例では、WSDのPrint Service宛てのHTTP POSTでのTCP受信ソケットからIPアドレスを取得し、このIPアドレスをもとにコンピュータ名を取得する。尚、本実施例では説明をわかりやすくする為に、このようにIPアドレスからコンピュータ名を取得して、このコンピュータ名を用いてPCを特定して各処理を行っているが、IPアドレスを用いてPCを特定して各処理を行ってもよい。プリンタ3は、前記印刷ジョブ名と前記ユーザ名と前記コンピュータ名を一時的に保存する(S1209)。プリンタ3は、前記印刷ジョブ名、前記ユーザ名、前記コンピュータ名をもとに、図14に示す印刷キューデータベース内に既にステップS1202で受信したCreatePrintJobRequestで開始要求された印刷ジョブの印刷ジョブ要求の予約が存在する可能性が有るかを確認する(S1206)。図14に示す印刷キューデータベース内に前記印刷ジョブ要求の予約が既に存在する可能性が有る場合ステップS1211へ進み、存在する可能性が無い場合ステップS1208へ進む(S1207)。ステップS1208において、図14に示す印刷キューデータベース内にステップS1202で受信したCreatePrintJobRequestで開始要求された印刷ジョブより優先順位の高い他の印刷ジョブ要求の予約が有る場合ステップS1217へ進み、無い場合ステップS1210へ進む。ステップS1210において、プリンタ3は、図14に示す印刷キューデータベースにステップS1202で受信したCreatePrintJobRequestで開始要求された印刷ジョブの印刷ジョブ要求を登録する。プリンタ3は、ステップS1202で受信した印刷ジョブ要求CreatePrintJobRequestに対して、この印刷ジョブを受け付けて実行することを表す応答としてCreatePrintJobResponse(例えば図11(b))をPC(PC1)に返し(S1218)、CreatePrintJobの処理を終了する(S1221)。ステップS1211において、プリンタ3はnew_jobフラグの値を確認し、「1」がセットされている場合ステップS1219へ進み、それ以外(「0」がセットされている)場合ステップS1212へ進む。ステップS1212において、プリンタ3は、ステップS1203で保存されたTime1から図13のステップS1303で保存されたTime2を減算して、プリンタ3が図13のステップS1302でGetPrinterElementsRequestを受信してからステップS1202でCreatePrintJobRequestを受信するまでの経過時間(受信時間差)を計測する。この経過時間が5秒を超えている場合ステップS1219へ進み、5秒以内の場合ステップS1220へ進む。ステップS1220において、プリンタ3は、ステップS1209で保存した前記印刷ジョブ名と前記ユーザ名と前記コンピュータ名をもとに、図14に示す印刷キューデータベース内でこれらの情報と同じ情報を持つ印刷ジョブ要求の予約を検索する。そして、この印刷キューデータベース内から「ans:ReceivedId」欄にセットされている印刷予約IDと「ans:SplJobId」欄にセットされているスプーラ40から発行されたジョブIDを取得して、一時的に保存する。プリンタ3は、図13のステップS1309で保存されている<ans:ABCCommand>要素(例えば904、1002)に含まれている情報の中から<ans:ReceivedId>要素にセットされている印刷予約ID(例えば1004)と、<ans:SplJobId>要素にセットされているスプーラ40から発行されたジョブID(例えば1003)を取得する(S1213)。
プリンタ3は、ステップS1213で取得した印刷予約IDとスプーラ40から発行されたジョブIDを、ステップS1220で一時的に保存した印刷予約ID及びスプーラ40から発行されたジョブIDとそれぞれ比較する(S1214)。さらに、プリンタ3は、ステップS1220で一時的に保存した印刷予約IDをもとに印刷キューデータベースから取得した印刷ジョブ名とユーザ名とコンピュータ名を、ステップS1209で一時的に保存した印刷ジョブ名、ユーザ名及びコンピュータ名とそれぞれ比較する(S1214)。プリンタ3は、前記比較対象の全ての情報を比較した結果、全ての比較対象情報がそれぞれ一致した場合ステップS1216へ進み、少なくとも1つ以上の一致しない情報が存在した場合ステップS1217へ進む(S1215)。ステップS1216において、プリンタ3は図14に示す印刷キューデータベースを確認し、ステップS1202で受信したCreatePrintJobRequestで開始要求された印刷ジョブより優先順位の高い他の印刷ジョブ要求の予約がこの印刷キューデータベース内に有る場合ステップS1219へ進み、無い場合ステップS1210へ進む。ステップS1217において、プリンタ3はnew_jobフラグに「1」をセットする。ステップS1219において、プリンタ3は、ステップS1202で受信した印刷ジョブ要求CreatePrintJobRequestに対して、この印刷ジョブを受け付けることができなかったことを表すFault(ServerErrorNotAcceptingJobs)をPC(PC1)に返し、CreatePrintJobの処理を終了する(S1221)。
図13はプリンタ3におけるGetPrinterElementsの処理を表すフローチャートである。同図は本発明の特徴を最もよく表す図の内の1つである。図13のフローに係るプログラムは、ROM16に記憶されており、RAM17に読み出され、CPU15により実行される。PC(PC1)からプリンタ3にGetPrinterElementsRequest(例えば図8(a)、図9(a)、図10(a))が発行されて、プリンタ3がこれを受け付けると、同図のステップS1301が開始される。プリンタ3は、前記GetPrinterElementsRequestを受信した後(S1302)、前記GetPrinterElementsRequestから<wprt:Name>要素(例えば801、903、1001)にセットされている値を確認する(S1304)。ステップS1304において、前記GetPrinterElementsRequestの中に複数の<wprt:Name>要素が存在する場合があるので、プリンタ3は取得した全ての<wprt:Name>要素にセットされている値を一時的に保存しておく。<wprt:Name>要素にセットされている値として、wprt:PrinterDescriptionが見つかった場合ステップS1306へ進み、見つからなかった場合ステップS1308へ進む(S1305)。ステップS1306において、プリンタ3は<ans:MultipleJobsControl>要素802に「true」をセットし、ステップS1308へ進む。ステップS1308において、プリンタ3は、ステップS1304で一時的に保存された<wprt:Name>要素にセットされている全ての値を確認し、ans:ABCCommandが見つかった場合ステップS1303へ進み、見つからなかった場合ステップS1319へ進む。ステップS1303において、プリンタ3は内蔵されているタイマーから時刻や経過時間を計算可能なカウント値を取得してTime2に保存する。このカウント値の単位は「秒」である。ステップS1309において、プリンタ3は前記GetPrinterElementsRequest内の<ans:ABCCommand>要素(例えば904、1002)に含まれている全ての情報を取得して保存する。プリンタ3はnew_jobフラグの値を確認し、「1」がセットされている場合ステップS1307へ進み、それ以外(「0」がセットされている)場合ステップS1311へ進む(S1320)。ステップS1307において、Time2から図12のステップS1203で保存されたTime1を減算して、図12のステップS1202でプリンタ3がCreatePrintJobRequestを受信してからステップS1302でプリンタ3がGetPrinterElementsRequestを受信するまでの経過時間(受信時間差)を計測する。この経過時間が5秒を超えている場合ステップS1321へ進み、5秒以内の場合ステップS1310へ進む。ステップS1310において、プリンタ3は、<ans:Retry>要素(例えば901、1005)にセットされている値を確認し、この値が「0」の場合ステップS1317へ進み、「0」以外(実際には0より大きい整数)の場合ステップS1311へ進む。ステップS1317において、プリンタ3は図17に示す印刷予約IDの発行処理を実行する。プリンタ3は、図17で<ans:ReceivedId>要素(例えば912、1011)にセットされた値を確認し、「None」の場合ステップS1321へ進み、「None」ではない場合ステップS1318へ進む。ステップS1318において、ステップS1317を経由して来た場合、プリンタ3は、図17のステップS1704で新規に発行した印刷予約ID(ans:ReceivedId)をもとに、図14に示す印刷キューデータベースに新規の印刷ジョブ要求の予約として各情報を登録して、印刷キューデータベースを更新する。ステップS1315(NO)を経由して来た場合、プリンタ3は、既存の印刷予約ID(ans:ReceivedId)をもとに、図14に示す印刷キューデータベースに既存の印刷ジョブ要求の予約として各情報を登録して、印刷キューデータベースを更新する。また、ステップS1318において、プリンタ3は、「Time」欄にセットされているタイムカウント値をTime2に保存されている値で更新する。ステップS1321において、プリンタ3はnew_jobフラグを「0」で初期化する。プリンタ3は、ステップS1306でセットされた情報、図17のステップS1705でセットされた情報、図14に示す印刷キューデータベース内にセットされている情報等を用いて、GetPrinterElementsResponseに各情報をセットして、ステップS1302で受信したGetPrinterElementsRequestに対する応答として、GetPrinterElementsResponseをPC(PC1)に返す(S1319)。そして、GetPrinterElementsの処理を終了する(S1322)。ステップS1311において、プリンタ3は<ans:ReceivedId>要素にセットされている印刷予約ID(例えば1004)を取得する。プリンタ3は、図14に示す印刷キューデータベース内の「ans:ReceivedId」欄または「ans:ReceivedId/lans:TimeStamp」欄に、この印刷予約IDが存在するか否かを確認する(S1312)。プリンタ3が、この印刷ジョブ要求の予約を表す印刷予約IDを図14に示す印刷キューデータベース内で発見した場合ステップS1314へ進み、発見しなかった場合ステップS1317へ進む(S1313)。ステップS1314において、プリンタ3は、図14に示す印刷キューデータベースから前記印刷予約IDで予約されている印刷ジョブ予約の「Time」欄にセットされているタイムカウント値を取得し、ステップS1303で保存されたTime2からこのタイムカウント値を減算して、最後にこの印刷ジョブ予約が更新された時からの経過時間を計測する。プリンタ3は、この経過時間が既定時間(ここでは20秒に設定)を超える場合ステップS1316へ進み、既定時間以内の場合ステップS1318へ進む(S1315)。ステップS1316において、プリンタ3は、図14に示す印刷キューデータベース内において、この印刷ジョブ要求の印刷予約ID(ans:ReceivedId)を一旦削除し、この印刷ジョブ要求をその印刷キューデータベース内の最後尾に移動して、最も優先順位の低い印刷ジョブ要求の予約となるように変更し、ステップS1317へ進む。
図12のステップS1212、図13のステップS1307において、一定時間の経過を判断する値として5秒の固定のタイムアウト値を設定したが、これらの例に限られることなく、プリンタ3の使用環境やユーザが使用するネットワークの環境に応じて、例えば、3秒、8秒、10秒というような固定のタイムアウト値を設定したり、プリンタ3の表示部21のタッチパネルや操作部20のボタン操作により、使用環境に応じた任意の適切な値を設定したりするように構成してもよい。また、プリンタ3がネットワーク4上のPCをモニタし、その数に応じてネットワークの混雑状況を把握し、その混雑状況から最適なタイムアウト値を設定するように構成してもよい。さらに、図12のステップS1212におけるタイムアウト値と、図13のステップS1307におけるタイムアウト値を、同一の値ではなく、それぞれ異なる値としてもよい。この場合、例えば、図12のステップS1212におけるタイムアウト値を5秒とし、図13のステップS1307におけるタイムアウト値を3秒とする、というような実施例となる。
図17はプリンタ3における印刷予約IDの発行の処理を表すフローチャートである。
同図は本発明の特徴を最もよく表す図の内の1つである。図17のフローに係るプログラムは、ROM16に記憶されており、RAM17に読み出され、CPU15により実行される。プリンタ3が図13のステップS1317の印刷予約IDの発行処理を実行すると、同図のステップS1701が開始される。プリンタ3は、図14に示す印刷キューデータベースの空領域の状況を確認し(S1702)、空領域が有る場合ステップS1704へ進み、空領域が無い場合ステップS1705へ進む(S1703)。ステップS1704において、プリンタ3は印刷予約ID(ans:ReceivedId)を新規に発行し、<ans:ReceivedId>要素(例えば912、1011)にこの印刷予約IDをセットし、印刷予約IDの発行処理を終了して(S1706)、図13のS1323へ進む。ステップS1704で発行される印刷予約IDは、プリンタ3内で管理されるものであり、プリンタ3内で一意に決定される値である。ステップS1705において、プリンタ3は<ans:ReceivedId>要素(例えば912、1011)に「None」をセットし、印刷予約IDの発行処理を終了して(S1706)、図13のS1323へ進む。このように、例えば、図14に示す印刷キューデータベースに新規の印刷ジョブ要求の予約を受け付けることが可能な空領域が存在しない場合、プリンタ3は、PC(PC1)からの印刷ジョブ要求の予約を受け付けることができない。この場合、図6に示すコーリングシーケンスに従って、PC(PC1)が印刷ジョブ要求を再度発行してくるので、プリンタ3は、図14に示す印刷キューデータベースに新規の印刷ジョブ要求を受け付けることが可能な空領域が存在した時に、この印刷ジョブ要求の予約を受け付ける。
図19はプリンタ3における印刷キューデータベースの更新割り込みの処理を表すフローチャートである。図19のフローに係るプログラムは、ROM16に記憶されており、RAM17に読み出され、CPU15により実行される。プリンタ3に内蔵されているタイマーにより、180秒毎にこの割り込みが発生し、同図に示す処理が実行される。プリンタ3に内蔵されているタイマーにより、この割り込み処理が発生すると、同図のステップS1901が開始される。プリンタ3は内蔵されているタイマーから時刻や経過時間を計算可能なカウント値を取得してTime3に保存する。このカウント値の単位は「秒」である(S1902)。プリンタ3は、図14に示す印刷キューデータベース内の印刷ジョブ要求の予約の中から、最も優先順位の高いものの内容をピックアップして確認する(S1903)。プリンタ3は、ステップS1903でピックアップした印刷ジョブ要求の予約から「Time」欄にセットされているタイムカウント値を取得する(S1904)。プリンタ3は、Time3からステップS1904で取得したタイムカウント値を減算する(S1905)。プリンタ3は、ステップS1905の減算結果が既定時間(60秒)を超える場合ステップS1907へ進み、既定時間(60秒)以内の場合ステップS1908へ進む(S1906)。ステップS1907において、プリンタ3は、ステップS1903でピックアップした印刷ジョブ要求の予約を図14に示す印刷キューデータベース内から削除し、ステップS1910へ進む。この時、プリンタ3は、この印刷ジョブ要求の印刷予約ID(ans:ReceivedId)も削除する。ステップS1908において、プリンタ3は、ステップS1905の減算結果が既定時間(20秒)を超える場合ステップS1909へ進み、既定時間(20秒)以内の場合ステップS1910へ進む。ここで、この既定時間(20秒)は、図13のステップS1315で設定している20秒と同一の値としている。ステップS1909において、プリンタ3は、図14に示す印刷キューデータベース内において、ステップS1903でピックアップした印刷ジョブ要求の予約の印刷予約ID(ans:ReceivedId)を一旦削除する。そして、この印刷ジョブ要求をその印刷キューデータベース内の最後尾に移動して、最も優先順位の低い印刷ジョブ要求の予約となるように変更し、ステップS1910へ進む。ステップS1910において、プリンタ3が、全ての印刷ジョブ要求の予約の確認を完了した場合印刷キューデータベースの更新割り込みの処理を終了し(S1912)、完了していない場合ステップS1911へ進む。ステップS1911において、プリンタ3は、図14に示す印刷キューデータベース内において、ステップS1903でピックアップした印刷ジョブ要求の予約の、ピックアップした時点で次の優先順位の印刷ジョブ要求の予約に進み、ステップS1903へ戻る。尚、本実施例において、タイマー割り込みのインターバルを180秒としたが、この例に限られることなく、任意のインターバルを設定可能である。
また、プリンタ3の表示部21のタッチパネルや操作部20のボタン操作により、使用環境に応じた任意の適切な値を設定したりするように構成してもよい。
図13のステップS1315及び図19のステップS1908において、既定時間を20秒の固定のタイムアウト値を設定したが、この例に限られることなく、プリンタ3の使用環境やユーザが使用するネットワークの環境に応じて、例えば、10秒、20秒、30秒、60秒というような固定のタイムアウト値を設定したり、プリンタ3の表示部21のタッチパネルや操作部20のボタン操作により、使用環境に応じた任意の適切な値を設定したりするように構成してもよい。また、プリンタ3がネットワーク4上のPCをモニタし、その数に応じてネットワークの混雑状況を把握し、その混雑状況から最適なタイムアウト値を設定するように構成してもよい。
図19のステップS1906において、既定時間を60秒の固定のタイムアウト値を設定したが、この例に限られることなく、プリンタ3の使用環境やユーザが使用するネットワークの環境に応じて、例えば、30秒、60秒、90秒、120秒というような固定のタイムアウト値を設定したり、プリンタ3の表示部21のタッチパネルや操作部20のボタン操作により、使用環境に応じた任意の適切な値を設定したりするように構成してもよい。また、プリンタ3がネットワーク4上のPCをモニタし、その数に応じてネットワークの混雑状況を把握し、その混雑状況から最適なタイムアウト値を設定するように構成してもよい。
図12、図13、図19において、経過時間を計算する方法としてプリンタ3に内蔵されているタイマーから取得したカウント値を利用する方法を挙げたが、この例に限られることなく、例えば、プリンタ3に内蔵されているリアルタイムクロックから取得した時刻を利用すること等によっても、実現することができる。
本実施例では周辺装置の例としてプリンタ3のようなプリンタを挙げたが、プリンタ、FAX、スキャナ、ストレージ等を搭載したマルチファンクションプリンタ(以降、MFPと略す場合がある)にも、本発明は有効である。WSDを搭載したMFPの場合、プリンタ、FAX、スキャナのそれぞれの機能に対して、次に示すようなWSDの各Serviceを割り当てることが可能である。
機能 WSDのService 備考
プリンタ Print Service プリンタ機能用
FAX Print Service FAX機能用
スキャナ Scan Service
ここで、各機能のServiceに割り当てられているServiceIdは、次の通
りである。
プリンタ: <wsdp:ServiceId>http://schemas.abc.xxx/Printer</wsdp:ServiceId>
FAX: <wsdp:ServiceId>http://schemas.abc.xxx/Fax</wsdp:ServiceId>
スキャナ: <wsdp:ServiceId>http://schemas.abc.xxx/Scanner</wsdp:ServiceId>
プリンタ機能とFAX機能には、どちらもPrint Serviceが割り当てられていて、ServiceIDがプリンタ機能用とFAX機能用とで異なっている。その為、プリンタ機能とFAX機能のServiceTypeは、どちらもPrinterServiceTypeとなる。
前述した通り、ランゲージモニタ36は、WSDAPIsのGetPrinterElements( )関数を使って、PC1からプリンタ3にGetPrinterElementsRequestを発行して、プリンタ3からPC1に返されるGetPrinterElementsResponseを受け取ることができる。この時、GetPrinterElements( )関数に次に示すようにServiceTypeを指定してこの関数をコールすることで、GetPrinterElementsを利用することができる。
<portType name=“PrinterServiceType” wse:EventSource=“true”>
<operation name=“GetPrinterElements”>
<input message=“wprt:GetPrinterElementsRequestMsg”
wsa:Action=“http://schemas.yyyy.xxx/YYYY/MM/wdp/print/ GetPrinterElements”/>
<output message=“wprt:GetPrinterElementsResponseMsg”
wsa:Action=“http://schemas.yyyy.xxx/YYYY/MM/wdp/print/ GetPrinterElementsResponse”/>
</operation>
</portType>
しかしながら、前記MFPの場合、プリンタ機能とFAX機能のServiceTypeはどちらもPrinterServiceTypeという同一のタイプである為、ServiceTypeを指定して前記関数をコールしても、プリンタ機能とFAX機能を区別してその機能に関する情報を取得することができない、という問題に直面する。このような問題に対して、例えば前記MFPの場合には、ランゲージモニタ36がServiceIDを指定して前記関数をコールすることで、プリンタ機能またはFAX機能を指定して、その指定した機能に関する情報をGetPrinterElementsを利用して取得することができる。これにより、プリンタ機能とFAX機能を備えるMFPに対しても、誤動作を防止して、正確な制御が可能な周辺装置制御システムを実現することができる。
CreatePrintJobRequestはWSDのPrint Serviceにおける印刷ジョブの開始要求であり、GetPrinterElementsRequestはWSDのPrint Serviceにおけるプリンタ情報取得要求である。
このように、本発明では、ある一定時間(同図では5秒)以内にステップS1202で受信したCreatePrintJobRequestとステップS1302で受信したGetPrinterElementsRequest(ans:ABCCommand)のそれぞれに含まれる情報を関連付けて、1つの印刷ジョブ要求の予約として扱い、印刷キューデータベースに登録し、プリンタ3内で一意に決定される印刷予約IDで印刷ジョブ要求の予約を管理することを特徴とする。つまり、印刷ジョブの開始要求とプリンタ情報取得要求というような異なる2つの要求が一定時間以内に受信された場合において、これらの要求に含まれる情報を関連付けて、1つの印刷ジョブ要求の予約として扱い、印刷キューデータベースに登録し、プリンタ3内で一意に決定される印刷予約IDで印刷ジョブ要求の予約を管理することを特徴とする。これにより、複数の印刷ジョブを受け付けることができず、1つの印刷ジョブだけを受け付けることができるようなプリンタにおいても、1台または複数のPCから発行された複数の印刷ジョブを発行された順序通り正確に印刷することができる。
<実施形態2>
実施形態1では、例えば、1台のPCからあるユーザが同じドキュメントを何度も繰り返して連続印刷するようなケースにおいて、スプーラ40がこれらの印刷ジョブを複数のスレッド等により並列処理できるケースを想定した。このようなケースにおいて、これら複数の印刷ジョブ要求、すなわち複数のCreatePrintJobRequest内の<wprt:JobName>要素(例えば1102)にセットされている印刷ジョブ名と<wprt:JobOriginatingUserName>要素(例えば1103)にセットされているユーザ名が、各印刷ジョブ要求間で同一の印刷ジョブ名とユーザ名になってしまう為、これらの印刷ジョブ要求を区別することができない、という問題があった。このような問題に対して、実施形態1では、スプーラ40から発行されたジョブIDを印刷キューデータベース内に保持する情報に含めることで、これらの印刷ジョブを識別し、前記問題を解決した。そして、プリンタ3が印刷ジョブ要求の予約を一元管理する方法の中から、最も容易な方法として、<ans:ReceivedId>要素(例えば912、1011)にセットされている印刷予約ID、または<lans:TimeStamp>要素(例えば1810)にセットされている、前記印刷予約IDに相当するタイムスタンプを利用する例を挙げた。
他の例として、前述したような、1台のPCからあるユーザが同じドキュメントを何度も繰り返して連続印刷するようなケースにおいて、スプーラ40がこれらの印刷ジョブを複数のスレッド等により並列処理することができず、優先順位の最も高い印刷ジョブを1つのスレッドでシーケンシャルに処理するケースを考える。このようなケースでは、1台のPCからあるユーザが同じドキュメントを何度も繰り返して連続印刷しても、スプーラ40は、プリンタキュー32にスタックされている印刷ジョブの中で優先順位の最も高い印刷ジョブだけを処理する。従って、例えば、WSDプロトコルだけを利用するケースを考えた場合、印刷予約IDやタイムスタンプを使わなくても、図14に示す印刷キューデータベースの中に記された次の3つの情報、
「Computer Name」欄のコンピュータ名、
「wprt:JobName」欄の印刷ジョブ名、
「wprt:JobOriginatingUserName」欄のユーザ名を使って、印刷ジョブ要求の予約を一元管理することが可能である。また、WSDプロトコルに加えて、IHVの独自プロトコルが混在するケースを考えた場合も、印刷ジョブ名とユーザ名の情報を図18に示すStartJobに加えることで、印刷予約IDやタイムスタンプを使わなくても、印刷ジョブ要求の予約を一元管理することが可能である。
但し、この実施形態2で挙げた例は、スプーラ40が複数の印刷ジョブを複数のスレッド等により並列処理することができず、優先順位の最も高い印刷ジョブを1つのスレッドでシーケンシャルに処理するケースに対してのみ有効なものである。
IHVの独自プロトコルの例としては、ネットワーク用のIHVの独自プロトコル(IHV Native)、あるいはローカル(USB)用のIHVの独自プロトコル(IHV Native 2)等が挙げられる。
以下、図22〜図24を用いて、詳細を説明する。
図22はプリンタ3が受け付けて予約した印刷ジョブ要求を管理する印刷キューデータベースを表す図である。同図は本発明の特徴を最もよく表す図の内の1つである。同図に示す印刷キューデータベースは図14(c)をベースにしたものであるので、実施形態1において、図14(c)で既に説明した内容に関してはその説明を省略する。図22と図14(c)を比較した場合の差異は、図14(c)には「ans:ReceivedId/lans:TimeStamp」欄が用意されている点である。この欄には、<ans:ReceivedId>要素(例えば912、1011)にセットされている印刷予約ID、またはプリンタ3がIHVの独自プロトコルを使ってPCに発行する<lans:TimeStamp>要素(例えば1810)にセットされているタイムスタンプを表す情報が格納される。図22には「ans:ReceivedId/lans:TimeStamp」欄が用意されておらず、前記印刷予約IDや前記タイムスタンプを格納する必要が無い。
図23はプリンタ3におけるCreatePrintJobの処理を表すフローチャートである。同図は本発明の特徴を最もよく表す図の内の1つである。図23のフローに係るプログラムは、ROM16に記憶されており、RAM17に読み出され、CPU15により実行される。PC(PC1)からプリンタ3にCreatePrintJobRequest(例えば図11(a))が発行されて、プリンタ3がこれを受け付けると、同図のステップS2301が開始される。プリンタ3は、前記CreatePrintJobRequestを受信した時(S2302)、プリンタ3に内蔵されているタイマーから時刻や経過時間を計算可能なカウント値を取得してTime1に保存する(S2303)。このカウント値の単位は「秒」である。プリンタ3は、前記CreatePrintJobRequestから<wprt:JobName>要素1102にセットされている印刷ジョブ名と、<wprt:JobOriginatingUserName>要素1103にセットされているユーザ名を取得する(S2304)。プリンタ3はPC1のコンピュータ名(Computer Name)を取得する(S2305)。本実施例では、WSDのPrint Service宛てのHTTP POSTでのTCP受信ソケットからIPアドレスを取得し、このIPアドレスをもとにコンピュータ名を取得する。尚、本実施例では説明をわかりやすくする為に、このようにIPアドレスからコンピュータ名を取得して、このコンピュータ名を用いてPCを特定して各処理を行っているが、IPアドレスを用いてPCを特定して各処理を行ってもよい。プリンタ3は、前記印刷ジョブ名と前記ユーザ名と前記コンピュータ名を一時的に保存する(S2306)。プリンタ3は、前記コンピュータ名をもとに、図22に示す印刷キューデータベース内に既にステップS2302で受信したCreatePrintJobRequestで開始要求された印刷ジョブの印刷ジョブ要求の予約が存在するかを確認する(S2307)。図22に示す印刷キューデータベース内に前記印刷ジョブ要求の予約が既に存在する場合ステップS2309へ進み、存在しない場合ステップS2313へ進む(S2308)。ステップS2309において、プリンタ3は、図22に示す印刷キューデータベースから前記コンピュータ名で予約されている印刷ジョブ予約の「Time」欄にセットされているタイムカウント値を取得し、ステップS2303で保存されたTime1からこのタイムカウント値を減算して、最後にこの印刷ジョブ予約が更新された時からの経過時間を計測する。プリンタ3は、この経過時間が既定時間(ここでは20秒に設定)を超える場合ステップS2311へ進み、既定時間以内の場合ステップS2312へ進む(S2310)。ステップS2311において、プリンタ3は、図22に示す印刷キューデータベース内において、この印刷ジョブ要求をその印刷キューデータベース内の最後尾に移動して、最も優先順位の低い印刷ジョブ要求の予約となるように変更し、ステップS2312へ進む。この時、もし図22に示す印刷キューデータベース内に空領域が無い場合、プリンタ3は、この印刷ジョブ要求の予約を破棄して、印刷キューデータベース内に印刷ジョブ要求の予約として格納しない。ステップS2312において、プリンタ3は、前記コンピュータ名をもとに、図22に示す印刷キューデータベースに印刷ジョブ要求の予約として各情報を登録して、印刷キューデータベースを更新する。この時、プリンタ3は、「Time」欄にセットされているタイムカウント値をTime1に保存されている値で更新する。ステップS2313において、プリンタ3は、図22に示す印刷キューデータベースにステップS2302で受信したCreatePrintJobRequestで開始要求された印刷ジョブの印刷ジョブ要求を登録する。図22に示す印刷キューデータベース内にステップS2302で受信したCreatePrintJobRequestで開始要求された印刷ジョブより優先順位の高い他の印刷ジョブ要求の予約が有る場合ステップS2315へ進み、無い場合ステップS2316へ進む(S2314)。ステップS2316において、プリンタ3は、ステップS2302で受信した印刷ジョブ要求CreatePrintJobRequestに対して、この印刷ジョブを受け付けて実行することを表す応答としてCreatePrintJobResponse(例えば図11(b))をPC(PC1)に返し、CreatePrintJobの処理を終了する(S2317)。ステップS2315において、プリンタ3は、ステップS2302で受信した印刷ジョブ要求CreatePrintJobRequestに対して、この印刷ジョブを受け付けることができなかったことを表すFault(ServerErrorNotAcceptingJobs)をPC(PC1)に返し、CreatePrintJobの処理を終了する(S2317)。
図24はプリンタ3におけるGetPrinterElementsの処理を表すフローチャートである。同図は本発明の特徴を最もよく表す図の内の1つである。図24のフローに係るプログラムは、ROM16に記憶されており、RAM17に読み出され、CPU15により実行される。PC(PC1)からプリンタ3にGetPrinterElementsRequest(例えば図8(a))が発行されて、プリンタ3がこれを受け付けると、同図のステップS2401が開始される。プリンタ3は、前記GetPrinterElementsRequestを受信した後(S2402)、前記GetPrinterElementsRequestから<wprt:Name>要素(例えば801)にセットされている値を確認する(S2403)。ステップS2403において、前記GetPrinterElementsRequestの中に複数の<wprt:Name>要素が存在する場合があるので、プリンタ3は取得した全ての<wprt:Name>要素にセットされている値を一時的に保存しておく。<wprt:Name>要素にセットされている値として、wprt:PrinterDescriptionが見つかった場合ステップS2405へ進み、見つからなかった場合ステップS2407へ進む(S2404)。ステップS2405において、プリンタ3は<ans:MultipleJobsControl>要素802に「true」をセットし、内蔵されているタイマーから時刻や経過時間を計算可能なカウント値を取得してTime2に保存する(S2406)。このカウント値の単位は「秒」である。ステップS2407において、プリンタ3はPC1のコンピュータ名(Computer Name)を取得する。プリンタ3は、前記コンピュータ名をもとに、図22に示す印刷キューデータベース内にこのコンピュータ名のPCから図23のステップS2302で既に受信したCreatePrintJobRequestで開始要求された印刷ジョブの印刷ジョブ要求の予約が存在するかを確認する(S2408)。図22に示す印刷キューデータベース内に前記印刷ジョブ要求の予約が既に存在する場合ステップS2410へ進み、存在しない場合ステップS2414へ進む(S2409)。ステップS2410において、プリンタ3は、図22に示す印刷キューデータベースから前記コンピュータ名で予約されている印刷ジョブ予約の「Time」欄にセットされているタイムカウント値を取得し、ステップS2406で保存されたTime2からこのタイムカウント値を減算して、最後にこの印刷ジョブ予約が更新された時からの経過時間を計測する。プリンタ3は、この経過時間が既定時間(ここでは20秒に設定)を超える場合ステップS2412へ進み、既定時間以内の場合ステップS2413へ進む(S2411)。ステップS2412において、プリンタ3は、図22に示す印刷キューデータベース内において、この印刷ジョブ要求をその印刷キューデータベース内の最後尾に移動して、最も優先順位の低い印刷ジョブ要求の予約となるように変更し、ステップS2413へ進む。この時、もし図22に示す印刷キューデータベース内に空領域が無い場合、プリンタ3は、この印刷ジョブ要求を破棄して、印刷キューデータベース内に印刷ジョブ要求の予約として格納しない。ステップS413において、プリンタ3は、前記コンピュータ名をもとに、図22に示す印刷キューデータベースに印刷ジョブ要求の予約として各情報を登録して、印刷キューデータベースを更新する。この時、プリンタ3は、「Time」欄にセットされているタイムカウント値をTime2に保存されている値で更新する。プリンタ3は、ステップS2402で受信したGetPrinterElementsRequestに対する応答として、GetPrinterElementsResponseをPC(PC1)に返し(S2414)、GetPrinterElementsの処理を終了する(S2415)。
<実施形態3>
本実施形態における図5、図6、図7、図16にそれぞれ示す各コーリングシーケンス、図12、図13、図17、図19、図20、図21、図23、図24にそれぞれ示す各フローチャートの実行によって実現できる各機能が、外部からインストールされるプログラムによって、情報処理装置によって実現されるようにしてもよい。そして、その場合、CD−ROMやフラッシュメモリやフレキシブルディスク等の記憶媒体により、あるいはネットワークを介して外部の記憶媒体から、プログラムを含む情報群が情報処理装置や周辺装置に供給される場合でも、本発明は適用されるものである。
このように、本発明は、以下の処理を実行することによっても達成される。即ち、前述した実施形態の機能を実現するソフトウェアのプログラムコードを記録した記憶媒体を、システムあるいは装置に供給し、そのシステムあるいは装置のコンピュータ(またはCPUやMPU)が記憶媒体に格納されたプログラムコードを読出す処理である。この場合、記憶媒体から読み出されたプログラムコード自体が本発明の新規な機能を実現することになり、そのプログラムコードを記憶した記憶媒体は本発明を構成することになる。プログラムコードを供給するための記憶媒体としては、例えば、フレキシブルディスク、ハードディスク、光ディスク、光磁気ディスク、CD−ROM、CD−R、磁気テープ、不揮発性のメモリカード、ROM、EEPROM等を用いることができる。
また、コンピュータが読み出したプログラムコードを実行することにより、前述した実施形態の機能が実現されるだけでなく、そのプログラムコードの指示に基づき、コンピュータ上で稼働しているOS等が実際の処理の一部または全部を行い、その処理によって前述した実施形態の機能が実現される場合も含まれることは言うまでもない。
本発明の実施の形態では、プリンタの例としてカラーインクジェットプリンタを使用したが、この例に限られることなく、例えば、モノクロLBP等の任意のプリンタを使用することができる。
本発明の実施の形態では情報処理装置としてパーソナルコンピュータを想定したが、この例に限られることなく、例えばDVDプレーヤー、ゲーム、セットトップボックス、インターネット家電等、同様な使用方法が可能な任意の情報処理装置(端末)に対して実現することができ、有効である。
本発明の実施の形態では、周辺装置としてプリンタを例示しているが、周辺装置として他に、複写機、ファクシミリ、スキャナ、デジタルカメラ、及びこれらの複合機能を備える装置等のいずれかが、本発明の適用対象となり得る。
本発明の実施の形態では、OSに例としてWindows(登録商標) Vistaと同等のOSを使用したが、これらのOSに限られることなく、任意のOSを使用することができる。
本発明の実施の形態では、ネットワーク4の構成例としてEthernet(登録商標)を用いたが、この例に限られることなく、他の任意のネットワーク構成であってもよい。
本発明の実施の形態では、PC1、PC2、PC5とプリンタ3との間のインタフェースとして、USBやEthernet(登録商標)を用いたが、このインタフェースに限られることなく、例えば、無線LAN、IEEE1394、Bluetooth等の任意のインタフェースを用いるようにしてもよい。
本発明の実施の形態では、Webサービスのプロトコルの例としてWSDを挙げたが、この例に限られることなく、例えばIHVの独自プロトコル等の任意のプロトコルを用いるようにしてもよい。
本発明の実施の形態では、WSDのPrint Service宛てのHTTP POSTでのTCP受信ソケットからIPアドレスを取得し、このIPアドレスをもとにコンピュータ名取得して、このコンピュータ名を用いてPCを特定している。この例に限られることなく、例えば、WSDのPrint Service宛てのHTTP POSTでのTCP受信ソケットからIPアドレスを取得して、このIPアドレスを用いてPCを特定する等の、他の手段を利用してPCを特定してもよい。このようにIPアドレスを利用することで、WSDのプロトコル内で2バイトコードを取り扱うような考慮が不要となり、プログラムを簡素化でき、コーディングミスを最小限に抑えることができるので、品質を向上することができる。
本発明の実施の形態では、印刷ジョブの開始要求であるCreatePrintJobオペレーション(図16のS1611(図21の(a)のステップS2102))と、プリンタに関する情報を取得する為に利用されるGetPrinterElementsオペレーション(図16のS1621(図20のステップS2016))を利用して、プリンタが印刷ジョブ要求の予約を受け付ける例を挙げた。この例に限られることなく、例えば、GetPrinterElementsオペレーションの代わりに、印刷ジョブに関する情報を取得する為に利用されるGetJobElementsオペレーション等のWSDのPrint Service Definitionで定義されている他のオペレーションを利用してもよい。