Solved

Get the number of pages printed on the printer

Posted on 2004-10-13
6
276 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 51

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

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

762 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