Не удается получить уведомление о задании на печать со статусом JOB_STATUS_DELETED

Я хочу получать уведомление, когда задание на печать было завершено или удалено. Теперь я вижу, что механизм уведомлений обеспечивает JOB_STATUS_DELETING, но получить статус JOB_STATUS_DELETED невозможно.

Я нашел что-то похожее Вот, но это не решает мою проблему.

Я делаю следующее:

  HANDLE hChange = FindFirstPrinterChangeNotification(hPrinter,
PRINTER_CHANGE_ALL,
0,
&NotificationOptions);

DWORD dwChange;
HANDLE aHandles[2];
aHandles[0] = hChange;
aHandles[1] = owner->GetStopRequestEvent();

while (hChange != INVALID_HANDLE_VALUE)
{
// sleep until a printer change notification wakes this thread or the
// event becomes set indicating it's time for the thread to end.
WaitForMultipleObjects(2, aHandles, FALSE, INFINITE);

if (WaitForSingleObject(hChange, 0U) == WAIT_OBJECT_0)
{
FindNextPrinterChangeNotification(hChange, &dwChange, &NotificationOptions, (LPVOID *) &pNotification);

if (pNotification != NULL)
{
// if a notification overflow occurred,
if (pNotification->Flags & PRINTER_NOTIFY_INFO_DISCARDED)
{
DWORD dwOldFlags = NotificationOptions.Flags;

// we must refresh to continue
NotificationOptions.Flags = PRINTER_NOTIFY_OPTIONS_REFRESH;

FreePrinterNotifyInfo(pNotification);

FindNextPrinterChangeNotification(hChange, &dwChange, &NotificationOptions, (LPVOID *) &pNotification);

NotificationOptions.Flags = dwOldFlags;
}

// iterate through each notification
for (DWORD x = 0; x < pNotification->Count; x++)
{
PRINTER_NOTIFY_INFO_DATA data = pNotification->aData[x];

if (data.Type == JOB_NOTIFY_TYPE)
{
if (data.Field == JOB_NOTIFY_FIELD_STATUS)
{
if (data.NotifyData.adwData[0] & ( JOB_STATUS_DELETED | JOB_STATUS_DELETING | JOB_STATUS_PRINTED))
{
owner->SendJobsData(data.NotifyData.adwData[0]);
}
......

когда я удаляю работу, JOB_NOTIFY_FIELD_STATUS проходит только DELETING, и никаких дальнейших уведомлений о статусе, но мне действительно нужно получить статус DELETED. Что я делаю неправильно?

полный код метода Poller здесь:
void Poll (владелец JobTracker *, сервис CServiceBase *)
{
HANDLE hPrinter = NULL;
РУЧКА hNotification;
if (! OpenPrinter (owner -> GetPrinterName (), &hPrinter, NULL))
вернуть;

PPRINTER_NOTIFY_INFO pNotification = NULL;

WORD JobFields[] =
{
JOB_NOTIFY_FIELD_PRINTER_NAME,
JOB_NOTIFY_FIELD_MACHINE_NAME,
JOB_NOTIFY_FIELD_PORT_NAME,
JOB_NOTIFY_FIELD_USER_NAME,
JOB_NOTIFY_FIELD_NOTIFY_NAME,
JOB_NOTIFY_FIELD_DATATYPE,
JOB_NOTIFY_FIELD_PRINT_PROCESSOR,
JOB_NOTIFY_FIELD_PARAMETERS,
JOB_NOTIFY_FIELD_DRIVER_NAME,
JOB_NOTIFY_FIELD_DEVMODE,
JOB_NOTIFY_FIELD_STATUS,
JOB_NOTIFY_FIELD_STATUS_STRING,
JOB_NOTIFY_FIELD_DOCUMENT,
JOB_NOTIFY_FIELD_PRIORITY,
JOB_NOTIFY_FIELD_POSITION,
JOB_NOTIFY_FIELD_SUBMITTED,
JOB_NOTIFY_FIELD_START_TIME,
JOB_NOTIFY_FIELD_UNTIL_TIME,
JOB_NOTIFY_FIELD_TIME,
JOB_NOTIFY_FIELD_TOTAL_PAGES,
JOB_NOTIFY_FIELD_PAGES_PRINTED,
JOB_NOTIFY_FIELD_TOTAL_BYTES,
JOB_NOTIFY_FIELD_BYTES_PRINTED
};
PRINTER_NOTIFY_OPTIONS_TYPE Notifications[1] =
{
{
JOB_NOTIFY_TYPE,
0,
0,
0,
sizeof(JobFields) / sizeof(JobFields[0]),
JobFields
},
};
PRINTER_NOTIFY_OPTIONS NotificationOptions =
{
2,
PRINTER_NOTIFY_OPTIONS_REFRESH,
sizeof(Notifications) / sizeof(Notifications[0]),
Notifications
};

// get a handle to a printer change notification object.
HANDLE hChange = FindFirstPrinterChangeNotification(hPrinter,
PRINTER_CHANGE_ALL,
0,
&NotificationOptions);

DWORD dwChange;
HANDLE aHandles[2];
aHandles[0] = hChange;
aHandles[1] = owner->GetStopRequestEvent();

while (hChange != INVALID_HANDLE_VALUE)
{
// sleep until a printer change notification wakes this thread or the
// event becomes set indicating it's time for the thread to end.
WaitForMultipleObjects(2, aHandles, FALSE, INFINITE);

if (WaitForSingleObject(hChange, 0U) == WAIT_OBJECT_0)
{
FindNextPrinterChangeNotification(hChange, &dwChange, &NotificationOptions, (LPVOID *) &pNotification);

if (pNotification != NULL)
{
// if a notification overflow occurred,
if (pNotification->Flags & PRINTER_NOTIFY_INFO_DISCARDED)
{
DWORD dwOldFlags = NotificationOptions.Flags;

// we must refresh to continue
NotificationOptions.Flags = PRINTER_NOTIFY_OPTIONS_REFRESH;

FreePrinterNotifyInfo(pNotification);

FindNextPrinterChangeNotification(hChange, &dwChange, &NotificationOptions, (LPVOID *) &pNotification);

NotificationOptions.Flags = dwOldFlags;
}

// iterate through each notification
for (DWORD x = 0; x < pNotification->Count; x++)
{
PRINTER_NOTIFY_INFO_DATA data = pNotification->aData[x];

if (data.Type == JOB_NOTIFY_TYPE)
{
if (data.Field == JOB_NOTIFY_FIELD_STATUS)
{
if (data.NotifyData.adwData[0] & ( JOB_STATUS_DELETED | JOB_STATUS_DELETING | JOB_STATUS_PRINTED))
{
owner->SendJobsData(data.NotifyData.adwData[0]);
}
}
if (data.Field == JOB_NOTIFY_FIELD_STATUS_STRING)
{
int a = 0;
}
}
else if (data.Type == PRINTER_NOTIFY_TYPE)
{
if (data.Field == PRINTER_NOTIFY_FIELD_STATUS)
{
int a = 0;
}
if (data.Field == PRINTER_NOTIFY_FIELD_STATUS_STRING)
{
int a = 0;
}
}
}
}

FreePrinterNotifyInfo(pNotification);
pNotification = NULL;
}
else if (WaitForSingleObject(owner->GetStopRequestEvent(), 0U) == WAIT_OBJECT_0)
{
FindClosePrinterChangeNotification(hChange);
hChange = INVALID_HANDLE_VALUE;
}
}

}

1

Решение

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

Я заметил, что каждый раз, когда работа покидает очередь, уведомление PRINTER_CHANGE_JOB_DELETE (я имею в виду изменение FindNextPrinterChangeNotification).

Поэтому я просто отслеживаю список задач в классе владельца потока (JobTracker) и обновляю его каждый раз в любом PRINTER_CHANGE_JOB. Но прежде чем обновить его, я смотрю на разницу и, если вижу, что какая-то работа исчезла (сравните по JobId), я беру свой вектор работ и отправляю на сервер пропущенную работу.

2

Другие решения


По вопросам рекламы [email protected]