2

I am using FindFirstPrinterChangeNotification and FindNextPrinterChangeNotification to catch printing events. However I have noticed that FindNextPrinterChangeNotification does not reliably returns all the events. I have found a guy with the same problem in this article.

Basically, when I debug my program, or put Sleep command like his suggestion when processing an event, FindNextPrinterChangeNotificationskips a lot of events. Also, most of the time I get a lot of SPOOLING status events but miss the DELETED status event (sometimes I get it, but most of the time I cannot), even though I already push the jobs to a Queue for later processing.

Does anyone have this problem too? Also, I am trying the Microsoft PDF Printer, The NumberOfPages increases as the SPOOLING events come, but the NumberOfPagesPrinted does not. Is it intended?

EDIT After some investigation, the events are not actually gone. If I call another print job, the previous events are fired (including the DELETING/DELETED status of previous print job). Can you please suggest what is the problem?

Here's the code for calling FindFirstPrinterChangeNotification:

    //We got a valid Printer handle.  Let us register for change notification....
    _changeHandle = FindFirstPrinterChangeNotification(_printerHandle, (int)PRINTER_CHANGES.PRINTER_CHANGE_JOB, 0, _notifyOptions);
    // We have successfully registered for change notification.  Let us capture the handle...
    _mrEvent.SafeWaitHandle = new Microsoft.Win32.SafeHandles.SafeWaitHandle(_changeHandle, true);
    //Now, let us wait for change notification from the printer queue....
    _waitHandle = ThreadPool.RegisterWaitForSingleObject(_mrEvent, new WaitOrTimerCallback(PrinterNotifyWaitCallback), _mrEvent, -1, true);

And this is for the FindNextPrinterChangeNotification:

    _notifyOptions.Count = 1;
    _notifyOptions.dwFlags = PRINTER_NOTIFY_OPTIONS_REFRESH;
    int pdwChange = 0;
    IntPtr pNotifyInfo = IntPtr.Zero;
    bool bResult = FindNextPrinterChangeNotification(_changeHandle, out pdwChange, _notifyOptions, out pNotifyInfo);
Luke Vo
  • 17,859
  • 21
  • 105
  • 181
  • What parameters are you passing to FindFirst and FindNext? Are you requesting ALL notifications? Check https://msdn.microsoft.com/en-us/library/windows/desktop/dd162723(v=vs.85).aspx – bizzehdee Jan 12 '16 at 10:29
  • @bizzehdee I have included the code in my question. I request for `PRINTER_CHANGE_JOB` only. – Luke Vo Jan 12 '16 at 10:42
  • I also added setting the flag `PRINTER_NOTIFY_OPTIONS_REFRESH`, and I received a lot more events, but there is still no consistent DELETING Status. – Luke Vo Jan 12 '16 at 10:46
  • The answer from alital is likely correct. By telling `RegisterWaitForSingleObject` not to reset the event, you're going to miss any events that occur during your callback. – Carey Gregory Feb 23 '16 at 02:13

1 Answers1

2

I had the same issue then I tried:

_waitHandle = ThreadPool.RegisterWaitForSingleObject(_mrEvent, new WaitOrTimerCallback(PrinterNotifyWaitCallback), _mrEvent, -1, true);    

with:

_waitHandle = ThreadPool.RegisterWaitForSingleObject(_mrEvent, new WaitOrTimerCallback(PrinterNotifyWaitCallback), _mrEvent, -1, false);

(false arg in the end) and seems to work now

alital
  • 411
  • 5
  • 15
  • 1
    I believe you copied the wrong line of code. I don't think you meant to say you replaced `FindFirstPrinterChangeNotification` with `RegisterWaitForSingleObject`. – Carey Gregory Feb 23 '16 at 02:11