} //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()
        } // 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()