Saturday, January 24, 2009

Printer status monitoring II

Since I developed the small class and application for monitoring the status of printers and jobs I've set upon improving it.  Specifically I was aiming to improve the mechanism it uses to track changes to the printers and print jobs.

There are really two options for this type of processing, you either poll the printers and queues on a regular basis or you make use of some type of notification process which will wake up your processing when an event occurs.

The first incarnation of the printer monitor test application relied on simple polling since I wasn't actually developing that part of the functionality - I was interested in getting the status information for the printers and jobs.

But, having the ability to handle the capture of printer and job state changes looks useful and I set about improving on the simple polling technique.

Windows implements a printer event notification process through the FindFirstPrinterChangeNotification API and its companion API's FindNextPrinterChangeNotification and FindClosePrinterChangeNotifcation.

Prior to calling FindFirst... you need to set up two structures, PRINTER_NOTIFY_OPTIONS_TYPE and PRINTER_NOTIFY_OPTIONS, which state the type of event and information you're interested in.  You also need an open handle for the printer being monitored.

FindFirst... returns a handle which can be used with the Windows wait functions (WaitForSingleObject etc.) which gives you your basic event monitoring process.

With the waitable handle you call the chosen wait API.  On return, and if the event fired, you can call FindNext... to get the event information allowing you to check printer and job status.  Then you're back to the wait function until the next event fires.

Once you're done, a call to FindClose... releases the resources associated with the wait.

Once contained in their own thread with some enable/disable processing you have a very effective and efficient print monitoring capability which isn't going to interfere with the UI threads.

Once these changes were in, and the rudimentary polling code removed, the monitoring application functioned just as before but with a reduction in system resource usage. It also has simpler access to a range of printer and job related status information which can be exposed through the component interface.

No comments: