Escribir al Registro de Eventos de Windows

En caso de que aun no lo hayas descubierto, todas las aplicaciones fallaran tarde o temprano.

La pregunta no es como escribir la aplicación perfecta que nunca falle. La pregunta es como escribir una aplicación que hará mas fácil encontrar y resolver problemas en un futuro.

Además de mostrar un error al usuario, vas a querer registrar los detalles del error en alguna parte. Puede ser a un archivo, a una base de datos, a un servicio web o incluso en un correo electrónico. Yo recomiendo hacerlo a mas de un lugar.

En este post vamos a ver como registrar errores al Registro de Eventos de Windows (Menú Inicio -> Herramientas Administrativas -> Visor de Eventos).

Visor de Eventos de Windows

.NET Framework provee la clase EventLog para fácilmente leer y escribir entradas al Registro de Eventos de Windows. Esta clase se encuentra en el espacio de nombres System.Diagnostics.

Para hacer entradas al Registro de Eventos llamamos el método WriteEntry, el cual esta sobrecargado. Por ejemplo, podemos llamar la siguiente sobrecarga estática (compartida). De esta manera, no es necesario crear una instancia de la clase EventLog.

EventLog.WriteEntry("Origen", "Descripcion del Error.", EventLogEntryType.Warning);

El primer parámetro corresponde al Origen del evento, el cual usualmente es el nombre de la aplicación o del componente.

El segundo parámetro corresponde a la descripción o mensaje del evento. En este caso serian los detalles de una excepción.

El tercer parámetro es para el tipo o nivel del evento. Podría ser Información (Information), Advertencia (Warning), o Error. Hay un par de tipos que son mas específicos para el registro Seguridad. La enumeración EventLogEntryType mantiene la lista de los diferentes tipos.

Existen otras sobrecargas de este método que nos permiten especificar un identificador de evento y una categoría. Podemos definir diferentes valores para estos campos numéricos de acuerdo al tipo de error dentro de la aplicación.

Antes de poder utilizar un origen para escribir entradas en el registro de eventos es necesario registrarlo. Podemos registrar un origen de eventos con el método CreateEventSource.

EventLog.CreateEventSource("Nombre de la Aplicacion", "Nombre de Registro");

El primer parámetro es el nombre del origen, y por lo general es el nombre de la aplicación. Este método escanea todos los registros para asegurarse de que el nuevo origen es único. Puede haber problemas al llamar este método similares a los problemas con el método SourceExists, del cual hablamos mas adelante.

El segundo parámetro es el registro al que queremos escribir entradas cada vez que usemos este origen. Puede ser Aplicación, Seguridad, Sistema, o un registro personalizado. Si pasamos un nombre de registro que no existe, un nuevo registro personalizado es creado.

Solo es necesario registrar un origen de eventos una vez. Podemos verificar si un origen ya esta registrado con el método SourceExists.

if (!EventLog.SourceExists("Nombre de la Aplicacion"))

Este método escanea cada registro para comprobar si un nombre de origen existe.

Comenzando con Windows Vista, necesitamos derechos de Administrador para poder leer el Registro de Seguridad. Si no tenemos derechos suficientes, podríamos recibir una SecurityException cuando llamemos SourceExists.

No se encontró el origen, pero no se pudo buscar en algunos o todos los registros de eventos. Registros inaccesibles: Seguridad.

Esto ocurriría si nuestro origen no existe en uno de los otros registros que son accesibles, como Aplicación. Si el origen es encontrado antes de que el método intente escanear el registro de Seguridad, no habrá problema. Así que al menos la primera vez que intentemos escribir una entrada al registro de eventos, necesitamos ejecutar la aplicación como administrador.

La solución ideal seria crear el origen durante la instalación del programa, ya que el instalador es ejecutado con derechos de administrador.

Aquí esta un pequeño controlador de errores que podemos utilizar en nuestras aplicaciones.

using System;
using System.Windows.Forms;
using System.Diagnostics;

namespace Example.Business
{

    public enum ErrorType
    {
        Critical,
        Minor,
        Information
    }

    class ErrorHandler
    {
        private const String origen = "Aplicacion Ejemplo";
        private const String log = "Application"; //Aplicación para Windows en español

        internal static void RegistrarError(String msg, ErrorType type, Exception ex)
        {
            try
            {
                if (!EventLog.SourceExists(origen))
                    EventLog.CreateEventSource(origen, log);

                if (type == ErrorType.Information)
                    EventLog.WriteEntry(origen, ex.ToString(), EventLogEntryType.Information);
                else if (type == ErrorType.Minor)
                    EventLog.WriteEntry(origen, ex.ToString(), EventLogEntryType.Warning);
                else
                    EventLog.WriteEntry(origen, ex.ToString(), EventLogEntryType.Error);
            }
            catch { }
        }

        internal static void ManejarError(String msg, ErrorType type, Exception ex)
        {
            //registrar error
            RegistrarError(msg, type, ex);

            //mostrar mensaje si es conveniente
            if (type == ErrorType.Critical)
            {
                MessageBox.Show(msg, origen, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

    }
}

También damos la opción de mostrar el error al usuario. Podríamos crear un formulario para mostrar mas detalles al usuario, pero aquí solo utilizamos MessageBox.

Mantuve el código para crear el origen del evento si no existe. Como mencione antes, es mejor colocar eso en el instalador de la aplicación. Veremos como crear un instalador en otro post.

Aquí esta un ejemplo de un formulario utilizando el controlador de errores.

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using Example.Business;

namespace Example.UI
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                throw new Exception("No es posible cargar el formulario.");
            }
            catch (Exception ex)
            {
                ErrorHandler.ManejarError("Un error ha ocurrido cargando Form1.", ErrorType.Critical, ex);
            }
        }
    }
}

Aquí esta el mensaje que el usuario vería.

Mensaje de error

Y aquí esta la entrada en el Visor de Eventos después de ejecutar la aplicación una vez como administrador.

Propiedades de evento

Por favor deja tus comentarios si tienes alguna pregunta o sugerencia.

Recibir Actualizaciones Gratis
Entradas Relacionadas
Comentarios