c# check printer status

偶尔善良 提交于 2019-11-28 23:06:17

问题


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.


回答1:


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.

http://msdn.microsoft.com/en-us/library/system.printing.aspx

        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"))
            {
                continue;
            }

            string status = printQueue.QueueStatus.ToString();

            try
            {
                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
                };

                printerDescriptions.Add(printerDescription);
            }
            catch (PrintQueueException ex)
            {
                // ... Logging removed
            }
        }



回答2:


The PrintQueue class in the System.Printing namespace is what you are after. It has many properties that give useful information about the status of the printer that it represents. Here are some examples;

        var server = new LocalPrintServer();

        PrintQueue queue = server.DefaultPrintQueue;

        //various properties of printQueue
        var isOffLine = queue.IsOffline;
        var isPaperJam = queue.IsPaperJammed;
        var requiresUser = queue.NeedUserIntervention;
        var hasPaperProblem = queue.HasPaperProblem;
        var isBusy = queue.IsBusy;

This is by no means a comprehensive list and remember that it is possible for the queue to have one or more of these statuses so you'll have to think about the order in which you handle them.




回答3:


You can do this with printer queues as @mark_h pointed out above.

However, if your printer is not the default printer you need to load that printer's queue instead. What you need to do instead of calling server.DefaultPrintQueue you would need to load the correct queue by calling GetPrintQueue() then pass it the printer name and an empty string array.

//Get local print server
var server = new LocalPrintServer();

//Load queue for correct printer
PrintQueue queue = server.GetPrintQueue(PrinterName, new string[0] { }); 

//Check some properties of printQueue    
bool isInError = queue.IsInError;
bool isOutOfPaper = queue.IsOutOfPaper;
bool isOffline = queue.IsOffline;
bool isBusy = queue.IsBusy;



回答4:


The only solution that is reliable across all brands of printers is to use SNMP to query the number of pages printed and ensure that it matches the number of pages in the document sent.

SNMP OID for page count is 1.3.6.1.2.1.43.10.2.1.4

From my testing, every other strategy has had unreliable behavior (odd null reference exceptions when fetching the print queue repeatedly) or provided inaccurate status codes or page counts.



来源:https://stackoverflow.com/questions/5001920/c-sharp-check-printer-status

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!