} //Fin PrinterProperties() /** * \brief Se establecen las propiedades de las impresoras gestionadas por el Servidor de impresión * \details La única propiedad que nos interesa establecer y mantener para poder monitorizar los trabajos de impresión es que * "Conserven los documentos después de su impresión" (Se conserven los ficheros de Spool) */ public static void ConfigurePrinters() { PrintQueue printQueue = null; LocalPrintServer localPrintServer; try { /// Accedemos al Servidor de Impresión Local localPrintServer = new LocalPrintServer(); Log.Debug(">>> Servidor de impresion: '" + localPrintServer.Name + "'"); /// Accedemos a las impresoras gestionadas por el Servidor de Impresión Local PrintQueueCollection localPrinterCollection = localPrintServer.GetPrintQueues(); System.Collections.IEnumerator localPrinterEnumerator = localPrinterCollection.GetEnumerator(); /// Recorremos todas las impresoras y revisamos su configuración para que se conserven los ficheros de Spool while (localPrinterEnumerator.MoveNext()) { printQueue = (PrintQueue)localPrinterEnumerator.Current; ApiImpresion PrintServer = new ApiImpresion(); PrintServer.KeepSpoolFiles(printQueue.Name); printQueue.Refresh(); } //while } catch (Exception e) { Log.Error(e); } //try } //ConfigurePrinters()
/** \brief Análisis del trabajo de Impresión. * \return No devuelve nada. * \details * Se guardan en B.D las propiedades del trabajo de impresión obtenidas a través de las API de impresión, del namespace * System.Printing y del análisis de los ficheros de Spool correspondientes al trabajo de impresión. */ private void AnalizePrintJob() // string Printer, string JobId) { // Objeto para permitir una espera en caso de que el fichero de spool este abierto ElapsedTime TiempoEspera; // Fichero de spool que se tiene que analizar FileInfo MiFileInfo; // Estructura utilizada para guardar los trabajos de impresión STRUCT_PRINT_JOB PrintJob = new STRUCT_PRINT_JOB(); this.ID_JOBNAME = ""; this.N_JOB = Convert.ToInt32(this.JobId); this.ID_PRINTER = this.Printer; // La impresora ¿es un plotter? if (Util.ContieneTexto(this.Printer, "Plotter")) { PrintJob.ID_ISPLOTTER = "S"; } else { PrintJob.ID_ISPLOTTER = "N"; } bool AnalizedSpool = false; //Se recuperan los primeros detalles del trabajo de impresión PrintJob.N_JOB = this.N_JOB; PrintJob.ID_PRINTER = this.ID_PRINTER; /// - Propiedades obtenidas a través del namespace System.Printing try { // Recuperamos las propiedades LocalPrinting.DetailsPrint(PrintJob.ID_PRINTER, this.JobId, ref PrintJob); this.ID_JOBNAME = PrintJob.ID_JOBNAME; this.F_PRINTJOB = PrintJob.F_PRINTJOB; Log.Info(" -- Se extraen las propiedades utilizando System.Printing --"); // Generamos log LogPrintJob(ref PrintJob); // Guardamos en B.D SavePrintJob(ref PrintJob); } catch (Exception e) { Log.Fatal("Error extrayendo propiedades a través de System.Printing"); Log.Fatal(e); } /// - Propiedades obtenidas a través de las APIs de impresión LimpiaStrucPrintJob(ref PrintJob); PrintJob.ID_JOBNAME = ID_JOBNAME; try { // Recuperamos las propiedades ApiImpresion MiApiImpresion = new ApiImpresion(); MiApiImpresion.Analize(this.Printer, (uint)Convert.ToInt32(this.JobId), ref PrintJob); // Guardamos en B.D las propiedades obtenidas Log.Info(" -- Se extraen las propiedades utilizando las API de impresión. --"); LogPrintJob(ref PrintJob); SavePrintJob(ref PrintJob); /// Enviamos información del trabajo de impresión via email LogPrintJobMail(ref PrintJob); } catch (Exception e) { Log.Fatal("No se puede analizar el trabajo de impresión: " + this.JobId + " a través de las APIs de winspool.drv."); Log.Fatal(e); } //try /// Para el analisis de ficheros de Spool, antes de empezar, nos aseguramos de que el fichero no está bloqueado // Establecemos un tiempo de espera TiempoEspera = new ElapsedTime(); // Fichero de spool que se tiene que analizar MiFileInfo = new FileInfo(LocalPrinting.PathPrintSpool() + @"\" + this.JobId.PadLeft(5, '0') + ".SPL"); while ((!TiempoEspera.OverElapsedTime()) & WatchIO.IsFileLocked(MiFileInfo)) { // Se da tiempo a que se libere el archivo de Spool System.Threading.Thread.Sleep(10); } /// - Propiedades obtenidas a través del análisis del fichero de Spool con lenguaje EMF LimpiaStrucPrintJob(ref PrintJob); PrintJob.ID_JOBNAME = ID_JOBNAME; if (PrintJob.N_JOBSIZE > 0) { try { Log.Debug("Analizamos si es lenguaje EMF"); // Se comenta la siguiente línea al desactivar la suscripción a los eventos del sistema de archivos de la clase WatchIO EmfSpool MyEmfSpool = new EmfSpool(LocalPrinting.PathPrintSpool() + @"\" + this.JobId.PadLeft(5, '0') + ".SPL"); MyEmfSpool.Analize(ref PrintJob); AnalizedSpool = true; Log.Info("Establecemos como fuente del análisis: EMF"); PrintJob.ID_FUENTE = "EMF"; Log.Info(" -- Se extraen las propiedades utilizando analisis EMF. --"); LogPrintJob(ref PrintJob); SavePrintJob(ref PrintJob); /// Enviamos información del trabajo de impresión via email LogPrintJobMail(ref PrintJob); } catch (Exception e) { Log.Info("El trabajo de impresión: " + this.JobId + " no utiliza lenguaje EMF."); Log.Fatal(e); }//try } /// - Propiedades obtenidas a través del análisis del fichero de Spool con lenguaje JPL. LimpiaStrucPrintJob(ref PrintJob); PrintJob.ID_JOBNAME = ID_JOBNAME; if ((!AnalizedSpool) && (PrintJob.N_JOBSIZE > 0)) { try { Log.Debug("Analizamos si es lenguaje JPL"); // Se comentan las siguientes 2 líneas al desactivar la suscripción a los eventos del sistema de archivos de la clase WatchIO Log.Debug(LocalPrinting.PathPrintSpool() + @"\" + @"\" + this.JobId.PadLeft(5, '0') + ".SPL"); JPLSpool MyJPLSpool = new JPLSpool(LocalPrinting.PathPrintSpool() + @"\" + this.JobId.PadLeft(5, '0') + ".SPL"); MyJPLSpool.Analize(ref PrintJob); AnalizedSpool = true; Log.Info(" -- Se extraen las propiedades utilizando analisis JPL. --"); LogPrintJob(ref PrintJob); SavePrintJob(ref PrintJob); /// Enviamos información del trabajo de impresión via email LogPrintJobMail(ref PrintJob); } catch (Exception e) { Log.Info("No se puede analizar el trabajo de impresión: " + this.JobId + " mediante análisis JPL."); Log.Fatal(e); } //try } //if Log.Debug("Trabajo de impresión: " + this.JobId + "en impresora " + this.Printer + " analizado con éxito"); } //AnalizeSpool()
} // EvenCapture /** * \brief Analisis de los Eventos de Impresión. * \details Los eventos de impresión se reciben en formato XML. Por lo que se ha construido un método para analizar los eventos en formato XML * \param eventoXML objeto con el contenido XML del evento que se va a analizar * \remarks * Se definen los códigos de eventos de impresión en la enumeración: ENUM_SYSTEM_PRINTING.EVENTS */ private static void AnalizeXmlParameters(Object eventoXML) { /// Si se ejecuta este método es por que está suscrito a los eventos del Servidor de Impresión. /// Establecemos por tanto el atributo para controlar si se están capturando los eventos de impresión: "IsEvenCapture" como verdadero. IsEvenCapture = true; Log.Debug(" -- Inicio AnalizeXmlParameters: -- " + Thread.CurrentThread.Name); /// Se carga el contenido XML del evento en un objeto tipo documento XML XmlDocument xDoc = new XmlDocument(); //Log.Debug("EvenRecord en XML: " + eventoXML); xDoc.LoadXml((string)eventoXML); Log.Debug(eventoXML.ToString()); // Estraemos los Parametros del evento XmlNodeList ElementoSystem = xDoc.GetElementsByTagName("System"); /// Obtenemos el evento. XmlNodeList nodosEventID = xDoc.GetElementsByTagName("EventID"); Log.Debug("Nombre del nodo: " + nodosEventID.Item(0).Name + ", Valor: " + nodosEventID.Item(0).InnerXml); Int16 IdEvento = Convert.ToInt16(nodosEventID.Item(0).InnerXml); // Se actualza la propiedad LastEven con el Evento de impresión que se está analizando. Necesario para realizar las pruebas unitarias. LastEvent = IdEvento; /// Se analizan los siguientes eventos de impresión y se extaen los parámetros asociados: switch (IdEvento) { case (short)ENUM_SYSTEM_PRINTING.EVENTS.PRINTER_PAUSED: //303: { /// - Pausar cola impresion XmlNodeList PrinterPaused = xDoc.GetElementsByTagName("PrinterPaused"); break; } case (short)ENUM_SYSTEM_PRINTING.EVENTS.PRINTER_UNPAUSED: // 304: { /// - Reanudar Impresora pausada XmlNodeList PrinterUnPaused = xDoc.GetElementsByTagName("PrinterUnPaused"); foreach (XmlElement nodo in PrinterUnPaused) { // Para indexar el nodo actual de los elementos PrinterUnPaused int i = 0; Log.Info("(Id. Evento: " + IdEvento.ToString() + ")" + "Param1: " + nodo.GetElementsByTagName("Param1")[i].InnerXml); i++; } break; } case (short)ENUM_SYSTEM_PRINTING.EVENTS.PRINTER_SET: // 306: { /// - Estableciendo configuracion de Impresora. Se comprueba que los trabajos de impresión se guardenen disco, sino, se vuelve a configurar /// para que se guarden. XmlNodeList PrinterSet = xDoc.GetElementsByTagName("PrinterSet"); foreach (XmlElement nodo in PrinterSet) { // Para indexar el nodo actual de los elementos PrinterSet int i = 0; Log.Info("(Id. Evento: " + IdEvento.ToString() + ")" + "Param1: " + nodo.GetElementsByTagName("Param1")[i].InnerXml); string Printer = nodo.GetElementsByTagName("Param1")[i].InnerXml; //Esperamos 1 sg. System.Threading.Thread.Sleep(1000); /// - - Con "ApiImpresion.KeepSpoolFiles(Printer)" aseguramos que se guarden los trabajos de impresión. ApiImpresion PrintServer = new ApiImpresion(); PrintServer.KeepSpoolFiles(Printer); i++; } break; } case (short)ENUM_SYSTEM_PRINTING.EVENTS.DOCUMENT_PRINTED: //307 { /// - Se ha imprimido el documento. Este evento en especial es muy importante por que cuando se detecta hacemos que se desencadene el proceso de análisis /// del trabajo de impresión con la creación de un objeto de la clase "AnalizeJobId". Este evento lleva asociadas las siguientes propiedades del Trabajo /// de impresión: /// - - Número de trabajo de impresión /// - - Nombre de documento /// - - Usuario /// - - Servidor de impresión /// - - Impresora /// - - Puerto /// - - Tamaño en bytes del fichero del trabajo de impresión /// - - Número de hojas XmlNodeList DocumentPrinted = xDoc.GetElementsByTagName("DocumentPrinted"); foreach (XmlElement nodo in DocumentPrinted) { // Para indexar el nodo actual de los elementos DocumentPrinted int i = 0; // Log de los parámetros Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Param1: " + nodo.GetElementsByTagName("Param1")[i].InnerXml); //JobId Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Param2: " + nodo.GetElementsByTagName("Param2")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Param3: " + nodo.GetElementsByTagName("Param3")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Param4: " + nodo.GetElementsByTagName("Param4")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Param5: " + nodo.GetElementsByTagName("Param5")[i].InnerXml); //Printer Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Param6: " + nodo.GetElementsByTagName("Param6")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Param7: " + nodo.GetElementsByTagName("Param7")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Param8: " + nodo.GetElementsByTagName("Param8")[i].InnerXml); string JobId = nodo.GetElementsByTagName("Param1")[i].InnerXml; string Printer = nodo.GetElementsByTagName("Param5")[i].InnerXml; // Se analiza el trabajo de impresión con la clase AnalizeJobId AnalizeJobId MyAnalizeJobId = new AnalizeJobId(Printer, JobId); i++; } break; } case (short)ENUM_SYSTEM_PRINTING.EVENTS.DOCUMENT_RESUMED: // 309: { /// - Reanudación inpresión XmlNodeList DocumentResumed = xDoc.GetElementsByTagName("DocumentResumed"); foreach (XmlElement nodo in DocumentResumed) { // Para indexar el nodo actual de los elementos DocumentPrinted int i = 0; //XmlNodeList Param1 = nodo.GetElementsByTagName("Param1"); //JobId // Log de los parámetros Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Param1(JobId): " + nodo.GetElementsByTagName("Param1")[i].InnerXml); //JobId Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Param2(Documento): " + nodo.GetElementsByTagName("Param2")[i].InnerXml); //Documento Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Param3(Usuario): " + nodo.GetElementsByTagName("Param3")[i].InnerXml); //Usuario Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Param4(Printer): " + nodo.GetElementsByTagName("Param4")[i].InnerXml); //Printer i++; } break; } case (short)ENUM_SYSTEM_PRINTING.EVENTS.DOCUMENT_DELETED: // 310: { /// - Trabajo de impresion eliminado XmlNodeList DocumentDeleted = xDoc.GetElementsByTagName("DocumentDeleted"); foreach (XmlElement nodo in DocumentDeleted) { // Para indexar el nodo actual de los elementos DocumentDeleted int i = 0; // Log de los parámetros Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Param1: " + nodo.GetElementsByTagName("Param1")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Param2: " + nodo.GetElementsByTagName("Param2")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Param3: " + nodo.GetElementsByTagName("Param3")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Param4: " + nodo.GetElementsByTagName("Param4")[i].InnerXml); i++; } break; } case (short)ENUM_SYSTEM_PRINTING.EVENTS.JOB_DIAG: // 800: { /// - Poniendo el trabajo en cola XmlNodeList JobDiag = xDoc.GetElementsByTagName("JobDiag"); foreach (XmlElement nodo in JobDiag) { // Para indexar el nodo actual de los elementos JobDiag int i = 0; // Log de los parámetros. Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "JobId: " + nodo.GetElementsByTagName("JobId")[i].InnerXml); i++; } break; } case (short)ENUM_SYSTEM_PRINTING.EVENTS.JOB_DIAG_PRINTING: // 801: { /// - Imprimiendo trabajo. XmlNodeList JobDiag = xDoc.GetElementsByTagName("JobDiag"); foreach (XmlElement nodo in JobDiag) { // Para indexar el nodo actual de los elementos JobDiag int i = 0; // Log del parámetro Log.Info("Id. Evento: (" + IdEvento.ToString() + ")" + "JobId: " + nodo.GetElementsByTagName("JobId")[i].InnerXml); i++; } break; } case (short)ENUM_SYSTEM_PRINTING.EVENTS.DELETE_JOB_DIAG: // 802: { /// - Se elimina el trabajo de impresion XmlNodeList DeleteJobDiag = xDoc.GetElementsByTagName("DeleteJobDiag"); foreach (XmlElement nodo in DeleteJobDiag) { // Para indexar el nodo actual de los elementos DeleteJobDiag int i = 0; // Log parámetros Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "JobId: " + nodo.GetElementsByTagName("JobId")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "JobSize: " + nodo.GetElementsByTagName("JobSize")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "DataType: " + nodo.GetElementsByTagName("DataType")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Pages: " + nodo.GetElementsByTagName("Pages")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "PagesPerSide: " + nodo.GetElementsByTagName("PagesPerSide")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "FilesOpened: " + nodo.GetElementsByTagName("FilesOpened")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "JobSizeHigh: " + nodo.GetElementsByTagName("JobSizeHigh")[i].InnerXml); i++; } break; } case (short)ENUM_SYSTEM_PRINTING.EVENTS.RENDER_JOB_DIAG: //805: { /// - Presentando trabajo impresión. XmlNodeList RenderJobDiag = xDoc.GetElementsByTagName("RenderJobDiag"); foreach (XmlElement nodo in RenderJobDiag) { // Para indexar el nodo actual de los elementos RenderJobDiag int i = 0; // Log parámetros Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "JobId: " + nodo.GetElementsByTagName("JobId")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "GdiJobSize: " + nodo.GetElementsByTagName("GdiJobSize")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "ICMMethod: " + nodo.GetElementsByTagName("ICMMethod")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Color: " + nodo.GetElementsByTagName("Color")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "XRes: " + nodo.GetElementsByTagName("XRes")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "YRes: " + nodo.GetElementsByTagName("YRes")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Quality: " + nodo.GetElementsByTagName("Quality")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Copies: " + nodo.GetElementsByTagName("Copies")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "TTOption: " + nodo.GetElementsByTagName("TTOption")[i].InnerXml); i++; } break; } case (short)ENUM_SYSTEM_PRINTING.EVENTS.FILE_OP_FAILED: //812: { /// - No se pudo eliminar el archivo de spool del trabajo de impresión. XmlNodeList FileOpFailed = xDoc.GetElementsByTagName("FileOpFailed"); foreach (XmlElement nodo in FileOpFailed) { // Para indexar el nodo actual de los elementos FileOpFailed int i = 0; // Comunicamos el error Log.Error("Id. Evento: " + IdEvento.ToString() + ")" + "No se puede eliminar el fichero de Spool: " + nodo.GetElementsByTagName("Source")[i].InnerXml); i++; } break; } case (short)ENUM_SYSTEM_PRINTING.EVENTS.PRINT_DRIVER_SANDBOX_JOB_PRINTPROC: // 842: { /// - El Servidor de impresión envió el trabajo a la impresora. XmlNodeList PrintDriverSandboxJobPrintProc = xDoc.GetElementsByTagName("PrintDriverSandboxJobPrintProc"); foreach (XmlElement nodo in PrintDriverSandboxJobPrintProc) { // Para indexar el nodo actual de los elementos PrintDriverSandboxJobPrintProc int i = 0; // Mostramos los valores recogidos Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "JobId: " + nodo.GetElementsByTagName("JobId")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Processor: " + nodo.GetElementsByTagName("Processor")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Printer: " + nodo.GetElementsByTagName("Printer")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Driver: " + nodo.GetElementsByTagName("Driver")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "IsolationMode: " + nodo.GetElementsByTagName("IsolationMode")[i].InnerXml); Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "ErrorCode: " + nodo.GetElementsByTagName("ErrorCode")[i].InnerXml); i++; } break; } case (short)ENUM_SYSTEM_PRINTING.EVENTS._ID_EVEN_CONTROL: // 9999: Generado por nosotros { /// - Evento autogenerado por nuestra aplicación para el control de subscripción a los eventos de Impresión. XmlNodeList RenderJobDiag = xDoc.GetElementsByTagName("EventData"); foreach (XmlElement nodo in RenderJobDiag) { int i = 0; // Log parametro Log.Info("Id. Evento: " + IdEvento.ToString() + ")" + "Data: " + nodo.GetElementsByTagName("Data")[i].InnerXml); i++; } break; } default: // Evento de impresión no controlado Log.Error(">>>>>>>>> Id. Evento: " + IdEvento.ToString() + ")" + "No se encuentra el evento " + IdEvento.ToString()); break; } } // Fin ExtractXmlParameters()