
TechNet コラムへようこそ。このコラムでは、よく寄せられるシステム管理スクリプトに関する質問に Scripting Guys がお答えします。システム管理スクリプトについて質問がある場合は、scripter@microsoft.com (英語のみ) までお送りください。すべての質問に回答することはできないかもしれませんが、可能な限り対応いたします。
Hey, Scripting Guy! アーカイブも忘れずにチェックしてください。
今日の質問 : 特定のプリンタで出力が行われるたびに通知を受け取る方法はありますか
| Q | Scripting Guy さん、よろしくお願いします。特定のプリンタで出力が行われるたびに通知を受け取る方法はありますか。 -- IL | ||
| A | IL さん、こんにちは。Scripting Guy の 1 人がかつてある会社で夏季アルバイトを体験したことがありましたが、そこは、ビル管理スタッフ室にそこそこのプリンタが 1 台あるだけの会社でした。 過去のつらい経験からこれだけは確かです。このようなプリンタで出力するたびに通知を受け取るのにさほどの労力は必要ありません。 もちろん、叫んだりわめいたりして通知することもできますが、さいわい、もっと平和的かつ文化的な方法で特定のプリンタへの出力を知らせる通知を受け取ることができます。ここでは、次のような WMI イベント通知スクリプトを使用します。 strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colPrintJobs = objWMIService. _
ExecNotificationQuery("Select * From __InstanceCreationEvent " _
& "Within 10 Where TargetInstance ISA 'Win32_PrintJob'")
Do While True
Set objPrintJob = colPrintJobs.NextEvent
If InStr(objPrintJob.TargetInstance.Name, "atl-color-printer-1") Then
Wscript.Echo objPrintJob.TargetInstance.Document, Now
End If
Loop
穏やかな方法で通知を受け取るには、まず、ローカル コンピュータ上の WMI サービスに接続します。このスクリプトは、リモート コンピュータの名前を変数 strComputer に割り当てるだけで、リモート コンピュータ上の WMI サービスに接続するように簡単に変更できます。また、プリント サーバーに接続する必要はありません。このスクリプトは、監視するプリンタ (この場合は atl-color-printer という名前のプリンタ) に接続するコンピュータで動作します。 WMI サービスに接続したら、次のコード行を実行します。 Set colPrintJobs = objWMIService. _
ExecNotificationQuery("Select * From __InstanceCreationEvent " _
& "Within 10 Where TargetInstance ISA 'Win32_PrintJob'")
上記のコードは、実際のイベント通知クエリです。このイベント通知クエリでは、Win32_PrintJob クラスの新しいインスタンスが作成されるたびに通知するように WMI に指示します。なぜでしょう。だれかが新しいドキュメントを印刷するたびに Win32_Print Job クラスの新しいインスタンスが生成されます。つまり、WIN32_PrintJob の新しいインスタンスが生成されるたびに通知を受け取れば、ドキュメントが印刷されたことを知ることができます。
ここで 1 つ、はっきりさせようと思います。イベント通知クエリがあれば、ドキュメントが印刷されるたびにスクリプトが知らせてくれますが、それで本当に知ったことになりますか。どのようなイベントが発生しているのかを知りたければ、そのような通知を送信するコードを追加する必要があります。このサンプル スクリプトでは、非常に簡単なフォームの通知を使用することにします。つまり、印刷されたドキュメントの名前と印刷の開始時刻をエコー バックする通知です。コードは次のようになります。 Do While True
Set objPrintJob = colPrintJobs.NextEvent
If InStr(objPrintJob.TargetInstance.Name, "atl-color-printer-1") Then
Wscript.Echo objPrintJob.TargetInstance.Document, Now
End If
Loop
ここでは、永久に実行される Do Loop を設定しました (Do While True は基本的に、True である間はループが実行され続けます)。なぜこの処理を行うのでしょうか。IL さんは、プリンタを常時監視し、ドキュメントが印刷されるたびに通知を受信したいわけですよね。その場合、無限ループ内に通知コードを配置するのが最も簡単な方法です。 次のコード行を見てください。 Set objPrintJob = colPrintJobs.NextEvent スクリプトがこのコード行に達すると、スクリプトは追跡を停止し、NextEvent の発生を待ちます。もちろんこの場合のイベントとは、Win32_PrintJob クラスの新しいインスタンスの作成です。ドキュメントが印刷されない (そして、このクラスの新しいインスタンスも作成されない) 場合、スクリプトはこの行で永久に待機し、次のイベント発生を律儀に待ち続けます。 次のイベントが発生し、ドキュメントの印刷が行われた場合、何をすればよいのでしょうか。まずは、ドキュメントが対象プリンタで出力されているかどうかをチェックする必要があります。 If InStr(objPrintJob.TargetInstance.Name, "atl-color-printer-1") Then ここでは InStr 関数を使用します。それは、印刷ジョブ Name が少なくともネットワーク プリンタで\\\\atl-ps-01\\atl-color-printer-1, 226 のようになっているためです。プリンタのネットワーク パスに加え、226 などのジョブ ID が個々の印刷ジョブに割り当てられているため、長大な文字列になります。ここでは、文字列 atl-color-printer-1 が印刷ジョブ Name に含まれているかどうかをチェックします。含まれている場合、ドキュメントはプリンタ atl-color-printer-1 で出力されています。
InStr 関数が True を返した場合、つまり文字列 atl-color-printer-1 が見つかった場合は、ドキュメントの名前と印刷の開始時刻をエコー バックします。 Wscript.Echo objPrintJob.TargetInstance.Document, Now これで終わりです。その後はループに戻り、次のイベントの発生を待ちます。監視を停止する場合は、スクリプトを実行しているプロセス (Cscript.exe または Wscript.exe) を終了します。 また、ドキュメントが印刷されたことをエコー バックする方法の代わりに、.WAV ファイルを再生して音声で通知するスクリプトを記述することもできます。これは、ご自分で試してください。おそらく、「経験済みだ。もう何年も前なのに、まだ耳鳴りがするよ」と言われるでしょう。 |
Hey, Scripting Guy!- アーカイブもチェックしてください。