[C#] How to create an event for print jobs being added? - Overclock.net - An Overclocking Community

Forum Jump: 

[C#] How to create an event for print jobs being added?

 
Thread Tools
post #1 of 2 (permalink) Old 01-01-2010, 04:32 PM - Thread Starter
Retired Staff
 
Join Date: Mar 2007
Location: Florida, United States
Posts: 15,199
Rep: 417 (Unique: 290)
I'm looking to create an event that triggers when a print job is added. In that event i want to copy the job and print it on another printer as well. Anyone have any idea where to start? My research has turned up nothing.
Licht is offline  
Sponsored Links
Advertisement
 
post #2 of 2 (permalink) Old 01-01-2010, 11:21 PM
 
Join Date: Sep 2009
Location: Orlando, FL
Posts: 5,000
You will have to utilize the Print Spooler API. Right click the "References", click "Add Reference" and search through until you find the correct library.

http://support.microsoft.com/kb/160129/EN-US/

http://support.microsoft.com/kb/196805

http://support.microsoft.com/kb/158828/EN-US/

Code:
 BOOL ListJobsForPrinter( LPTSTR szPrinterName )
   {

   HANDLE         hPrinter;
   DWORD          dwNeeded, dwReturned, i;
   JOB_INFO_1     *pJobInfo;

   // You need a printer handle, open the printer
   if( ! OpenPrinter( szPrinterName, &hPrinter, NULL ) )
     return FALSE;

   // First you call EnumJobs() to find out how much memory you need
   if( ! EnumJobs( hPrinter, 0, 0xFFFFFFFF, 1, NULL, 0, &dwNeeded,
                   &dwReturned ) )
   {
     // It should have failed, but if it failed for any reason other
     // than "not enough memory", you should bail out
     if( GetLastError() != ERROR_INSUFFICIENT_BUFFER )
     {
       ClosePrinter( hPrinter );
       return FALSE;
     }
   }
   // Allocate enough memory for the JOB_INFO_1 structures plus
   // the extra data - dwNeeded from the previous call tells you
   // the total size needed
   if( (pJobInfo = (JOB_INFO_1 *)malloc( dwNeeded )) == NULL )
   {
     ClosePrinter( hPrinter );
     return FALSE;
   }
   // Call EnumJobs() again and let it fill out our structures
   if( ! EnumJobs( hPrinter, 0, 0xFFFFFFFF, 1, (LPBYTE)pJobInfo,
                   dwNeeded, &dwNeeded, &dwReturned ) )
   {
     ClosePrinter( hPrinter );
     free( pJobInfo );
     return FALSE;
   }
   // You're done with the printer handle, close it
   ClosePrinter( hPrinter );

   // dwReturned tells how many jobs there are
   // Here, you'll simply display the number of jobs found
   printf( "%d jobs\
", dwReturned );
   // It's easy to loop through the jobs and access each one
   for(i=0;i<dwReturned;i++)
   {
     // pJobInfo[i] is a JOB_INFO_1 struct for that job
     // so here you could do whatever you want for each job
     printf( "[%d] [%s]\
", pJobInfo[i].JobId, pJobInfo[i].pDocument );
   }

   // Clean up
   free( pJobInfo );
   return TRUE;
 }
http://support.microsoft.com/kb/160129/EN-US/

It seems that you can monitor print events with two methods: polling or events. In this case you are interested in events. I recommend using events, because polling after a specified interval uses system resources. There is also a chance that an event will be missed between polls.


Quote:
Monitoring Print Queues by Events
Event-driven monitoring is a technique of gathering information when changes occur, rather than on some arbitrary periodic basis. It is superior to polling in that it is process efficient and it does not miss information that passes between the polling period of the polling technique.

Event-driven monitoring of printers is possible on Windows NT by using Change Notifications. Printer Change Notifications on Windows NT operate with process synchronization objects. These objects are mutexs that become signaled when a desired change occurs on the target printer object.

Like the polling technique, the event driven monitoring is located in the NotificationUpdate() function in the Threads.C module. This function implements a loop that is controlled by the signaled state of the Printer Change Notification object. As each change or set of changes occurs on the printer, the object becomes signaled triggering the loop to retrieve details of the changes and update the view. The loop is also controlled by mutexs for refreshing the view and terminating the monitoring.

Two things should be considered when Printer Change Notifications are used.

First, multiple changes can be combined into a single change notification. This is necessary because many changes can occur in the time period between notifications. Therefore, care should be taken when writing code to parse the buffer returned by FindNextPrinterChangeNotification() because it may contain many unrelated changes.

Second, it is possible for the changes that occur to overflow the change notification mechanism. When this happens, a special call to FindNextPrinterChangeNotification() must be made to refresh the list of changes.

The sample source code properly deals with both of these possibilities.
I hope this helps.

EDIT:
http://www.codeproject.com/KB/printi...atchvbnet.aspx
Code:
<DllImport("winspool.drv", EntryPoint:="OpenPrinterA", _ 
    SetLastError:=True, CharSet:=CharSet.Ansi, _ 
    ExactSpelling:=True, _ 
    CallingConvention:=CallingConvention.StdCall)> _ 
    Public Shared Function OpenPrinter(ByVal pPrinterName As String, _ 
    ByRef phPrinter As Int32, _ 
    ByVal pDefault As Int32) As Boolean 

    End Function 

<DllImport("winspool.drv", EntryPoint:="ClosePrinter", _ 
    SetLastError:=True, _ 
    ExactSpelling:=True, _ 
    CallingConvention:=CallingConvention.StdCall)> _ 

    Public Shared Function ClosePrinter _
    (ByVal hPrinter As Int32) As Boolean 

    End Function
This of course is VB, but the DLLImport function in C# is almost identical, and this snippet shouldn't be that hard to understand.
chatch15117 is offline  
Reply

Quick Reply
Message:
Options

Register Now

In order to be able to post messages on the Overclock.net - An Overclocking Community forums, you must first register.
Please enter your desired user name, your email address and other required details in the form below.
User Name:
If you do not want to register, fill this field only and the name will be used as user name for your post.
Password
Please enter a password for your user account. Note that passwords are case-sensitive.
Password:
Confirm Password:
Email Address
Please enter a valid email address for yourself.
Email Address:

Log-in



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Show Printable Version Show Printable Version
Email this Page Email this Page


Forum Jump: 

Posting Rules  
You may post new threads
You may post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off