Acceder a la caché de Internet Explorer (IV)

windowsservice

En los dos primeros artículos pudimos ver los objetos del API de Windows que íbamos a usar para poder acceder a la caché de los archivos temporales de Internet, cómo persistir estos datos en formato XML, y finalmente cómo permitir que temporalmente nuestra aplicacación se ejecute con las credenciales de otro usuario, para poder realizar una serie de acciones que de otro modo no podría efectuar por falta de privilegios.

Siguiendo con el objetivo de este ejercicio hoy vamos a encapsular la lógica de negocio de nuestra aplicación en forma de servicio de Windows, y éste va a encargarse de realizar una consulta a la caché de Internet de nuestro ordenador cada X tiempo (configurable mediante un fichero XML).

Lo primero de todo va a ser construir la base de nuestro servicio mediante un proyecto de tipo Windows Service. Esta plantilla nos genera un proyecto con un componente de tipo ServiceBase, que servirá para ir construyendo nuestro pequeño juguetito.

CreateWindowsService

A continuación vamos a cambiar el nombre al servicio, en nuestro caso lo llamaremos "IECacheQueryService". Y posteriormente estableceremos a True los valores de las propiedades CanPauseAndContinue y CanShutdown, para poder pausar y detener nuestro servicio en tiempo de ejecución.

Importante: Comprobar que el nombre sel servicio se ha cambiado correctamente en el punto de entrada de la aplicación (si no fuese así tendremos que modificarlo manualmente):

static class Program
    {
        static void Main()
        {
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                new IECacheQueryService() 
            };
 
            ServiceBase.Run(ServicesToRun);
        }
    }

Implementando funcionalidad al servicio:

De momento el servicio será capaz de iniciarse, pero no realizará nada. Ahora debemos dotarlo de funcionalidad, y para ello vamos a crear un temporizador que se encargue de realizar una tarea cada X tiempo (por defecto una hora). Éste lo crearemos como un miembro dentro de nuestra clase:

public partial class IECacheQueryService : ServiceBase
{
    private Timer clock = new Timer();

Y lo usaremos desde el constructor de la misma, así como en los eventos OnStart y OnStop. Observar que en el constructor lo inicializamos con un valor que proviene del fichero de configuración del proyecto (propiedades del proyecto/settings) llamado TimerInterval y se ha establecido a un valor de 3.600.000 (1 hora en milisegundos).

public IECacheQueryService()
{
    InitializeComponent();
 
    clock = new Timer(Properties.Settings.Default.TimerInterval);
    clock.Elapsed += new ElapsedEventHandler(clock_Elapsed);
    clock.Enabled = true;
    //...
}
 
 
protected override void OnStart(string[] args)
{           
    ExecuteQuery();
    clock.Start();
    //...
}
 
protected override void OnStop()
{
    clock.Stop();
}

Del mismo modo también especificamos el manejador de evento asociado que se ejecutará cada vez que se cumpla este intervalo de tiempo (clock_Elapsed). Éste será el corazón de nuestro servicio y será el encargado de invocar la consulta a la caché de IE:

void clock_Elapsed(object sender, ElapsedEventArgs e)
    {
        try
        {
            ExecuteQuery();
        }
        catch (Exception ex)
        {
            appEventLog.WriteEntry("Exception: " + ex.Message,
                EventLogEntryType.Error);
        }
    }

Simple verdad? Ahora vamos a construir este método ExecuteQuery a apartir de las piezas que vimos en anteriores entradas de la misma serie. No os preocupeis que en el último post estará un enlace al código completo del ejemplo (incluido el instalable).

Que hace exactamente este método?

