0

I need to run a Windows Service of server X to show the status of all printers: Out of paper, no toner, etc. The service is running on a machine but of course not all printers are installed on it. Even when the printers are installed on the machine, we do NOT have the status of the printers!

The only thing I was able to do is to remove the paper, print a test page (notepad), and now I can see that I'm missing paper with the code below, but as you might thing, this is not doable: I don't want to send a test page to every printers of the network every 10 minutes or so!

I try to query PrintQueue.Refresh but status is not updating, I don't see that the printer tray is open (or missing paper, or no toner, whatever I do with the printer.) BTW, Win32_printer don't show me a better result.

NOTE:

  1. MonitoringWS is the web service that can access the database.
  2. Printers is the list of printers that we want to query.

This is what I try to do.

 var printServers = GetListOfPrinterServers();
            var listPrinters = printers as List<Printer> ?? printers.ToList();
            foreach (
                var printServer in
                    printServers.Select(
                        server => new PrintServer(server, PrintSystemDesiredAccess.EnumerateServer)))
            {
                printServer.Refresh();
                var printQueues = printServer.GetPrintQueues();
                foreach (var printQueue in printQueues)
                {
                    var queue = printQueue;
                    var printersFound = listPrinters.Where(p =>
                                                                                                                                string.Equals(p.PrinterName, queue.FullName,
                                                                             StringComparison.OrdinalIgnoreCase));
                    foreach (var printer in printersFound)
                    {
                        printQueue.Refresh();

                        Debug.WriteLine(string.Format("{0} {1}", printQueue.FullName, printQueue.HostingPrintServer.Name) );
                        var pm = new MonitoringWS.PrinterMonitoring
                                     {
                                         FkPrinter = printer.PkPrinter,
                                         QueueStatus = printQueue.QueueStatus,
                                         DriverName = printQueue.QueueDriver.Name,
                                         MonitoringDateTime = DateTime.Now
                                     };

                        printerMonitorings.Add(pm);
                    }
                }
            }
Bestter
  • 877
  • 1
  • 12
  • 29
  • 1
    This could be impossible. See [here](https://support.microsoft.com/en-us/help/160129/how-to-get-the-status-of-a-printer-and-a-print-job), there is an interesting paragraph around "[...] a system Printer reports no status when the Printer queue is empty. In this state, the Printer is assumed ready to accept print jobs. This is a valid assumption even if the physical printer is in an error state such as off-line. The operating system considers the Printer ready to accept print jobs even if, for some reason, it cannot complete delivery to the physical printer [...]" – Cee McSharpface Feb 19 '18 at 16:54
  • and "to determine the state of a physical printer: the Spooler must be attempting to send a print job to the physical printer" – Cee McSharpface Feb 19 '18 at 16:55
  • Thanks for the article, it's really useful. But now, how I can i achieve my objective: I need to know the status of all printers on the network, in C#. I don't care about the API, or the method, or whatever: I just need to know the status of all printers. Thank you – Bestter Feb 19 '18 at 16:56
  • Are the printers itself all connected via network ? Are they mainly the same vendor / type ? Perhaps SNMP could be a solution, see https://stackoverflow.com/questions/14559727/c-sharp-get-page-count-for-all-printers-with-snmp. (I did this 20 years ago with perl, I am not sure how good SNMP is supported by the current printers ...) – Rainer Schaack Feb 19 '18 at 17:32
  • Hi! Yes, printers are network, but we have two type of printer: 1. Barcode printer, mostly Datamax or Citizen (Datamax compatible), some Zebra printer too. 2. Normal printer: we don't know the printers of our customers, could be HP, Epson, Canon... anything! – Bestter Feb 19 '18 at 18:21

1 Answers1

0

I found a way: SNMP. I use library SNMP# at http://www.snmpsharpnet.com/ and I implement RFC 2790: https://www.rfc-editor.org/rfc/rfc2790 .

With that, when the printer support that standard and when SNMP is active, I got the status of the printer (no toner, no paper, paper jam, etc.)

Thanks everybody for your help.

Community
  • 1
  • 1
Bestter
  • 877
  • 1
  • 12
  • 29
  • Hi Bestter, could you post an example of the sort of thing you did to get the status of your printers please? I had a look at the site you linked to, but couldn't really see where to start with it all. Many thanks – Ted Oct 26 '20 at 17:26
  • 1
    @Ted : After many research, I really do NOT recommand this method. EVERY printer model of the world have different code, and the manufacturer do not want do give you any doccumentation of the meaning of the code returned by SNMP. Maybe if you throw alots of cash, they will. Because of that, I use a thid party, PRTG, which know how to communicate with the different printers. PRTG got a very powerfull RestFull API that you can use in your application to monitor your printer. But, it's not free. I use a lots of non-standard printer, maybe if you use big name printer, you can try SNMP. good luck – Bestter Oct 26 '20 at 18:08
  • 1
    Thanks for the warning! Why is everything to do with printing still horrible in 2020? (Although, everything's horrible in 2020, so maybe printing will get fixed next year too?!) – Ted Oct 27 '20 at 10:05
  • @Ted: to answer your complaint: no standard. (Except maybe HP) – Bestter Oct 27 '20 at 12:44