Omar del Valle Rodríguez

January 2010 - Artículos

4 horas de trabajo

4 horas de trabajo me costó leer un registro de Windows desde una aplicación.

Esta vez voy a dejar la Web, y me voy a Windows Form, pero en particular, trataré un hecho que me ocurrió hace unos días y que me costó mucho rato resolver. Actualmente me encuentro desarrollando un Smartclient. Algunos valores de configuración, la aplicación los lee del registro de Windows. El instalador de dicho Smartclient ya tiene toda la lógica pensada, pero aún no está realizado.

Durante el momento de la instalación, y dependiendo de determinados procesos, se crearán los registros con los valores que necesita posteriormente la aplicación para su correcto funcionamiento. Como el instalador aún no está, usé el “regedit” para crear los registros a mano y que el desarrollo no se detuviera. Aquí empezaron los problemas….

Voy a re-crear la situación por la que pasé en una aplicación de ejemplo, la configuración del entorno de desarrollo fue Windows 7 64 bits y Visual Studio 2008, aunque el ejemplo lo haré ahora con Visual Studio 2010.

Mi aplicación de consola:

class Program
{
  
public static long Prueba
   {
     
get
     
{
       
var masterKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Prueba");
        
if (masterKey == null) throw new ApplicationException("No existe el registro");

        return
Convert.ToInt64(masterKey.GetValue("Prueba"));
      }
   }

  
static void Main(string[] args)
   {
     
Console.WriteLine("Valor del registro: {0}", Prueba);
      
Console.ReadLine();
   }
}

 

Esta aplicación simplemente tiene una propiedad Prueba que busca un valor en el HKEY_LOCAL_MACHINE\SOFWARE\Prueba y retorna su valor como un entero de 64 bits. Para probar mi aplicación, voy al registro de Windows y creo manualmente lo que estoy necesitando.

 



Al ejecutar mi código se genera el ApplicationException que en mi código informa que el registro no existe.



Algo pasa aquí, el código es tan sencillo que me hace dudar de un posible error, de todas maneras me voy al MSDN y busco la documentación. Según MSDN, Registry.OpenSubKey, cito textualmente, “Contiene los datos de configuración correspondientes al equipo local. Este campo lee la clave base HKEY_LOCAL_MACHINE del Registro de Windows”. Por ahí todo estaba bien. Este campo retorna un objeto del tipo RegistryKey, del cual MSDN nos dice que “representa un nodo de nivel de clave en el Registro de Windows.”

Todo parece correcto pero mi código sigue sin funcionar. Así que después de darle vueltas y vueltas a todo esto, decidí cambiar el método OpenSubKey, por CreateSubKey.

 var masterKey = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Prueba");
 

Ahora sí que pasó, claro, mi código si por alguna razón la clave no existía, la creó y por eso funcionó todo sin problemas.

Quiero ver que todo es como lo imagino, así que elimino el registro Prueba y ejecuto nuevamente la aplicación. En este punto, vuelve a pasar sin problemas, supongo que el registro fue creando nuevamente. La sorpresa llegó cuando por más que buscaba el registro en HKEY_LOCAL_MACHINE\SOFWARE\Prueba este no aparecía. Decido realizar una búsqueda dentro del Regedit, y aparece mi registro Prueba.

Observen lo que está pasando, yo estoy desde mi aplicación creando un registro para HKEY_LOCAL_MACHINE\SOFWARE\Prueba
y el registro se crea en HKEY_LOCAL_MACHINE\SOFWARE\Wow6432Node\Prueba

En ese momento supe lo que pasaba. Mi aplicación interactúa con un Hardware cuyo driver solo funciona para 32 bits. Esto nos obligó a cambiar en el Build de la aplicación a una plataforma x86. Pues bien, si nuestra aplicación está compilada solo para trabajar con 32 bits y operamos registros de Windows sobre 64 bits, Windows 7 crea una ruta distinta a la que trazamos en nuestro código.

Si desde nuestra aplicación creamos y leemos los registros, no tendríamos problema, porque esta ruta ficticia es transparente para el Framework. El peligro, y por lo que me decidí a escribir el artículo, es porque en muchos casos los registros se crean desde instaladores, y podemos encontrarnos que lo que esperábamos que existiese porque el instalador supuestamente ha hecho su trabajo, no existe.

Nota: No quería terminar sin agradecer a Javier Conesa, miembro del grupo de usuarios SecondNug, por ayudarme a capturar las pantallas en Windows 7 64 bits. :P 

Salu2