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