无法获取状态JOB_STATUS_DELETED的打印作业通知

Can't get print job notification with status JOB_STATUS_DELETED

本文关键字:打印 作业 通知 DELETED STATUS 获取 状态 JOB      更新时间:2023-10-16

我想在打印作业完成或删除时收到通知。现在我看到通知机制提供了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;HANDLE 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;
      }
  }

}

如果有人面临这样的任务,我会离开我解决它的方法。

我注意到,每次作业离开队列时,PRINTER_CHANGE_job_DELETE通知(我的意思是FindNextPrinterChangeNotification的更改)。

所以,我只跟踪线程所有者类(JobTracker)中的任务列表,每次在任何PRINTER_CHANGE_JOB上刷新它。但在刷新之前,我会查看差异,如果我看到一些作业被取消(通过JobId进行比较),我会获取我的作业向量,并将丢失的作业发送到服务器。