private void cmdResumeJob_Click(object sender, RoutedEventArgs e) { if (lstJobs.SelectedValue != null) { PrintQueue queue = printServer.GetPrintQueue(lstQueues.SelectedValue.ToString()); PrintSystemJobInfo job = queue.GetJob((int)lstJobs.SelectedValue); job.Resume(); } }
private void cmdCancelJob_Click(object sender, RoutedEventArgs e) { if (lstJobs.SelectedValue != null) { PrintQueue queue = printServer.GetPrintQueue(lstQueues.SelectedValue.ToString()); PrintSystemJobInfo job = queue.GetJob((int)lstJobs.SelectedValue); job.Cancel(); lstQueues_SelectionChanged(null, null); } }
private void lstJobs_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (lstJobs.SelectedValue == null) { lblJobStatus.Text = ""; } else { PrintQueue queue = printServer.GetPrintQueue(lstQueues.SelectedValue.ToString()); PrintSystemJobInfo job = queue.GetJob((int)lstJobs.SelectedValue); lblJobStatus.Text = "Job Status: " + job.JobStatus.ToString(); } }
internal void PrinterNotifyWaitCallback(object state, bool timedOut) { if (_printerHandle == IntPtr.Zero) { return; } #region read notification details _notifyOptions.Count = 1; var pdwChange = 0; IntPtr pNotifyInfo; var bResult = FindNextPrinterChangeNotification(_changeHandle, out pdwChange, _notifyOptions, out pNotifyInfo); //If the Printer Change Notification Call did not give data, exit code if ((bResult == false) || (((int)pNotifyInfo) == 0)) { return; } //If the Change Notification was not relgated to job, exit code var bJobRelatedChange = ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_ADD_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_ADD_JOB) || ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_SET_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_SET_JOB) || ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_DELETE_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_DELETE_JOB) || ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_WRITE_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_WRITE_JOB); if (!bJobRelatedChange) { return; } #endregion #region populate Notification Information //Now, let us initialize and populate the Notify Info data var info = (PRINTER_NOTIFY_INFO)Marshal.PtrToStructure(pNotifyInfo, typeof(PRINTER_NOTIFY_INFO)); var pData = (long)pNotifyInfo + (long)Marshal.OffsetOf(typeof(PRINTER_NOTIFY_INFO), "aData"); var data = new PRINTER_NOTIFY_INFO_DATA[info.Count]; for (uint i = 0; i < info.Count; i++) { data[i] = (PRINTER_NOTIFY_INFO_DATA)Marshal.PtrToStructure((IntPtr)pData, typeof(PRINTER_NOTIFY_INFO_DATA)); pData += Marshal.SizeOf(typeof(PRINTER_NOTIFY_INFO_DATA)); } #endregion #region iterate through all elements in the data array for (var i = 0; i < data.Count(); i++) { if ((data[i].Field == (ushort)PRINTERJOBNOTIFICATIONTYPES.JOB_NOTIFY_FIELD_STATUS) && (data[i].Type == (ushort)PRINTERNOTIFICATIONTYPES.JOB_NOTIFY_TYPE) ) { var jStatus = (JOBSTATUS)Enum.Parse(typeof(JOBSTATUS), data[i].NotifyData.Data.cbBuf.ToString()); var intJobId = (int)data[i].Id; string strJobName; PrintSystemJobInfo pji = null; try { _spooler = new PrintQueue(new PrintServer(), SpoolerName); pji = _spooler.GetJob(intJobId); if (!_objJobDict.ContainsKey(intJobId)) { _objJobDict[intJobId] = pji.Name; } strJobName = pji.Name; } catch { //Trace.WriteLine(ex.Message); pji = null; _objJobDict.TryGetValue(intJobId, out strJobName); if (strJobName == null) { strJobName = string.Empty; } } if (OnJobStatusChange != null) { //Let us raise the event OnJobStatusChange(this, new PrintJobChangeEventArgs(intJobId, strJobName, jStatus, pji)); } } } #endregion #region reset the Event and wait for the next event _mrEvent.Reset(); _waitHandle = ThreadPool.RegisterWaitForSingleObject(_mrEvent, PrinterNotifyWaitCallback, _mrEvent, -1, true); #endregion }
static void Main(string[] args) { // Obtain a list of print servers. Console.Write("Enter path and file name of CRLF-delimited list of print servers" + "\n(press Return for default \"C:\\PrintServers.txt\"): "); String pathToListOfPrintServers = Console.ReadLine(); if (pathToListOfPrintServers == "") { pathToListOfPrintServers = @"C:\PrintServers.txt"; } StreamReader fileOfPrintServers = new StreamReader(pathToListOfPrintServers); // Obtain the username of the person with the problematic print job. Console.Write("\nEnter username of person that submitted print job" + "\n(press Return for the current user {0}: ", Environment.UserName); String userName = Console.ReadLine(); if (userName == "") { userName = Environment.UserName; } // Prompt user to determine the method that will be used to read the queue status. Console.Write("\nEnter \"Y\" to check the problematic job using its JobStatus attributes." + "\nOtherwise, press Return and the job will be checked using its specific properties: "); String useAttributesResponse = Console.ReadLine(); // Create list of all jobs submitted by user. String line; Boolean atLeastOne = false; String jobList = "\n\nAll print jobs submitted by the user are listed here:\n\n"; while ((line = fileOfPrintServers.ReadLine()) != null) { PrintServer myPS = new PrintServer(line, PrintSystemDesiredAccess.AdministrateServer); PrintQueueCollection myPrintQueues = myPS.GetPrintQueues(); //<SnippetEnumerateJobsInQueues> foreach (PrintQueue pq in myPrintQueues) { pq.Refresh(); PrintJobInfoCollection jobs = pq.GetPrintJobInfoCollection(); foreach (PrintSystemJobInfo job in jobs) { // Since the user may not be able to articulate which job is problematic, // present information about each job the user has submitted. if (job.Submitter == userName) { atLeastOne = true; jobList = jobList + "\nServer:" + line; jobList = jobList + "\n\tQueue:" + pq.Name; jobList = jobList + "\n\tLocation:" + pq.Location; jobList = jobList + "\n\t\tJob: " + job.JobName + " ID: " + job.JobIdentifier; } } // end for each print job } // end for each print queue //</SnippetEnumerateJobsInQueues> } // end while list of print servers is not yet exhausted fileOfPrintServers.Close(); if (!atLeastOne) { jobList = "\n\nNo jobs submitted by " + userName + " were found.\n\n"; Console.WriteLine(jobList); } else { jobList = jobList + "\n\nIf multiple jobs are listed, use the information provided" + " above and by the user to identify the job needing diagnosis.\n\n"; Console.WriteLine(jobList); //<SnippetIdentifyAndDiagnoseProblematicJob> // When the problematic print job has been identified, enter information about it. Console.Write("\nEnter the print server hosting the job (including leading slashes \\\\): " + "\n(press Return for the current computer \\\\{0}): ", Environment.MachineName); String pServer = Console.ReadLine(); if (pServer == "") { pServer = "\\\\" + Environment.MachineName; } Console.Write("\nEnter the print queue hosting the job: "); String pQueue = Console.ReadLine(); Console.Write("\nEnter the job ID: "); Int16 jobID = Convert.ToInt16(Console.ReadLine()); // Create objects to represent the server, queue, and print job. PrintServer hostingServer = new PrintServer(pServer, PrintSystemDesiredAccess.AdministrateServer); PrintQueue hostingQueue = new PrintQueue(hostingServer, pQueue, PrintSystemDesiredAccess.AdministratePrinter); PrintSystemJobInfo theJob = hostingQueue.GetJob(jobID); if (useAttributesResponse == "Y") { TroubleSpotter.SpotTroubleUsingJobAttributes(theJob); // TroubleSpotter class is defined in the complete example. } else { TroubleSpotter.SpotTroubleUsingProperties(theJob); } TroubleSpotter.ReportQueueAndJobAvailability(theJob); //</SnippetIdentifyAndDiagnoseProblematicJob> }// end else at least one job was submitted by user // End the program Console.WriteLine("\nPress Return to end."); Console.ReadLine(); } // end Main
public void PrinterNotifyWaitCallback(Object state,bool timedOut) { if (_printerHandle == IntPtr.Zero) return; #region read notification details _notifyOptions.Count = 1; int pdwChange = 0; IntPtr pNotifyInfo = IntPtr.Zero; bool bResult = FindNextPrinterChangeNotification(_changeHandle, out pdwChange, _notifyOptions, out pNotifyInfo); //If the Printer Change Notification Call did not give data, exit code if ((bResult == false) || (((int)pNotifyInfo) == 0)) return; //If the Change Notification was not relgated to job, exit code bool bJobRelatedChange = ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_ADD_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_ADD_JOB) || ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_SET_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_SET_JOB) || ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_DELETE_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_DELETE_JOB) || ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_WRITE_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_WRITE_JOB); if (!bJobRelatedChange) return; #endregion #region populate Notification Information //Now, let us initialize and populate the Notify Info data PRINTER_NOTIFY_INFO info = (PRINTER_NOTIFY_INFO)Marshal.PtrToStructure(pNotifyInfo, typeof(PRINTER_NOTIFY_INFO)); int pData = (int)pNotifyInfo + Marshal.SizeOf(typeof(PRINTER_NOTIFY_INFO)); PRINTER_NOTIFY_INFO_DATA[] data = new PRINTER_NOTIFY_INFO_DATA[info.Count]; for (uint i = 0; i < info.Count; i++) { data[i] = (PRINTER_NOTIFY_INFO_DATA)Marshal.PtrToStructure((IntPtr)pData, typeof(PRINTER_NOTIFY_INFO_DATA)); pData += Marshal.SizeOf(typeof(PRINTER_NOTIFY_INFO_DATA)); } #endregion #region iterate through all elements in the data array for (int i = 0; i < data.Count(); i++) { if ( (data[i].Field == (ushort)PRINTERJOBNOTIFICATIONTYPES.JOB_NOTIFY_FIELD_STATUS) && (data[i].Type == (ushort)PRINTERNOTIFICATIONTYPES.JOB_NOTIFY_TYPE) ) { JOBSTATUS jStatus = (JOBSTATUS)Enum.Parse(typeof(JOBSTATUS), data[i].NotifyData.Data.cbBuf.ToString()); int intJobID = (int)data[i].Id; string strJobName = ""; PrintSystemJobInfo pji = null; try { _spooler = new PrintQueue(new PrintServer(), _spoolerName); pji = _spooler.GetJob(intJobID); if (!objJobDict.ContainsKey(intJobID)) objJobDict[intJobID] = pji.Name; strJobName = pji.Name; } catch { pji = null; objJobDict.TryGetValue(intJobID, out strJobName); if (strJobName == null) strJobName = ""; } if (OnJobStatusChange != null) { //Let us raise the event OnJobStatusChange(this,new PrintJobChangeEventArgs(intJobID,strJobName,jStatus,pji)); } } } #endregion #region reset the Event and wait for the next event _mrEvent.Reset(); _waitHandle = ThreadPool.RegisterWaitForSingleObject(_mrEvent, new WaitOrTimerCallback(PrinterNotifyWaitCallback), _mrEvent, -1, true); #endregion }
public void PrinterNotifyWaitCallback(Object state, bool timedOut) { if (_printerHandle == IntPtr.Zero) { return; } #region read notification details _notifyOptions.Count = 1; int pdwChange = 0; IntPtr pNotifyInfo = IntPtr.Zero; bool bResult = FindNextPrinterChangeNotification(_changeHandle, out pdwChange, _notifyOptions, out pNotifyInfo); //If the Printer Change Notification Call did not give data, exit code if ((bResult == false) || (((int)pNotifyInfo) == 0)) { return; } //If the Change Notification was not relgated to job, exit code bool bJobRelatedChange = ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_ADD_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_ADD_JOB) || ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_SET_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_SET_JOB) || ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_DELETE_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_DELETE_JOB) || ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_WRITE_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_WRITE_JOB); if (!bJobRelatedChange) { return; } #endregion #region populate Notification Information // Initialize and populate the Notify Info data PRINTER_NOTIFY_INFO info = (PRINTER_NOTIFY_INFO)Marshal.PtrToStructure(pNotifyInfo, typeof(PRINTER_NOTIFY_INFO)); int pData = (int)pNotifyInfo + Marshal.SizeOf(typeof(PRINTER_NOTIFY_INFO)); PRINTER_NOTIFY_INFO_DATA[] data = new PRINTER_NOTIFY_INFO_DATA[info.Count]; for (uint i = 0; i < info.Count; i++) { data[i] = (PRINTER_NOTIFY_INFO_DATA)Marshal.PtrToStructure((IntPtr)pData, typeof(PRINTER_NOTIFY_INFO_DATA)); pData += Marshal.SizeOf(typeof(PRINTER_NOTIFY_INFO_DATA)); } #endregion // Iterate through all elements in the data array for (int i = 0; i < data.Length; i++) { if ((data[i].Field == (ushort)PRINTERJOBNOTIFICATIONTYPES.JOB_NOTIFY_FIELD_STATUS) && (data[i].Type == (ushort)PRINTERNOTIFICATIONTYPES.JOB_NOTIFY_TYPE)) { JOBSTATUS jStatus = (JOBSTATUS)Enum.Parse(typeof(JOBSTATUS), data[i].NotifyData.Data.cbBuf.ToString()); { int intJobID = (int)data[i].Id; string strJobName = ""; PrintSystemJobInfo pji = null; try { _spooler = new PrintQueue(new PrintServer(), _spoolerName); pji = _spooler.GetJob(intJobID); if (!objJobDict.ContainsKey(intJobID)) { objJobDict[intJobID] = pji.Name; } strJobName = pji.Name; } catch { pji = null; objJobDict.TryGetValue(intJobID, out strJobName); if (strJobName == null) { strJobName = ""; } } if (OnJobStatusChange != null) { if ((jStatus & JOBSTATUS.JOB_STATUS_DELETING) == JOBSTATUS.JOB_STATUS_DELETING && (jStatus & JOBSTATUS.JOB_STATUS_PRINTING) == JOBSTATUS.JOB_STATUS_PRINTING && (jStatus & JOBSTATUS.JOB_STATUS_PRINTED) == JOBSTATUS.JOB_STATUS_PRINTED) { if (intJobID != _lastJobID) { // Raise the event OnJobStatusChange(this, new PrintJobChangeEventArgs(intJobID, strJobName, jStatus, pji)); _lastJobID = intJobID; } } } } } } // Reset the Event and wait for the next event _mrEvent.Reset(); _waitHandle = ThreadPool.RegisterWaitForSingleObject(_mrEvent, new WaitOrTimerCallback(PrinterNotifyWaitCallback), _mrEvent, -1, true); }
/** \brief Detalles del Trabajo de Impresion * \param Printer Nombre de impresora * \param JobId Número de trabajo de impresión * \param PrintJob Estructura para almacenar las propiedades del trabajo de impresión, pasado por referencia * \details * Con este método recuperamos los detalles del trabajo de impresión: Cola, Número de Páginas, Tamaño página, Usuario, etc. * \remarks Hay que revisar si la propiedad PrintQueue.IsRawOnlyEnabled = False indica que el spool del trabajo * se almacena en formato EMF. */ public static void DetailsPrint(string Printer, string JobId, ref STRUCT_PRINT_JOB PrintJob) { PrintQueue ColaImpresion = null; PrintSystemJobInfo JobInfo = null; Log.Debug("========================================================================="); Log.Debug(" NAMESPACE System.Printing"); Log.Debug("========================================================================="); Log.Debug(""); /// Conectamos con el Servidor de impresión local LocalPrintServer ServidorImpresionLocal = null; try { ServidorImpresionLocal = new LocalPrintServer(); Log.Debug("==> Servidor de Impresión: " + ServidorImpresionLocal.Name); } catch (Exception e) { Log.Error("No se puede abrir el Servidor de Impresión Local: " + e); throw e; } /// Abrimos la impresora y su trabajo de Impresión pasados como argumentos al método Log.Debug("==> Trabajo de impresión: " + JobId + " a través de la Cola de Impresión: " + Printer); try { Log.Debug("Abrimos conexión con impresora: " + Printer); ColaImpresion = (PrintQueue)ServidorImpresionLocal.GetPrintQueue(Printer); Log.Debug("Recuperamos trabajo de Impresión: " + JobId); ColaImpresion.GetJob(Convert.ToInt32(JobId)); ColaImpresion.Refresh(); /// - Generamos log con las propiedades del Trabajo de Impresión if (ColaImpresion.IsRawOnlyEnabled) { Log.Debug("==> La cola de impresión sólo utiliza RAW."); } else { Log.Debug("==> La cola de impresión admite EMF."); } /// Se guarda en el log los detalles del trabajo de impresión Log.Debug("PageMediaSizeName: " + ColaImpresion.CurrentJobSettings.CurrentPrintTicket.PageMediaSize.PageMediaSizeName); Log.Debug("PageMediaSize: " + ColaImpresion.CurrentJobSettings.CurrentPrintTicket.PageMediaSize); Log.Debug("Width: " + ColaImpresion.CurrentJobSettings.CurrentPrintTicket.PageMediaSize.Width); Log.Debug("Height: " + ColaImpresion.CurrentJobSettings.CurrentPrintTicket.PageMediaSize.Height); Log.Debug("Número copias: " + ColaImpresion.CurrentJobSettings.CurrentPrintTicket.CopyCount); Log.Debug("OutputColor: " + ColaImpresion.CurrentJobSettings.CurrentPrintTicket.OutputColor); Log.Debug("PageOrientation: " + ColaImpresion.CurrentJobSettings.CurrentPrintTicket.PageOrientation); Log.Debug("Duplexing: " + ColaImpresion.CurrentJobSettings.CurrentPrintTicket.Duplexing); Log.Debug("OutputColor: " + ColaImpresion.CurrentJobSettings.CurrentPrintTicket.OutputColor); Log.Debug("=====> Propiedades JOB a través PrintSystemJobInfoFO ===="); JobInfo = PrintSystemJobInfo.Get(ColaImpresion, Convert.ToInt32(JobId)); Log.Debug("JobStatus: " + JobInfo.JobStatus); Log.Debug("Name: " + JobInfo.Name); Log.Debug("NumberOfPages: " + JobInfo.NumberOfPages); Log.Debug("NumberOfPagesPrinted: " + JobInfo.NumberOfPagesPrinted); Log.Debug("Submitter: " + JobInfo.Submitter); Log.Debug("TimeJobSubmitted: " + JobInfo.TimeJobSubmitted.ToString()); Log.Debug("JobSize: " + JobInfo.JobSize); /// - Almacenamos las propiedades del Trabajo de Impresión en el struct de entrada al método pasado por referencia PrintJob.F_PRINTJOB = JobInfo.TimeJobSubmitted.ToLocalTime().Day.ToString().PadLeft(2, '0') + "/" + JobInfo.TimeJobSubmitted.ToLocalTime().Month.ToString().PadLeft(2, '0') + "/" + JobInfo.TimeJobSubmitted.ToLocalTime().Year.ToString().PadLeft(4, '0') + " " + JobInfo.TimeJobSubmitted.ToLocalTime().Hour.ToString().PadLeft(2, '0') + ":" + JobInfo.TimeJobSubmitted.ToLocalTime().Minute.ToString().PadLeft(2, '0') + ":" + JobInfo.TimeJobSubmitted.ToLocalTime().Second.ToString().PadLeft(2, '0'); PrintJob.ID_JOBNAME = PrintJob.N_JOB.ToString().PadLeft(5, '0') + "_" + PrintJob.F_PRINTJOB; PrintJob.ID_FUENTE = "System.Printing"; PrintJob.ID_LOGIN = JobInfo.Submitter; PrintJob.ID_PRINTSERVER = ServidorImpresionLocal.Name; PrintJob.ID_DOCUMENT = JobInfo.Name; PrintJob.N_PAGES = JobInfo.NumberOfPages; PrintJob.N_PAGES_PRINTED = JobInfo.NumberOfPagesPrinted; PrintJob.N_LENGTH = (int)ColaImpresion.CurrentJobSettings.CurrentPrintTicket.PageMediaSize.Height; PrintJob.N_WIDTH = (int)ColaImpresion.CurrentJobSettings.CurrentPrintTicket.PageMediaSize.Width; PrintJob.ID_MEDIASIZE = ColaImpresion.CurrentJobSettings.CurrentPrintTicket.PageMediaSize.ToString(); // PageMediaSizeName; PrintJob.N_MEDIASIZE = (int)ColaImpresion.CurrentJobSettings.CurrentPrintTicket.PageMediaSize.PageMediaSizeName; PrintJob.N_ORIENTATION = (int)ColaImpresion.CurrentJobSettings.CurrentPrintTicket.PageOrientation; PrintJob.ID_ORIENTATION = ColaImpresion.CurrentJobSettings.CurrentPrintTicket.PageOrientation.ToString(); PrintJob.N_COPIES = (int)ColaImpresion.CurrentJobSettings.CurrentPrintTicket.CopyCount; PrintJob.ID_COLOR = ColaImpresion.CurrentJobSettings.CurrentPrintTicket.OutputColor.ToString(); PrintJob.N_COLOR = (int)ColaImpresion.CurrentJobSettings.CurrentPrintTicket.OutputColor; PrintJob.ID_DUPLEX = ColaImpresion.CurrentJobSettings.CurrentPrintTicket.Duplexing.ToString(); if (ColaImpresion.CurrentJobSettings.CurrentPrintTicket.Duplexing != null) { PrintJob.N_DUPLEX = (int)ColaImpresion.CurrentJobSettings.CurrentPrintTicket.Duplexing; } PrintJob.ID_STATUS = JobInfo.JobStatus.ToString(); // ?: Operador condicional ==> (condicion) ? valor_caso_verdadero : valor_caso_falso PrintJob.N_COLORPAGES = (PrintJob.ID_COLOR.ToUpper() == "COLOR") ? PrintJob.N_PAGES_PRINTED: 0; PrintJob.N_JOBSIZE = JobInfo.JobSize; } catch (Exception e) { Log.Error("No se puede abrir el trabajo de impresión: " + JobId + " a través de la Cola de Impresión: " + Printer); Log.Fatal("Comprobar que en la impresora: " + Printer + " se guardan los trabajos de impresión", e); throw e; } } // Fin DetailsPrint()
internal void PrinterNotifyWaitCallback(object state, bool timedOut) { if (_printerHandle == IntPtr.Zero) { return; } _notifyOptions.Count = 1; int pdwChange = 0; var pNotifyInfo = IntPtr.Zero; bool bResult = FindNextPrinterChangeNotification(_changeHandle, out pdwChange, _notifyOptions, ref pNotifyInfo); if (bResult == false || pNotifyInfo == IntPtr.Zero) { return; } bool bJobRelatedChange = (pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_ADD_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_ADD_JOB || (pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_SET_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_SET_JOB || (pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_DELETE_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_DELETE_JOB || (pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_WRITE_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_WRITE_JOB; if (!bJobRelatedChange) { return; } var info = (PRINTER_NOTIFY_INFO)Marshal.PtrToStructure(pNotifyInfo, typeof(PRINTER_NOTIFY_INFO)); long pData = (long)pNotifyInfo + (long)Marshal.OffsetOf(typeof(PRINTER_NOTIFY_INFO), "aData"); var data = new PRINTER_NOTIFY_INFO_DATA[info.Count]; for (uint i = 0; i < info.Count; i++) { data[i] = (PRINTER_NOTIFY_INFO_DATA)Marshal.PtrToStructure((IntPtr)pData, typeof(PRINTER_NOTIFY_INFO_DATA)); pData += Marshal.SizeOf(typeof(PRINTER_NOTIFY_INFO_DATA)); } for (int i = 0; i < data.Count(); i++) { if (data[i].Field == (ushort)PRINTERJOBNOTIFICATIONTYPES.JOB_NOTIFY_FIELD_STATUS && data[i].Type == (ushort)PRINTERNOTIFICATIONTYPES.JOB_NOTIFY_TYPE ) { var jStatus = (JOBSTATUS)Enum.Parse(typeof(JOBSTATUS), data[i].NotifyData.Data.cbBuf.ToString()); int intJobId = (int)data[i].Id; string strJobName; PrintSystemJobInfo pji = null; try { _spooler = new PrintQueue(new PrintServer(), SpoolerName); pji = _spooler.GetJob(intJobId); if (!_objJobDict.ContainsKey(intJobId)) { _objJobDict[intJobId] = pji.Name; } strJobName = pji.Name; } catch { //Trace.WriteLine(ex.Message); pji = null; _objJobDict.TryGetValue(intJobId, out strJobName); if (strJobName == null) { strJobName = string.Empty; } } if (OnJobStatusChange != null) { //Let us raise the event OnJobStatusChange(this, new PrintJobChangeEventArgs(intJobId, strJobName, jStatus, pji)); } } } _mrEvent.Reset(); _waitHandle = ThreadPool.RegisterWaitForSingleObject(_mrEvent, PrinterNotifyWaitCallback, _mrEvent, -1, true); }
/// <summary> /// Отлавливается нужное задание и вызывается событие, на которое подписались в вызывающем коде /// </summary> /// <param name="state"></param> /// <param name="timedOut"></param> internal void PrinterNotifyWaitCallback(object state, bool timedOut) { if (_printerHandle == IntPtr.Zero) { return; } #region read notification details _notifyOptions.Count = 1; var pdwChange = 0; IntPtr pNotifyInfo; var bResult = FindNextPrinterChangeNotification(_changeHandle, out pdwChange, _notifyOptions, out pNotifyInfo); _notifyOptions.dwFlags = 0; //If the Printer Change Notification Call did not give data, exit code if ((bResult == false) || (((int)pNotifyInfo) == 0)) { return; } //If the Change Notification was not relgated to job, exit code var bJobRelatedChange = ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_ADD_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_ADD_JOB) || ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_SET_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_SET_JOB) || ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_DELETE_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_DELETE_JOB) || ((pdwChange & PRINTER_CHANGES.PRINTER_CHANGE_WRITE_JOB) == PRINTER_CHANGES.PRINTER_CHANGE_WRITE_JOB); if (!bJobRelatedChange) { return; } #endregion #region populate Notification Information //Now, let us initialize and populate the Notify Info data var info = (PRINTER_NOTIFY_INFO)Marshal.PtrToStructure(pNotifyInfo, typeof(PRINTER_NOTIFY_INFO)); var pData = (long)pNotifyInfo + (long)Marshal.OffsetOf(typeof(PRINTER_NOTIFY_INFO), "aData"); var data = new PRINTER_NOTIFY_INFO_DATA[info.Count]; for (uint i = 0; i < info.Count; i++) { data[i] = (PRINTER_NOTIFY_INFO_DATA)Marshal.PtrToStructure((IntPtr)pData, typeof(PRINTER_NOTIFY_INFO_DATA)); pData += Marshal.SizeOf(typeof(PRINTER_NOTIFY_INFO_DATA)); } #endregion #region iterate through all elements in the data array for (var i = 0; i < data.Count(); i++) { if (data[i].Field == (ushort)PRINTERJOBNOTIFICATIONTYPES.JOB_NOTIFY_FIELD_STATUS && (data[i].Type == (ushort)PRINTERNOTIFICATIONTYPES.JOB_NOTIFY_TYPE || data[i].Type == (ushort)PRINTERJOBNOTIFICATIONTYPES.JOB_NOTIFY_FIELD_TOTAL_PAGES) ) { var jStatus = (JOBSTATUS)Enum.Parse(typeof(JOBSTATUS), data[i].NotifyData.Data.cbBuf.ToString()); if ((jStatus & JOBSTATUS.JOB_STATUS_DELETING) != 0 || (jStatus & JOBSTATUS.JOB_STATUS_DELETED) != 0 || (jStatus & JOBSTATUS.JOB_STATUS_ERROR) != 0) { return; } var intJobId = (int)data[i].Id; string strJobName; PrintSystemJobInfo pji = null; try { _spooler = new PrintQueue(new PrintServer(), SpoolerName); pji = _spooler.GetJob(intJobId); if (!_objJobDict.ContainsKey(intJobId)) { _objJobDict[intJobId] = $"'n:{pji.Name}|js:{pji.JobStatus}|pn:{pji.NumberOfPages}|ji:{intJobId}|{Guid.NewGuid().ToString()}'"; } strJobName = pji.Name; pji.Refresh(); } catch (Exception ex) { pji = null; _objJobDict.TryGetValue(intJobId, out strJobName); if (strJobName == null) { strJobName = string.Empty; } Registry.GetValue <Logger>().Error(ex, "When extract job"); return; } if (OnJobStatusChange != null) { //Let us raise the event calls: pqm_OnJobStatusChange JobDetail jobDetails = GetJobDetail(data[i].Id); //Get detalis about job OnJobStatusChange(this, new PrintJobChangeEventArgs(intJobId, _objJobDict[intJobId], strJobName, jStatus, jobDetails, pji)); //Set pause for job } } } #endregion #region reset the Event and wait for the next event _mrEvent.Reset(); _waitHandle = ThreadPool.RegisterWaitForSingleObject(_mrEvent, PrinterNotifyWaitCallback, _mrEvent, -1, true); #endregion }