private void Print(PrintJob printJob) { string errorMessage = null; int actionID = 0; short returnCode = 0; if (Monitor.TryEnter(this.Lock, 2000)) { this.isPrinting = true; if (!this.printerSDK.IsOpen) { try { this.printerSDK.Open(this.deviceName); } catch { } } bool wasGraphicsLayerBuilt = false; try { try { this.printerSDK.ClearGraphicsLayers(); } catch { } printJob.ActionID = 0; this.printerSDK.JobControl.FeederSource = FeederSourceEnum.CardFeeder; this.printerSDK.JobControl.Destination = DestinationTypeEnum.Eject; this.printerSDK.JobControl.DeleteAfter = true; if (printJob.ImageData == null) { throw new ApplicationException("Print Job Image Data is NULL."); } byte[] printableData = BuildImage(printJob.ImageData, printJob.Orientation == Orientation.Landscape ? ZMotifGraphics.ImageOrientationEnum.Landscape : ZMotifGraphics.ImageOrientationEnum.Portrait, ZMotifGraphics.RibbonTypeEnum.Color, out errorMessage); byte[] blackImageData = null; if (printableData != null) { this.printerSDK.BuildGraphicsLayers(SideEnum.Front, PrintTypeEnum.Color, GraphicTypeEnum.BMP, printableData); if (printJob.IsHalfPanelRibbon) { blackImageData = BuildImage(printJob.BlackImageData, printJob.Orientation == Orientation.Landscape ? ZMotifGraphics.ImageOrientationEnum.Landscape : ZMotifGraphics.ImageOrientationEnum.Portrait, ZMotifGraphics.RibbonTypeEnum.MonoK, out errorMessage); if (blackImageData != null) { this.printerSDK.BuildGraphicsLayers(SideEnum.Front, PrintTypeEnum.MonoK, GraphicTypeEnum.BMP, blackImageData); } else { throw new ApplicationException(string.Format("Error Starting Print Job. Half Panel Ribbon installed and Black Image Data is NULL")); } } wasGraphicsLayerBuilt = true; returnCode = this.printerSDK.PrintGraphicsLayers(1, out actionID); if (returnCode == 0) { printJob.ActionID = actionID; } else { throw new ApplicationException(string.Format("Error {0} Starting Print Job.", returnCode)); } } else { throw new ApplicationException("Error Building Print Image."); } } catch (Exception ex) { string exceptionMessage = string.Format("Exception submitting print job.\n\n{0}", ex.Message); printJob.JobStatusCode = PrintJobStatusCode.ErrorStartingPrintJob; printJob.EndTime = DateTime.Now; ApplicationEvent.WriteToWindowsLog(System.Diagnostics.EventLogEntryType.Error, EventLogIDType.PrintJob, EventLogCategoryType.Error, exceptionMessage); returnCode = -1; this.OnPrintingComplete = null; } finally { Monitor.Exit(this.Lock); if (returnCode == 0) { this.MonitorStatus(printJob); } else { this.isPrinting = false; } } } else { ApplicationEvent.WriteToWindowsLog(System.Diagnostics.EventLogEntryType.Error, EventLogIDType.PrintJob, EventLogCategoryType.Error, string.Format("Unable to obtain lock when printing. Printer: {0}, Job ID: {1}", this.Name, printJob.JobID)); } } private byte[] BuildImage(byte[] imageData, ZMotifGraphics.ImageOrientationEnum imageOrientation, ZMotifGraphics.RibbonTypeEnum ribbonType, out string errMsg) { ZMotifGraphics graphics = null; byte[] printerImageData = null; errMsg = string.Empty; try { int dataLen = 0; using (Image image = (Image)((new ImageConverter()).ConvertFrom(imageData))) { using (Image tempImage = image.GetThumbnailImage(1024, 648, null, IntPtr.Zero)) { imageData = (byte[])new ImageConverter().ConvertTo(tempImage, typeof(byte[])); } } using (graphics = new ZMotifGraphics()) { graphics.InitGraphics(1024, 648, imageOrientation, ribbonType); if (ribbonType != ZMotifGraphics.RibbonTypeEnum.Color) { graphics.ColorProfile = string.Empty; } if (this.IsHalfPanelRibbon) { graphics.DrawImage(ref imageData, Configuration.ZXP31HalfPanelOffsetX, Configuration.ZXP31HalfPanelOffsetY, 1024, 648, 0); } else { graphics.DrawImage(ref imageData, ZMotifGraphics.ImagePositionEnum.Centered, 1024, 648, 0); } if (imageData != null) { printerImageData = graphics.CreateBitmap(out dataLen); } graphics.ClearGraphics(); graphics.CloseGraphics(); } } catch (Exception ex) { printerImageData = null; errMsg = ex.StackTrace; } finally { if (graphics != null) { graphics.Dispose(); } graphics = null; } return printerImageData; } public void MonitorStatus(PrintJob printJob) { // Start a thread to submit the print jobs so we don't affect client response time // Thread monitorStatusThread = new Thread(new ParameterizedThreadStart(this.MonitorStatusThread)); monitorStatusThread.Priority = ThreadPriority.Normal; monitorStatusThread.IsBackground = true; // Start the thread // monitorStatusThread.Start(printJob); } private void MonitorStatusThread(object parameters) { PrintJob printJob = (PrintJob)parameters; string printingStatus = null; string magStatus = null; string contactStatus = null; string contactlessStatus = null; int errorCode = 0; int copiesCompleted = 0; int copiesRequested = 0; short returnCode = 0; bool didPrintingComplete = false; double printJobTimeoutSeconds = 0.00F; //ZebraPrinterStatus currentPrinterStatus = this.status; if (this.isPrintMonitorRunning) { string message = string.Format("Print Monitor Thread Already Running. Existing Print Job ID = {0}, Print Job ID: {1}.\n\nNew Print Job ID = {2}, Print Action ID: {3}", this.printJobID, this.printJobActionID, printJob.JobID, printJob.ActionID); ApplicationEvent.WriteToWindowsLog(System.Diagnostics.EventLogEntryType.Error, EventLogIDType.PrintJobStatus, EventLogCategoryType.Error, message); return; } this.isPrintMonitorRunning = true; this.printJobID = printJob.JobID; this.printJobActionID = printJob.ActionID; Thread.Sleep(3000); while (true) { try { if (Monitor.TryEnter(this.Lock, 2000)) { try { returnCode = this.printerSDK.GetJobStatus(printJob.ActionID, out printingStatus, out errorCode, out copiesCompleted, out copiesRequested, out magStatus, out contactStatus, out contactlessStatus); if (returnCode == 0) { this.status = ZebraPrinterStatus.Printing; } else { try { this.status = (ZebraPrinterStatus)returnCode; } catch { this.status = ZebraPrinterStatus.Unknown; } } PrintJobs.Instance.UpdatePrintJob(printJob.JobID, PrintJobStatusCode.Printing, this.status.ToString(), (int)this.status); } catch (Exception ex) { string message = string.Format("Exception getting print job status.\n\n{0}", ex.Message); ApplicationEvent.WriteToWindowsLog(System.Diagnostics.EventLogEntryType.Error, EventLogIDType.PrintJobStatus, EventLogCategoryType.Error, message); } finally { Monitor.Exit(this.Lock); } } else { Thread.Sleep(2000 + (this.portNumber * 550)); continue; } } catch (Exception ex) { string message = string.Format("Exception getting print job status (Outside Lock).\n\n{0}", ex.Message); ApplicationEvent.WriteToWindowsLog(System.Diagnostics.EventLogEntryType.Error, EventLogIDType.PrintJobStatus, EventLogCategoryType.Error, message); } didPrintingComplete = (printingStatus == "done_ok"); if (didPrintingComplete) { this.status = ZebraPrinterStatus.OK; } if (returnCode != 0 || errorCode != 0 || didPrintingComplete) { Thread.Sleep(3000); this.fullSheetsRemaining = this.GetFullSheetsRemaining(); break; } else { if (printJobTimeoutSeconds > Configuration.PrintJobTimeoutSeconds) { didPrintingComplete = false; this.status = ZebraPrinterStatus.PrintJobTimeout; break; } Thread.Sleep(2000 + (this.portNumber * 550)); printJobTimeoutSeconds += (((double)2000 + (double)(this.portNumber * 550)) / 1000.00F); } } if (this.OnPrintingComplete != null) { // Configure the printing complete event // ZebraPrintingCompleteEventArgs printingCompleteEventArgs = new ZebraPrintingCompleteEventArgs(this.Name); printingCompleteEventArgs.DidPrintingComplete = didPrintingComplete; printingCompleteEventArgs.PrinterStatus = Enum.GetName(typeof(ZebraPrinterStatus), this.status); printingCompleteEventArgs.FullSheetsRemaining = this.fullSheetsRemaining; printingCompleteEventArgs.Printer = this; printingCompleteEventArgs.PrintJob = printJob; printingCompleteEventArgs.OriginalJobActionID = printJob.ActionID; printingCompleteEventArgs.JobID = this.LastPrintJobID; // Raise the printing complete event // this.OnPrintingComplete(this, printingCompleteEventArgs); } this.isPrinting = false; this.isPrintMonitorRunning = false; }