6

Is there a way to update the print queue status information contained in the PrintQueue object?

I've tried calling Refresh on the PrintQueue object but that doesn't really do anything. For instance, I've turned off the printer and the Control Panel correctly shows the printer as "Offline", however the QueueStatus property, as well as the IsOffline property don't reflect that - no matter how many times I call Refresh on both the PrintServer and the PrintQueue in question.

I've seen examples of how to get status information using WMI queries but I wonder - since these properties are available on the PrintQueue object - whether there is any way to use those.

Mike Dinescu
  • 54,171
  • 16
  • 118
  • 151
  • How is this WPF related? – benPearce Nov 24 '10 at 00:19
  • Hi, did you manage to find a solution for this issue? I faced it as well. – rem Jun 16 '11 at 15:59
  • @rem - no, unfortunately I couldn't find a way to get those properties to work. In the end I gave up on the whole idea since it wasn't worth the trouble just to display the status of the printers in my app. If you do find the answer, please post it here! – Mike Dinescu Jun 16 '11 at 16:35
  • OK, Miky, thank you for letting know! – rem Jun 16 '11 at 16:56

2 Answers2

0

After try to print your PrintDocument (System.Drawing.Printing), try to check status of printjobs.

First step: Initialize your printDocument.

Second step: Get your printer Name From System.Drawing.Printing.PrinterSettings.InstalledPrinters.Cast<string>();

And copy it into your printerDocument.PrinterSettings.PrinterName

Third step: Try to print and dispose.

printerDocument.Print();
printerDocument.Dispose();

Last step: Run the check in a Task (do NOT block UI thread).

   Task.Run(()=>{
     if (!IsPrinterOk(printerDocument.PrinterSettings.PrinterName,checkTimeInMillisec))
     {
        // failed printing, do something...
     }
    });

Here is the implementation:

        private bool IsPrinterOk(string name,int checkTimeInMillisec)
        {
            System.Collections.IList value = null;
            do
            {
                //checkTimeInMillisec should be between 2000 and 5000
                System.Threading.Thread.Sleep(checkTimeInMillisec);

                using (System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_PrintJob WHERE Name like '%" + name + "%'"))
                {
                    value = null;

                    if (searcher.Get().Count == 0) // Number of pending document.
                        return true; // return because we haven't got any pending document.
                    else
                    {
                        foreach (System.Management.ManagementObject printer in searcher.Get())
                        {
                            value = printer.Properties.Cast<System.Management.PropertyData>().Where(p => p.Name.Equals("Status")).Select(p => p.Value).ToList();
                            break; 
                        }
                    }
                }
           }
           while (value.Contains("Printing") || value.Contains("UNKNOWN") || value.Contains("OK"));

           return value.Contains("Error") ? false : true;    
        }

Good luck.

Péter Hidvégi
  • 743
  • 6
  • 21
  • The question was regarding the new System.Printing.PrintQueue objects. Your answer is about the older System.Drawing.Printing... objects. I appreciate your taking the time to add it here but it doesn't answer the question. – Mike Dinescu Nov 30 '16 at 22:59
  • I tried to use PrintQueue too. You can do the same (in a cycle) with your printQueue instance (after try to print). You can get your pq.QueueStatus and it will return with PrintQueueStatus.Error value after unsuccessful printing. i tried this method too. But I have experienced that my answer is more reliable solution than `printQueue.QueueStatus` – Péter Hidvégi Nov 30 '16 at 23:56
  • So you would have to actually try printing something before you're able to get the status of the print queue? That would be rather problematic for the user, don't you think? Or did I misread? – Mike Dinescu Nov 30 '16 at 23:58
  • Yes, you would have to try printing something before you're able to get QueueStatus of printerQueue and yes,this is not the best solution that I can imagine but it works and at least it will return with error value after a unsuccessful printing and it can be inferred from the response that the printer is not available. – Péter Hidvégi Dec 01 '16 at 00:16
  • I agree that in the case of offline printers it would work but in the case when the printer is online constantly printing something to it is just not good UX - in fact I'd rather not display status than spuriously send print jobs to all printers to determine their status. Don't you agree? – Mike Dinescu Dec 01 '16 at 00:19
  • Okay, but in practice the user select a printer (from InstalledPrinters) and the user going to send the document to selected printer. Our task is confirm that the printing was successful or unsuccessful. Whether a printer is "available", i'm not sure that printer won't throw any error. (For example out of paper or run out of ink or other problems.) After an unsuccessful printing the user can choose another one printer. – Péter Hidvégi Dec 01 '16 at 00:38
  • Yes, but the question was about offering users the ability to see what printers are online of the printers available on the computer. Much like you can tell in Control Panel - the ones online are solid while printers that are offline or not connected are semitransparent. That is what I was looking for – Mike Dinescu Dec 01 '16 at 06:13
0

Very late answer,

The only way I found so far is restarting the print Spooler service but this causes a bunch of other problems with WMI and it's not a clean solution.

Axeltherabbit
  • 680
  • 3
  • 20