The .NET Printer Monitor Component - Service example

This example is an extensible windows service that monitors one or more printers and responds to their events (such as when a job is added or removed or when the printer details change)

Demonstrates

Requirements

Download

You can download the source code and the compiled service here : PrinterMonitorService.zip (118kb)

How to use this example

Setting the printer monitoring options

The service options are set in the configuration file called PrinterMonitorService.exe.config. An example of the content of this file is:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
   <configSections>
      <!-- Extra custom configuration sections -->
      <section name="printerEventListeners"
               type="PrinterMonitorService.CustomConfigurationSectionReaders.PrinterEventListenersSectionReader, PrinterMonitorService" />
               
      <section name="printJobEventListeners"
               type="PrinterMonitorService.CustomConfigurationSectionReaders.PrintJobEventListenersSectionReader, PrinterMonitorService" />         
      <section name="monitoredPrinters"
               type="PrinterMonitorService.CustomConfigurationSectionReaders.MonitoredPrintersSectionReader, PrinterMonitorService" />         
   </configSections>
    
    <printerEventListeners>
       <!-- Key = the unique name by which the listener is known,
            ClassType = the full type name of the class implementing IPrinterEventListenerBase ,
            CommandLine = startup parameters for that class -->
       <printerEventListener key="printerEventListener1" 
           classType="PrinterMonitorService.PrinterMonitorLogfileListener"
           commandLine="c:\Temp\printerListener1.log" />
    </printerEventListeners>
    
    <printJobEventListeners>
       <!-- Key = the unique name by which the listener is known,
            ClassType = the full type name of the class implementing IPrinterEventListenerBase ,
            CommandLine = startup parameters for that class -->
       <printJobEventListener key="printJobEventListener1" 
           classType="PrinterMonitorService.PrintJobMonitorLogfileListener"
           commandLine="c:\Temp\printJobListener1.log" />
    </printJobEventListeners>
    
    <monitoredPrinters>
         <!-- DeviceName = The unique name by which the printer is known
           -->
         <monitoredPrinter DeviceName="HP LaserJet 5L"/>
         <monitoredPrinter DeviceName="Microsoft Office Document Image Writer"/>
    </monitoredPrinters>
      
    <appSettings>
      <!-- Monitor level...1=Max, 2=Min, 3=None-->
      <add key="MonitorJobEventInformationLevel" value="1"/>
      <!-- Monitor Printer Change Events? "False"=No, "True"=Yes -->
      <add key="MonitorPrinterChangeEvent" value="True"/>
      <!-- Monitor Job Added Events?  -->
      <add key="MonitorJobAddedEvent" value="True"/>
      <!-- Monitor Job Deleted Events?  -->
      <add key="MonitorDeletedEvent" value="True"/>
      <!-- Monitor Job Set Events?  -->
      <add key="MonitorJobSetEvent" value="True"/>
      <!-- Monitor Job Written Events?  -->
      <add key="MonitorJobWrittenEvent" value="True"/>
                  
    </appSettings>
    
    <system.diagnostics>
       <switches>
          <!-- Printer Monitor Component tracing : values can be
                 Off=0
                 Error=1
                 Warning=2
                 Info=3
                 Verbose=4
          -->
          <add name="PrinterMonitorComponent" value="2" />
          <add name="Application" value="4" />
       </switches>
       <trace autoflush="false" indentsize="4">
         <listeners>
           <add name="LogFileListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\Temp\PrinterMonitorService.log" />
         </listeners>
       </trace> 
    </system.diagnostics>
</configuration>
      

The <monitoredPrinters> section contains the printers to be monitored, uniquely keyed by their device name. Add or remove entries to this collection to specify which printers to monitor.

The <printerEventListeners> section is the collection of classes that will be notified when a printer in the collection being monitored is changed - for instance if the PrinterInformationChanged event is triggered.

The <printJobEventListeners> section is the collection of classes that will be notified when a print job event occurs on one of the printers being monitored - for instance if a job is added, deleted, set or written.

Installing the service

To install the service you can use the InstallUtil utility that comes as part of the Visual Studio set. e.g.

InstallUtil PrinterMonitorService.exe

The service will default to be manually initiated. To set the service running, open up the services window and select it in the list then press the button marked "start"

The windows service manager

Extending the example

As it stands the example just writes the printer and print job to one or more named log files. However you can implement your own custom event listeners to send emails, update databases or any number of possibilities. To do this simple write a class that inherits the base class PrintJobMonitorListenerBase or PrinterMonitorListenerBase as appropriate. The log file examples are:

'\\ --[PrinterMonitorLogfileListener]--------------------
'\\ Monitors printer change events to a logfile
'\\ (c) 2003 Merrion Computing Ltd
'\\ -----------------------------------------------------
Public Class PrinterMonitorLogfileListener
    Inherits PrinterMonitorListenerBase

#Region "Private members"
    Private _Logfilename As String
#End Region

#Region "Command line startup parameters"
    Public Overrides WriteOnly Property CommandLine() As String
        Set(ByVal Value As String)
            _Logfilename = Value
        End Set
    End Property
#End Region

#Region "OnPrinterInformationChanged"
    Public Overrides Sub OnPrinterInformationChanged(ByVal PrinterName As String, ByVal Location As String, ByVal Comment As String, ByVal JobCount As Integer)

        If Not _Logfilename = "" Then
            Dim jf As New System.IO.StreamWriter(_Logfilename, True)
            jf.WriteLine("Printer settings changed " & System.DateTime.Now.ToString)
            jf.WriteLine("Printer : " & PrinterName)
            jf.WriteLine("Location : " & Location)
            jf.WriteLine("Comment : " & Comment)
            jf.WriteLine("Pending jobs : " & JobCount.ToString)
            jf.Close()
        End If

    End Sub
#End Region

End Class