viernes, abril 18, 2008

Usar el Registro de Windows con java JNIRegistry

De nuevo vuelvo a escribir para intentar plasmar un poquito mas de conocimiento adquirido con este tema del uso del registro de windows, pero esta vez utilizando una librería externa de java creada por el grupo ICE Engineering que elimina la limitación de solo poder usar el registro de windows a partir de la clave (nodo) ../java/prefs/ que nos impone el uso de la clase Preferences de java, de la cual ya escribir explicándola un poco.

Antes de empezar a explicar un poco como hacer todo esto y poner un ejemplo auto explicativo, debo decir que esta librería externa que usamos para poder usar el registro de windows, realiza su cometido haciendo uso del JNI (Java Native Inferface) que no es más que este grupo, para poder implementar esto, se creo una librería en C que haciendo uso de la API que windows proporciona para usar el registro de windows, nos ofrece unas clases para poder hacer todo el trabajo.

Para poder usar este código fuente, debemos añadir la librería a nuestro proyecto ( registry.jar) y además poner la DLL donde este el proyecto para que podamos ejecutar el ejemplo.

Organización de la librería JNIregistry .

Esta librería nos proporciona varias clases, pero las más básicas son:

Registry, RegistryKey y RegistryValue.

Registry: Es la clase nos proporciona los mecanismos para poder inicializar/usar/abrir un árbol de claves (nodos) , osea lo primero para poder usar las demás cosas.

RegistryKey: Esta clase es la que usamos para trabajar con las claves que necesitamos, paa usar un objeto de esta clase, debemos inicializarlo/crearlo mendiante la clase Registry.

RegistryValue:Esta clase es la que representa un registro, osea donde se contienen los datos a los que queremos acceder.

La clase RegistryValue representa un registro en el registro de windows, pero tened en cuenta que representa un registro genérico, osea, puede cargar/crear un registro de cualquier tipo (DWORD, binario, string, etc...) así que cuando vayamos a sacar valores o introducirlos debemos dárselos como un vector de bytes. Sino queremos estar pendientes de estar haciendo conversiones de tipos y tenemos muy claro con que tipo de registro estamos trabajando, podemos usar las clases específicas para manejar cada tipo de registro, las cuales nos proporcionan mecanismos más cómodos para trabajar con los registros de windows. Estas clases las podemos ver en la documentación.

Dicho todo lo anterior, ya solo me queda poner el código de ejemplo, el cual nos da una visión de como usar la clase de forma genérica. Sólo una aclaración, este ejemplo usa una clave que yo usaba la "Software\\Atlas\\egEasy\\egOffice\\miclave" es una ruta que tengo yo en mi ordenador y "miclave" es una clave que me cree con el regedit de windows para hacer las pruebas de solo lectura, si quieren esto lo podéis cambiar o crearos ustedes mismo el árbol de claves que deseen.

Código del ejemplo:
import com.ice.jni.registry.Registry;
import com.ice.jni.registry.RegistryException;
import com.ice.jni.registry.RegistryKey;
import com.ice.jni.registry.RegistryValue;

/**
*
* @author nmelian
*/
public class Main {

/*
* El archivo DLL de este jar, hay que meterlo en la carpeta del proyecto
* en la raiz solamente. a no se que se configure el java.lib, para que vaya
* a la ruta que tu quieras a buscar la DLL
*/
public static void main(String[] args)
{
/*
* En este punto nos creamos un objeto que representa una Clave (nodo)
* y con openSubkey le asignamos la ruta de la clave que queremos usar
* y el arbol que vayamos a usar (el del user o el de la maquina local)
* */
RegistryKey regkey = Registry.HKEY_CURRENT_USER;
RegistryKey Clave =Registry.openSubkey(regkey,"Software\\Atlas\\egEasy\\egOffice\\miclave",RegistryKey.ACCESS_ALL);

try
{
/*Aqui nos creamos un objeto que representa un Registro y le asignamos
* el registro que queremos sacado de la clve que nos creamos antes.
* */
RegistryValue Registro = Clave.getValue("mivalor");

/* Con el registro que acabamos de obtener, podemos acceder a distivos
* atributos, como el nombre del atributo (que debe ser el mismo que
* utilizamos en Clave.getValue("mivalor"); cuadno creamos el objeto registro
* El nombre con su ruta absoluta con getFullName() y el tipo de registro
* que es, con getType() Por ultimo para acceder al valor que contiene el
* registro debemos utilizar la Clave y decirle que nos de la ristra que
* representa el contenido del registro que le pasamos. Ojo, esta forma de
* acceder a los datos del registro, es unsando la clase RegistryValue, que
* la mas generica para que no importe que tipo de registro estamos accediendo,
* ya que si es un tipo binario, un tipo DWORD, etc... deberíamos acceder a los
* datos con Registro.getByteData() y luego transformarlos al tipo de dato que
* nosotros esperemos.
* */
System.out.print(
"\nName :" +
Registro.getName() +
"\nKey :" +
Registro.getKey().getFullName() +
"\nType :" +
Registro.getType() +
"\nContenido :" +
Clave.getStringValue(Registro.getName())
);

/* Para asignarle un valor a un regitro para guardarlo en la clave, debemos
* primero asignarle el valor al registro, con Registro.setByteData();
* el valor que vayamos a asignarle debemos pasarselo vomo un vector de bytes,
* despues debemos asignar ese registro a la clave donde estemos trabajando,
* con Clave.setValue( Registro);
*
* */
String contenido = "12.18.1.1";
Registro.setByteData(contenido.getBytes());
Clave.setValue( Registro);
System.out.print(
"\n///--------" +
"\nName :" +
Registro.getName() +
"\nKey :" +
Registro.getKey().getFullName() +
"\nType :" +
Registro.getType() +
"\nContenido :" +
Clave.getStringValue(Registro.getName())
);

}
catch(RegistryException ex)
{
ex.printStackTrace();
}
}

}

2 comentarios:

Unknown dijo...

Hola, gracias por el código!
Yo tengo un problema, y es que cuando hago openSubkey y le paso la cadena del tipo UBICACION\\etc\\etc
me devuelve un nullPointerException... He probado varias combinaciones y no consigo nada. A qué puede ser debido? Es necesario estar como administrador para acceder a estos datos aunque mediante regedit los puedas visualizar??

Muchas gracias!

Anónimo dijo...

Hola muchas gracias por la explicacion.... Pero tengo una pregunta, como hago para crear claves y valores a un Nodo desde Java. He buscado documentacion acerca de esto pero la verdad es muy poca. Te agradeceria mucho si me pudieses explicar eso. Aunque el post es demasiiiado viejo jejeje