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

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

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

  1. Подключается к базе данных и обновляет продукт по мере использования
  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.

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

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

Спасибо,

2 ответа

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

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

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

После того, как вы попытаетесь распечатать документ PrintDocument (System.Drawing.Printing), попробуйте проверить состояние заданий на печать.

Первый шаг: инициализируйте ваш printDocument.

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

И скопируйте его в ваш printerDocument.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;    
    }

Удачи.

Другие вопросы по тегам