Как эффективно приостановить задание принтера перед печатью на C#C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Как эффективно приостановить задание принтера перед печатью на C#

Сообщение Anonymous »

Я работаю над приложением C# для мониторинга и управления заданиями принтера. Моя цель — приостановить задание печати, как только оно будет добавлено в очередь принтера, прежде чем оно начнет печатать. Однако я столкнулся с некоторыми проблемами, связанными со временем и надежностью приостановки задания, особенно при работе с разными драйверами принтера и размерами задания.
Вот что я сделал на данный момент:
  • Открыл принтер и настроил уведомления об изменениях:

Код: Выделить всё

IntPtr hPrinter;
if (!OpenPrinter(printerName, out hPrinter, IntPtr.Zero))
{
int errorCode = Marshal.GetLastWin32Error();
Log($"Failed to open printer: {printerName}. Error code: {errorCode}");
return;
}

IntPtr hChange = FindFirstPrinterChangeNotification(hPrinter, PRINTER_CHANGE_ADD_JOB | PRINTER_CHANGE_WRITE_JOB | PRINTER_CHANGE_SET_JOB, 0, IntPtr.Zero);
if (hChange == IntPtr.Zero)
{
int errorCode = Marshal.GetLastWin32Error();
Log($"Failed to create change notification for printer: {printerName}. Error code: {errorCode}");
ClosePrinter(hPrinter);
return;
}

  • Отслеживание изменений принтера:

Код: Выделить всё

while (bKeepMonitoring && !cancellationToken.IsCancellationRequested)
{
uint waitResult = WaitForSingleObject(hChange, 1000);
if (waitResult == WAIT_OBJECT_0)
{
int pdwChange;
IntPtr lppPrinterNotifyInfo;
bool fcnreturn = FindNextPrinterChangeNotification(hChange, out pdwChange, IntPtr.Zero, out lppPrinterNotifyInfo);

if (fcnreturn)
{
if ((pdwChange & PRINTER_CHANGE_ADD_JOB) != 0)
{
Log($"A new print job was added to printer: {printerName}");
JOB_INFO_1? jobInfo = PausePrintJob(hPrinter);
if (jobInfo != null)
{
Log($"Job paused: {jobInfo.Value.JobId}, Document: {jobInfo.Value.pDocument}");
}
}
// Additional handling for other events
}
else
{
int errorCode = Marshal.GetLastWin32Error();
Log($"Failed to get next printer change notification for printer: {printerName}. Error code: {errorCode}");
bKeepMonitoring = false;
}
}
else if (waitResult == WAIT_TIMEOUT)
{
Log("Timeout...");
}
else
{
int errorCode = Marshal.GetLastWin32Error();
Log($"WaitForSingleObject failed for printer: {printerName}. Error code: {errorCode}");
bKeepMonitoring = false;
}
}
  • Приостановка задания печати:

Код: Выделить всё

private static JOB_INFO_1? PausePrintJob(IntPtr hPrinter)
{
uint needed = 0, returned = 0;
IntPtr buffer = IntPtr.Zero;

try
{
EnumJobs(hPrinter, 0, 1, 1, buffer, 0, out needed, out returned);
if (needed == 0)
{
Log("No job to pause.");
return null;
}

buffer = Marshal.AllocHGlobal((int)needed);
if (EnumJobs(hPrinter, 0, 1, 1, buffer, needed, out needed, out returned) && returned > 0)
{
JOB_INFO_1 jobInfo = (JOB_INFO_1)Marshal.PtrToStructure(buffer, typeof(JOB_INFO_1));
Log($"Pausing job: {jobInfo.JobId}, Document: {jobInfo.pDocument}");

if (!SetJob(hPrinter, jobInfo.JobId, 0, IntPtr.Zero, JOB_CONTROL_PAUSE))
{
int errorCode = Marshal.GetLastWin32Error();
Log($"Failed to pause job: {jobInfo.JobId}. Error code: {errorCode}");
}
else
{
return jobInfo;
}
}
}
finally
{
if (buffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(buffer);
}
}

return null;
}
Проблема:
Несмотря на установку малого интервала опроса и обработку различных событий уведомлений, все же бывают случаи, когда задание на печать начинает печатать до того, как оно будет приостановлено, особенно с некоторыми драйверами принтера или большие объемы печати. Иногда я получаю статус «Приостановлено — печать» вместо статуса «Приостановлено».
Вопросы:
Что можно сделать, чтобы гарантировать, что задание приостанавливается сразу после добавления в очередь?
Существуют ли определенные драйверы или конфигурации принтера, которые лучше подходят для такого типа управления заданиями?
Как я могу улучшить время и надежность обнаружения и приостановки печати задание до начала печати?
Дополнительная информация:
Для тестирования я использую драйвер принтера «Общий/Только текст».
Я пробовал другой таймаут. значения для WaitForSingleObject.
Приложение работает с правами администратора.
Будем очень признательны за любые идеи и предложения!

Подробнее здесь: https://stackoverflow.com/questions/786 ... in-c-sharp
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Разница между печатью (i) и печатью (*i) [дубликат]
    Anonymous » » в форуме Python
    0 Ответы
    17 Просмотры
    Последнее сообщение Anonymous
  • Как установить настройки принтера без прав администратора для задания принтера, который печатает файл PDF или PS?
    Гость » » в форуме Python
    0 Ответы
    53 Просмотры
    Последнее сообщение Гость
  • Немедленно приостановить задание печати на C#
    Anonymous » » в форуме C#
    0 Ответы
    8 Просмотры
    Последнее сообщение Anonymous
  • Неудачное копирование ввода тензора с/задание: localhost/replica: 0/Задача: 0/Устройство: ЦП: от 0 до/задание: localhost
    Anonymous » » в форуме Python
    0 Ответы
    7 Просмотры
    Последнее сообщение Anonymous
  • Трудности с печатью в журнале ошибок Magento 2
    Anonymous » » в форуме Php
    0 Ответы
    78 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C#»