Есть ли способ проверить успешность процесса печати?

У меня есть приложение, где мне нужно распечатать билет. Каждый билет должен быть уникальным. Приложение представляет собой формы окон и полностью написано в С#. Для нашего применения мы используем лазерные монохромные принтеры Samsung ML-2525.

Поток в основном следующий: оператор выбирает продукт/билет (который уникален), а затем нажимает кнопку, которая выполняет 2 вещи:

  • Подключение к базе данных и обновление используемого продукта
  • Распечатывает билет (это делается с использованием System.Drawing и GDI +)

По какой-то причине время от времени изображение, которое нужно распечатать, не отправляется на принтер. Это редкий случай, но это случается.

Я попытался подключиться к принтеру с помощью Win32_Printer (http://msdn.microsoft.com/en-us/library/Aa394363), но я не могу получить текущее состояние принтера (онлайн, автономный режим, низкий уровень тонера, замятие бумаги и т.д.). Я могу проверить только, существует ли принтер и правильно ли установлен размер бумаги. Я попробовал код, похожий на следующий, но он не работал.

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

Я попытался получить API для принтера, но я не мог его удержать. Кстати, программное обеспечение принтера указывает на различные ошибки на панели инструментов Windows.

Мой вопрос в том, может ли кто-нибудь привести меня в правильном направлении относительно того, как подключиться к принтеру и проверить, была ли печать успешной.

Кроме того, было бы полезно, если бы кто-то знал о каком-то другом конкретном принтере, в котором я мог бы выполнить это, т.е. меняя аппаратное обеспечение.

Спасибо,

Ответы

Ответ 1

Чтобы получить список очередей печати на локальном компьютере, попробуйте метод PrintServer GetPrintQueues.

Как только у вас есть экземпляр объекта PrintQueue, связанного с соответствующим принтером, вы можете использовать его для доступа к состоянию принтера (IsOffline, IsPaperOut и т.д.). Кроме того, вы можете использовать его для получения списка заданий в заданной очереди (GetPrintJobInfoCollection), которые затем позволят вам получить работу, (IsInError, IsCompleted, IsBlocked и т.д.).

Надеюсь, это поможет!

Ответ 2

После попытки печати PrintDocument (System.Drawing.Printing) попробуйте проверить статус printjobs.

Первый шаг: Инициализация документа print.ocument.

Второй шаг: получите свой принтер Имя От System.Drawing.Printing.PrinterSettings.InstalledPrinters.Cast<string>();

И скопируйте его в свой принтерDocument.PrinterSettings.PrinterName

Третий шаг: попробуйте распечатать и удалить.

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

Последний шаг: запустите проверку задачи (НЕ блокируйте поток пользовательского интерфейса).

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

Вот реализация:

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

Удачи.