  • Primero de todo crea un objeto de tipo StopWatch para medir con precisión el tiempo que transcurre en la ejecución del mismo.
  • Llama al método getResults que se encarga de efectuar la consulta y devolver un objeto que es una lista genérica de entradas de la caché.
  • Construye el nombre de fichero en el que guardaremos los resultados y llama al método saveResults, encargado de realizar la suplantación de identidad y serializar los resultados en el fichero antes mencionado.
private void ExecuteQuery()
{
    try
    {
        Stopwatch watch = new Stopwatch();
        watch.Start();
        List<IECacheEntry> results = getResults(
            Properties.Settings.Default.SearchPattern);
        string filename = string.Format("{0}{1}_{2}.xml",
            Properties.Settings.Default.TargetPathLocation,
            Environment.MachineName,
            DateTime.Now.ToString("ddMMyyyy_hhmm"));
        watch.Stop();
        TimeSpan ts = watch.Elapsed;
        saveResults(results, filename);
        appEventLog.WriteEntry(string.Format(
            "Query executed successfully at {0} in '{1}' by user '{2}'. Elapsed time (ms): {3}",
            DateTime.Now.ToString(), Environment.MachineName,
            WindowsIdentity.GetCurrent().Name,ts.Milliseconds));
    }
    catch (Exception ex)
    {
        appEventLog.WriteEntry("Exception: " + ex.Message,
            EventLogEntryType.Error);
    }
}

Está el servicio terminado? Bueno, si asumimos que el código está completo y funciona sin errores, sí, lo está :-P

Y ahora cómo lo probamos? Pues... bueno, para probarlo antes tenemos que instalarlo.

Agregando los elementos necesarios para instalar el servicio:

No he encontrado demasiada documentación al respecto, de modo que intentaré mostrar los pasos a seguir mediante capturas de pantalla.

Vamos a agregar un elemento que nos permita distribuir el servicio:

AddInstallerClass

Le agregaremos dos componentes serviceProcessInstaller y serviceInstaller (es posible que no aparezcan en la barra de herramientas, así que tendremos que agregarlos mediante la opción "Choose Items..."

InstallerComponents

A continuación los configuraremos del siguiente modo:

Control Propiedad Valor
serviceProcessInstaller1 Account LocalSystem (*)
serviceProcessInstaller1 Parent Installer1
serviceInstaller1 Description Internet Explorer Query Cache
serviceInstaller1 Display Name Internet Explorer Query Cache
serviceInstaller1 Parent Installer1
serviceInstaller1 ServiceName IEQueryCache
serviceInstaller1 StartType Automatic

(*) Habitualmente se utilizará siempre la cuenta con menos nivel de privilegios (LocalService), pero en nuestro caso necesitamos acceder a la caché de IE, de modo que es posible que incluso tengamos que configurar la cuenta de un usuario de windows con suficientes permisos.

Cruzamos los dedos, compilamos el proyecto y vamos a agegar un proyecto de instalación a la solución.

Creando el proyecto de instalación:

Agregaremos un proyecto de tipo Setup and deployment, que será el encargado de instalar nuestro servicio en las estaciones Windows que deseamos monitorizar.

CreateSetupProject

Agregamos la salida del proyecto anterior al nuevo proyecto de instalación:

AddProjectOutput

AddProjectOutputDialog

Ahora mostraremos la ventana de "custom actions" para agregar como acción al instalador la salida de nuestro proyecto de servicio de Windows.

AddCustomAction

AddCustomActionDialog

Una vez realizado esto ya podemos compilar el proyecto de instalación e instalarlo en las estaciones cliente. Si quereis instalarlo en vuestra estación para probarlo y configurarlo adecuadamente, la opción más sencilla es seleccionar la opción Install del menú contextual del proyecto de instalación, en el explorador de proyectos.

Setup

Una vez instalado, aparecerá en el administrador de servicios, para que podamos configurarlo del modo deseado. En este caso particular, si deseamos monitorizar la caché de un usuario en particular, deberemos usar las credenciales de éste usuario, ya que si no el S.O. no será capaz de montar el fichero Index.dat correspondiente a la caché de Internet Explorer.

AdminServices

Bueno, hasta aquí ha llegado este ejemplo. En el próximo post haremos un resumen de lo que se ha visto hasta ahora y publicaré un enlace con el código completo del proyecto para que sirva de ejemplo (o de mal ejemplo :-P).

Saludos desde andorra,

Published 30/5/2008 17:22 por Lluis Franco
Comparte este post:

Comentarios

# re: Acceder a la caché de Internet Explorer (IV)

Wednesday, June 18, 2008 9:15 PM por jimmy

Amigo!, gracias por este tuto, la verdad esta bastante práctico y UTIL!!!! saludos desde Cd. Obregón, Son. México!, te haz sacado un 10! :D