C# check printer status


in my application (Windows 7, VS2010) i have to decrement a credit counter after successfully printing an image.
Anyway, before starting the entire process, i'd like to know about printer status in order to alert the user on paper out, paper jam and so on.
Now, looking around i found several example that use Windows WMI but… never works. Using THIS snippet, for example, the printer status is always ready also if i remove the paper, open the cover… turn off the printer.

The printer status is always good also now, that i'm testing from office the printer that is comfortably turned off at home.
have I to detonate the device by dynamite in order to have a printer error status?

This is the code i've used

ManagementObjectCollection MgmtCollection;
ManagementObjectSearcher MgmtSearcher;

//Perform the search for printers and return the listing as a collection
MgmtSearcher = new ManagementObjectSearcher("Select * from Win32_Printer");
MgmtCollection = MgmtSearcher.Get();

foreach (ManagementObject objWMI in MgmtCollection)

    string name = objWMI["Name"].ToString().ToLower();

    if (name.Equals(printerName.ToLower()))

        int state = Int32.Parse(objWMI["ExtendedPrinterStatus"].ToString());
        if ((state == 1) || //Other
        (state == 2) || //Unknown
        (state == 7) || //Offline
        (state == 9) || //error
        (state == 11) //Not Available
        throw new ApplicationException("hope you are finally offline");

        state = Int32.Parse(objWMI["DetectedErrorState"].ToString());
        if (state != 2) //No error
        throw new ApplicationException("hope you are finally offline");



Where 'printerName' is received as parameter.

Thank you in advice.

Best Solution

You don't say what version of .Net you're using, but since .Net 3.0 there has been some good printing functionality. I've used this and whilst I can't be sure that it reports all kinds of status levels, I've certainly seen messages such as 'Toner Low' for various printers etc.

PrinterDescription is a custom class, but you can see the properties its using.


        PrintQueueCollection printQueues = null;
        List<PrinterDescription> printerDescriptions = null;

        // Get a list of available printers.
        this.printServer = new PrintServer();
        printQueues = this.printServer.GetPrintQueues(new[] { EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections });
        printerDescriptions = new List<PrinterDescription>();

        foreach (PrintQueue printQueue in printQueues)
            // The OneNote printer driver causes crashes in 64bit OSes so for now just don't include it.
            // Also redirected printer drivers cause crashes for some printers. Another WPF issue that cannot be worked around.
            if (printQueue.Name.ToUpperInvariant().Contains("ONENOTE") || printQueue.Name.ToUpperInvariant().Contains("REDIRECTED"))

            string status = printQueue.QueueStatus.ToString();

                PrinterDescription printerDescription = new PrinterDescription()
                    Name = printQueue.Name,
                    FullName = printQueue.FullName,
                    Status = status == Strings.Printing_PrinterStatus_NoneTxt ? Strings.Printing_PrinterStatus_ReadyTxt : status,
                    ClientPrintSchemaVersion = printQueue.ClientPrintSchemaVersion,
                    DefaultPrintTicket = printQueue.DefaultPrintTicket,
                    PrintCapabilities = printQueue.GetPrintCapabilities(),
                    PrintQueue = printQueue

            catch (PrintQueueException ex)
                // ... Logging removed
Related Question