Есть ли способ проверить, был ли процесс печати успешным?
У меня есть приложение, где мне нужно распечатать билет. Каждый билет должен быть уникальным. Приложение Windows Forms и полностью написано на C#. Для нашего приложения мы используем лазерные монохроматические принтеры 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.
У меня вопрос, может ли кто-нибудь привести меня в правильном направлении, как подключиться к принтеру и проверить, была ли печать успешной.
Кроме того, было бы полезно, если бы кто-то знал о каком-то другом конкретном принтере, в котором я могу выполнить это, например, об изменении аппаратного обеспечения.
Спасибо,
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;
}
Удачи.