Solved

Get the number of pages printed on the printer

Posted on 2004-10-13
6
277 Views
Last Modified: 2012-08-13

 Hi,

 I need to know if there is a method (a WinAPI function maybe) which tells me the number of pages printed on a printer installed to the pc.
 I see that GetPrinter function is able to retrieve printer info. But i havent been able to find how to get the nr of pages printed.
 I am looking for a method\function.
 I am interested if I can count the number of pages from a moment on, not necessary how many pages where ever been printed on the printer.
 Another possibilty would be to use the printer test page. Ive heard that on the test page the printer writes the nr of pages printed. If i can save the printer to an image that would be ok too (but without actually printing the page).

 Thank you.
0
Comment
Question by:KIS
6 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 250 total points
ID: 12298270
This was an issue here a while ago (http:Q_20366052.html). The easiest way is IMHO to use "FindNextPrinterChangeNotification()" (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_0tym.asp and http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_390y.asp)- there is a "JOB_NOTIFY_TYPE" that has information about "JOB_NOTIFY_FIELD_TOTAL_PAGES" that will tell you how many pages are about to be printed. For a code sample, see http://nienie.com/~masapico/api_FindFirstPrinterChangeNotification.html - I hope your Japanese isn't as rusty as mine :o)

BTW, here's the code:

here's the code:

