Is there a way to check if a printing process was successful?

13k views Asked by At

I have an application where I need to print a ticket. Each ticket must be unique. The application is windows forms and written entirely in c#. For our application we're using Samsung ML- 2525 laser monochromatic printers.

The flow is basically the following, the operator picks a product/ticket (which is unique) and then it presses a button that does 2 things:

  1. Connects to a database and updates the product as used
  2. Prints the ticket (this is done using System.Drawing and GDI+)

For some reason, every once in a while, the image that needs to be printed is not sent to the printer. It's a rare case, but it happens.

I tried to connect to the printer using Win32_Printer ( http://msdn.microsoft.com/en-us/library/Aa394363 ) but I can't get to get the current printer's state (online, offline, low toner, paper jam, etc). I can only check if the printer exists and that the paper size is installed correctly. I tried code similar to the following but it didn't work

    private string MonitorPrintJobWmi()
    {
        var jobMessage = String.Empty;
        var scope = new ManagementScope(ManagementPath.DefaultPath);
        scope.Connect();

        var selectQuery = new SelectQuery { QueryString = @"select *  from Win32_PrintJob" };

        var objSearcher = new ManagementObjectSearcher(scope, selectQuery);
        var objCollection = objSearcher.Get();

        foreach (var job in objCollection)
        {
            if (job != null)
            {
                jobMessage += String.Format("{0} \r\n", job["Name"].ToString());
                jobMessage += String.Format("{0} \r\n", job["JobId"].ToString());
                _jobId = Convert.ToInt32(job["JobId"]);
                jobMessage += String.Format("{0} \r\n", job["JobStatus"].ToString());
                jobMessage += String.Format("{0} \r\n", job["Status"].ToString());
            }
        }
        return jobMessage;
    }

I tried to get an API for the printer but I couldn't get a hold of it. By the way, the printer's software do indicate different errors in the windows toolbar.

My question is if anyone can lead me in the right direction as to how to connect to a printer and check if printing was successful.

Also, it would be helpful if someone know of some other specific printer in which I may accomplish this ie, changing hardware.

Thanks,

2

There are 2 answers

4
Ben Gribaudo On

To get a list of print queues on the local machine, try PrintServer's GetPrintQueues method.

Once you have an instance of the PrintQueue object associated with the relevant printer, you can use it to access the printer's status (IsOffline, IsPaperOut, etc.). Also, you can use it to get a list of the jobs in the given queue (GetPrintJobInfoCollection) which then will allow you to get job-specific status information (IsInError, IsCompleted, IsBlocked, etc.).

Hope this helps!

0
Péter Hidvégi On

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);
            // or use Timer with Threading.Monitor instead of thread sleep

            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.