void DoPrtNotify()
{
     HANDLE hPrinter = INVALID_HANDLE_VALUE;
     HANDLE hNotify;
     BOOL b;
     PRINTER_NOTIFY_INFO *p;
     DWORD i;
     char *pBuf;
     DWORD *adwData;

     PRINTER_NOTIFY_OPTIONS no;
     PRINTER_NOTIFY_OPTIONS_TYPE not[2];
     WORD pnf[100], jnf[100];
     DWORD ChangeReason;

     no.Version = 2;
     no.Count = 2;
     no.pTypes = not;

     i = 0;
     pnf[i++] = PRINTER_NOTIFY_FIELD_SERVER_NAME;
     pnf[i++] = PRINTER_NOTIFY_FIELD_PRINTER_NAME;
     pnf[i++] = PRINTER_NOTIFY_FIELD_SHARE_NAME;
     pnf[i++] = PRINTER_NOTIFY_FIELD_PORT_NAME;
     pnf[i++] = PRINTER_NOTIFY_FIELD_DRIVER_NAME;
     pnf[i++] = PRINTER_NOTIFY_FIELD_COMMENT;
     pnf[i++] = PRINTER_NOTIFY_FIELD_LOCATION;
     pnf[i++] = PRINTER_NOTIFY_FIELD_SEPFILE;
     pnf[i++] = PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR;
     pnf[i++] = PRINTER_NOTIFY_FIELD_PARAMETERS;
     pnf[i++] = PRINTER_NOTIFY_FIELD_DATATYPE;
     pnf[i++] = PRINTER_NOTIFY_FIELD_ATTRIBUTES;
     pnf[i++] = PRINTER_NOTIFY_FIELD_PRIORITY;
     pnf[i++] = PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY;
     pnf[i++] = PRINTER_NOTIFY_FIELD_START_TIME;
     pnf[i++] = PRINTER_NOTIFY_FIELD_UNTIL_TIME;
     pnf[i++] = PRINTER_NOTIFY_FIELD_STATUS_STRING;
     pnf[i++] = PRINTER_NOTIFY_FIELD_CJOBS;
     pnf[i++] = PRINTER_NOTIFY_FIELD_AVERAGE_PPM;
     pnf[i++] = PRINTER_NOTIFY_FIELD_TOTAL_PAGES;
     pnf[i++] = PRINTER_NOTIFY_FIELD_PAGES_PRINTED;
     pnf[i++] = PRINTER_NOTIFY_FIELD_TOTAL_BYTES;
     pnf[i++] = PRINTER_NOTIFY_FIELD_BYTES_PRINTED;

     not[0].Type = PRINTER_NOTIFY_TYPE;
     not[0].Count = i;
     not[0].pFields = pnf;

     i=0;
     jnf[i++] = JOB_NOTIFY_FIELD_PRINTER_NAME;
     jnf[i++] = JOB_NOTIFY_FIELD_MACHINE_NAME;
     jnf[i++] = JOB_NOTIFY_FIELD_PORT_NAME;
     jnf[i++] = JOB_NOTIFY_FIELD_USER_NAME;
     jnf[i++] = JOB_NOTIFY_FIELD_NOTIFY_NAME;
     jnf[i++] = JOB_NOTIFY_FIELD_DATATYPE;
     jnf[i++] = JOB_NOTIFY_FIELD_PRINT_PROCESSOR;
     jnf[i++] = JOB_NOTIFY_FIELD_PARAMETERS;
     jnf[i++] = JOB_NOTIFY_FIELD_DRIVER_NAME;
     jnf[i++] = JOB_NOTIFY_FIELD_STATUS_STRING;
     jnf[i++] = JOB_NOTIFY_FIELD_DOCUMENT;
     jnf[i++] = JOB_NOTIFY_FIELD_PRIORITY;
     jnf[i++] = JOB_NOTIFY_FIELD_POSITION;
     jnf[i++] = JOB_NOTIFY_FIELD_START_TIME;
     jnf[i++] = JOB_NOTIFY_FIELD_UNTIL_TIME;
     jnf[i++] = JOB_NOTIFY_FIELD_TIME;
     jnf[i++] = JOB_NOTIFY_FIELD_TOTAL_PAGES;
     jnf[i++] = JOB_NOTIFY_FIELD_PAGES_PRINTED;
     jnf[i++] = JOB_NOTIFY_FIELD_TOTAL_BYTES;
     jnf[i++] = JOB_NOTIFY_FIELD_BYTES_PRINTED;

     not[1].Type = JOB_NOTIFY_TYPE;
     not[1].Count = 20;
     not[1].pFields = jnf;


     b = OpenPrinter(
          "\\\\ringo\\ringoprt",
          &hPrinter,
          NULL);

     if(!b) {
          printf("printer can not open(%d)\n", GetLastError());
          return;
     }

     hNotify = FindFirstPrinterChangeNotification(
          hPrinter,
          PRINTER_CHANGE_ALL,
          0,
          &no);

     if(hNotify == INVALID_HANDLE_VALUE) {
          printf("find first fail(%d)\n", GetLastError());
          ClosePrinter(hPrinter);
          return;
     }

     for(;;) {

          WaitForSingleObject(hNotify, INFINITE);

          no.Flags = 0;

          b = FindNextPrinterChangeNotification(
               hNotify,
               &ChangeReason,
               &no,
               &p);

          if(!b) printf("find next error(%d)\n", GetLastError());

          printf("\nCxg-6...\n");
          printf("\tJmR: ");

          if(ChangeReason & PRINTER_CHANGE_ADD_PRINTER) printf("v
^G     A ");
          if(ChangeReason & PRINTER_CHANGE_SET_PRINTER) printf("v
^L]hOX " );
          if(ChangeReason & PRINTER_CHANGE_DELETE_PRINTER) printf("v
^m ");
          if(ChangeReason & PRINTER_CHANGE_FAILED_CONNECTION_PRINTER) printf("Z18s ");
          if(ChangeReason & PRINTER_CHANGE_ADD_JOB) printf("WuG     A ");
          if(ChangeReason & PRINTER_CHANGE_SET_JOB) printf("Wu]hOX ");
          if(ChangeReason & PRINTER_CHANGE_DELETE_JOB) printf("Wum ");
          if(ChangeReason & PRINTER_CHANGE_WRITE_JOB) printf("Wu+] ");
          if(ChangeReason & PRINTER_CHANGE_ADD_FORM) printf("tH[G     A ");
          if(ChangeReason & PRINTER_CHANGE_SET_FORM) printf("tH[]hOX ");
          if(ChangeReason & PRINTER_CHANGE_DELETE_FORM) printf("tH[m ");
          if(ChangeReason & PRINTER_CHANGE_ADD_PORT) printf("|[gG     A ");
          if(ChangeReason & PRINTER_CHANGE_CONFIGURE_PORT) printf("|[g]hOX ");
          if(ChangeReason & PRINTER_CHANGE_DELETE_PORT) printf("|[gm ");
          if(ChangeReason & PRINTER_CHANGE_ADD_PRINT_PROCESSOR) printf("v
gvZbTG     A ");
          if(ChangeReason & PRINTER_CHANGE_DELETE_PRINT_PROCESSOR) printf("v
gvZbTm ");
          if(ChangeReason & PRINTER_CHANGE_ADD_PRINTER_DRIVER) printf("h     CoG     A ");
          if(ChangeReason & PRINTER_CHANGE_SET_PRINTER_DRIVER) printf("h     Co]hOX ");
          if(ChangeReason & PRINTER_CHANGE_DELETE_PRINTER_DRIVER) printf("h     Com ");
          if(ChangeReason & PRINTER_CHANGE_TIMEOUT) printf("^CAEg ");
          printf("\n");

          if(p != NULL) {
               for(i=0; i<p->Count; i++) {
                    pBuf = p->aData[i].NotifyData.Data.pBuf;
                    adwData = p->aData[i].NotifyData.adwData;

                    switch(p->aData[i].Type) {
                    case PRINTER_NOTIFY_TYPE:
                         printf("\tv
^Jm(no.%d)...", i);
                         switch(p->aData[i].Field) {
                         case PRINTER_NOTIFY_FIELD_SERVER_NAME:
                              printf("T[o<F%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_PRINTER_NAME:
                              printf("v
^<F%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_SHARE_NAME:
                              printf(" $L<F%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_PORT_NAME:
                              printf("|[g<F%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_DRIVER_NAME:
                              printf("h     Co<F%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_COMMENT:
                              printf("v
^L`>F%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_LOCATION:
                              printf("]uj
:%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_DEVMODE:
                              // DEVMODE structure
                              break;
                         case PRINTER_NOTIFY_FIELD_SEPFILE:
                              printf(" fXht@C <:%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR:
                              printf("v
gvZbT<:%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_PARAMETERS:
                              printf("v
gvZbTLp     [^:%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_DATATYPE:
                              printf("f[^Lm^:%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR:
                              // SECURITY_DESCRIPTOR
                              break;
                         case PRINTER_NOTIFY_FIELD_ATTRIBUTES:
                              printf("v
^LsT:\n");
                              if(PRINTER_ATTRIBUTE_QUEUED & adwData[0]) printf("\t\tL[\n");
                              if(PRINTER_ATTRIBUTE_DIRECT & adwData[0]) printf("\t\tv
^I<Zf[^pi\n");
                              if(PRINTER_ATTRIBUTE_DEFAULT & adwData[0]) printf("\t\tftH g\n");
                              if(PRINTER_ATTRIBUTE_SHARED & adwData[0]) printf("\t\t $L7i\n");
                              if(PRINTER_ATTRIBUTE_NETWORK & adwData[0]) printf("\t\tlbg[N\n");
                              if(PRINTER_ATTRIBUTE_HIDDEN & adwData[0]) printf("\t\t     B5v
^\n");
                              if(PRINTER_ATTRIBUTE_LOCAL & adwData[0]) printf("\t\t[J v
^\n");
                              if(PRINTER_ATTRIBUTE_ENABLE_DEVQ & adwData[0]) printf("\t\tjv5H"hLgp[/7i\n");
                              if(PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS & adwData[0]) printf("\t\ts| chLgpc7\n");
                              if(PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST & adwData[0]) printf("\t\tXv[ 3j=hLgpE     Is|7i\n");
                              if(PRINTER_ATTRIBUTE_WORK_OFFLINE & adwData[0]) printf("\t\tIt     Cs|\n");
                              if(PRINTER_ATTRIBUTE_ENABLE_BIDI & adwData[0]) printf("\t\tenable BIDI(?)\n");
                              if(PRINTER_ATTRIBUTE_RAW_ONLY & adwData[0]) printf("\t\t<Zf[^ML]\n");
                              break;
                         case PRINTER_NOTIFY_FIELD_PRIORITY:
                              printf(" ;]LDfxF%d\n", adwData[0]);
                              break;
                         case PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY:
                              printf("ftH gLDfx:%d\n", adwData[0]);
                              break;
                         case PRINTER_NOTIFY_FIELD_START_TIME:
                              printf("p     B\FHi
Jn
TF%02d:%02d\n", adwData[0]/60, adwData[0]%60);
                              break;
                         case PRINTER_NOTIFY_FIELD_UNTIL_TIME:
                              printf("ps     B\IHi
TF%02d:%02d\n", adwData[0]/60, adwData[0]%60);
                              break;
                         case PRINTER_NOTIFY_FIELD_STATUS:
                              if(adwData[0] & PRINTER_STATUS_PAUSED) printf("jb~ ");
                              if(adwData[0] & PRINTER_STATUS_ERROR) printf("G     [ ");
                              if(adwData[0] & PRINTER_STATUS_PENDING_DELETION) printf("pending_deletion ");
                              if(adwData[0] & PRINTER_STATUS_PAPER_JAM) printf(" l\h ");
                              if(adwData[0] & PRINTER_STATUS_PAPER_OUT) printf("ro ");
                              if(adwData[0] & PRINTER_STATUS_MANUAL_FEED) printf("manual_feed ");
                              if(adwData[0] & PRINTER_STATUS_PAPER_PROBLEM) printf("Lbh ");
                              if(adwData[0] & PRINTER_STATUS_OFFLINE) printf("It     C ");
                              if(adwData[0] & PRINTER_STATUS_IO_ACTIVE) printf("io_active ");
                              if(adwData[0] & PRINTER_STATUS_BUSY) printf("busy ");
                              if(adwData[0] & PRINTER_STATUS_PRINTING) printf("s| ");
                              if(adwData[0] & PRINTER_STATUS_OUTPUT_BIN_FULL) printf("output_bin_full ");
                              if(adwData[0] & PRINTER_STATUS_NOT_AVAILABLE) printf("not_available ");
                              if(adwData[0] & PRINTER_STATUS_WAITING) printf("R @ ");
                              if(adwData[0] & PRINTER_STATUS_PROCESSING) printf(" ");
                              if(adwData[0] & PRINTER_STATUS_INITIALIZING) printf("    
z     ; ");
                              if(adwData[0] & PRINTER_STATUS_WARMING_UP) printf("warming_up ");
                              if(adwData[0] & PRINTER_STATUS_TONER_LOW) printf("gi[*-H" ");
                              if(adwData[0] & PRINTER_STATUS_NO_TONER) printf("gi[*3" ");
                              if(adwData[0] & PRINTER_STATUS_PAGE_PUNT) printf("page_punt ");
                              if(adwData[0] & PRINTER_STATUS_USER_INTERVENTION) printf("user_intervention ");
                              if(adwData[0] & PRINTER_STATUS_OUT_OF_MEMORY) printf("out_of_memory ");
                              if(adwData[0] & PRINTER_STATUS_DOOR_OPEN) printf("door_open ");
                              if(adwData[0] & PRINTER_STATUS_SERVER_UNKNOWN) printf("server_unknown ");
                              if(adwData[0] & PRINTER_STATUS_POWER_SAVE) printf("power_save ");
                                   
                              break;
                         case PRINTER_NOTIFY_FIELD_STATUS_STRING:
                              printf("sTF%d\n", pBuf);
                         case PRINTER_NOTIFY_FIELD_CJOBS:
                              printf("L[I=_gj=WuL:%d\n", adwData[0]);
                              break;
                         case PRINTER_NOTIFY_FIELD_AVERAGE_PPM:
                              printf("Py[W =hL= Os|
T:%d*\n", adwData[0]);
                              break;
                         case PRINTER_NOTIFY_FIELD_TOTAL_PAGES:
                              printf("y[WF%d\n", adwData[0]);
                              break;
                         case PRINTER_NOTIFY_FIELD_PAGES_PRINTED:
                              printf("s|y[WF%d\n", adwData[0]);
                              break;
                         case PRINTER_NOTIFY_FIELD_TOTAL_BYTES:
                              printf("oCgF%d\n", adwData[0]);
                              break;
                         case PRINTER_NOTIFY_FIELD_BYTES_PRINTED:
                              printf("s|oCgF%d\n", adwData[0]);
                              break;
                         }
                         break;
                    case JOB_NOTIFY_TYPE:
                         printf("\tWuJm(no.%d, id:%d)...", i, p->aData[i].Id);
                         switch(p->aData[i].Field) {
                         case JOB_NOTIFY_FIELD_PRINTER_NAME:
                              printf("v
^<F%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_MACHINE_NAME:
                              printf("Wul, 3}V<F%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_PORT_NAME:
                              printf("|[gF%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_USER_NAME:
                              printf("Wul, 3[U<F%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_NOTIFY_NAME:
                              printf("Jmf[UF%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_DATATYPE:
                              printf("f[^Lm^:%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_PRINT_PROCESSOR:
                              printf("v
gvZbT<:%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_PARAMETERS:
                              printf("v
gvZbTVLp     [^:%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_DRIVER_NAME:
                              printf("h     Co<:%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_DEVMODE:
                              // DEVMODE
                              break;
                         case JOB_NOTIFY_FIELD_STATUS:
                              printf("WuLsT(flag):");
                              if(adwData[0] & JOB_STATUS_PAUSED) printf("jb~ ");
                              if(adwData[0] & JOB_STATUS_ERROR) printf("G     [ ");
                              if(adwData[0] & JOB_STATUS_DELETING) printf("m ");
                              if(adwData[0] & JOB_STATUS_SPOOLING) printf("Xv[  ");
                              if(adwData[0] & JOB_STATUS_PRINTING) printf("s| ");
                              if(adwData[0] & JOB_STATUS_OFFLINE) printf("It     C ");
                              if(adwData[0] & JOB_STATUS_PAPEROUT) printf("oM ");
                              if(adwData[0] & JOB_STATUS_PRINTED) printf("s|I9 ");
                              if(adwData[0] & JOB_STATUS_DELETED) printf("mI9 ");
                              if(adwData[0] & JOB_STATUS_BLOCKED_DEVQ) printf("blocked_dev_queue ");
                              if(adwData[0] & JOB_STATUS_USER_INTERVENTION) printf("user_intervention ");
                              if(adwData[0] & JOB_STATUS_RESTART) printf("
X^[g ");
                              printf("\n");
                              break;
                         case JOB_NOTIFY_FIELD_STATUS_STRING:
                              printf("WuLsT(msg):%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_DOCUMENT:
                              printf("hLg<:%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_PRIORITY:
                              printf("Dfx:%d\n", adwData[0]);
                              break;
                         case JOB_NOTIFY_FIELD_POSITION:
                              printf("T:%d\n", adwData[0]);
                              break;
                         case JOB_NOTIFY_FIELD_SUBMITTED:
                              //SYSTEMTIME
                              break;
                         case JOB_NOTIFY_FIELD_START_TIME:
                              printf("s|
Jn
T: %d:%d\n", adwData[0]/60, adwData[0]%60);
                              break;
                         case JOB_NOTIFY_FIELD_UNTIL_TIME:
                              printf("s|I9
T: %d:%d\n", adwData[0]/60, adwData[0]%60);
                              break;
                         case JOB_NOTIFY_FIELD_TIME:
                              printf(" o     _
T: %d: %d\n", adwData[0]/60, adwData[0]%60);
                              break;
                         case JOB_NOTIFY_FIELD_TOTAL_PAGES:
                              printf("s|: %d\n", adwData[0]);
                              break;
                         case JOB_NOTIFY_FIELD_PAGES_PRINTED:
                              printf("s|: %d\n", adwData[0]);
                              break;
                         case JOB_NOTIFY_FIELD_TOTAL_BYTES:
                              printf("oCg: %d\n", adwData[0]);
                              break;
                         case JOB_NOTIFY_FIELD_BYTES_PRINTED:
                              printf("s|oCg: %d\n", adwData[0]);
                              break;
                         }
                         break;
                    }
               }
               b = FreePrinterNotifyInfo(p);
               if(!b) printf("free error:%d\n", GetLastError());
          }
     }
     if(hPrinter!=INVALID_HANDLE_VALUE) {
          ClosePrinter(hPrinter);
          FindClosePrinterChangeNotification(hNotify);
     }
}
0
 

Author Comment

by:KIS
ID: 12298290

  Hi,

  I know about notifications. I need a solution for win9x and win2000\xp
  My mistake.

 Thanks.

0
 
LVL 52

Assisted Solution

by:Julian Hansen
Julian Hansen earned 250 total points
ID: 12313493
Hmm - I think you are pretty stuck then short of writing your own print monitor or print driver.

Even if you do use notifications there is the problem that you have to have the app receiving the notifications running all the time or else you miss a notification and that is the only time you get information about the number of pages being printed.

This one had me stumped for a couple of days - I kept trying to figure out what I was doing wrong with the GetPrinter API - eventually I found a posting on a newsgroup that you have to catch the notifications to get pages and bytes spooled to a printer - apparently it is only during spooling that this information is recorded - hence the notification.

The windows printer applet doesn't have the same problem because it gets all its info from Explorer and as Exploder is running the whole time it doesn't miss notifications.

I would be very interested to find a way around this but I don't think you are going to find an easy solution.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
MSVCR80.dll crash 2 134
Prototype for MessageDlg in Embacadero XE 2 2 35
Focus not getting shifted out of  editbox 2 57
Excel/Word Add-in in what language? 5 107
Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now