Compartir a través de


Explorando la API de Windows en C++: La función RegDeleteKeyEx para eliminar claves de Registro (es-ES)

RegDeleteKeyEx

Esta es realmente una función muy sencilla de utilizar, pero por supuesto demasiado útil, pues se encarga de eliminar una sub-clave especificada, pero a la vez todos los valores que se hayan creado.

Nota: Es de vital importancia saber que esta función sólo eliminará una sub-clave especificada y todos sus valores, pero si existe otra sub-clave habrá acceso denegado, pues para borrar todo un árbol, es necesario hacer uso de la función RegDeleteTree que describiré en otro artículo.

La declaración que presenta la documentación oficial es la siguiente:

HKEY hKey: Como siempre, es un tipo de apuntador a alguna clave que se encuentre abierta, ese apuntador lo debe retornar RegOpenKeyEx, RegCreateKeyEx, o utilizar algunas de las claves que se encuentran predefinidas en Windows:

**HKEY_CLASSES_ROOT
**

**HKEY_CURRENT_CONFIG
**

**HKEY_CURRENT_USER
**

**HKEY_LOCAL_MACHINE
**

HKEY_USERS

LPCTSTR lpSubKey: Corresponde al nombre de la sub-clave que se va a eliminar. Esta variable no puede recibir ningún tipo de declaración NULL, y naturalmente debe referirse a alguna sub-clave de la clave especificada en hKey previamente.

REGSAM samDesired: A diferencia de las declaraciones para esta variable en otras funciones, aquí se debe especificar la vista específica de la plataforma del Registro. En otras palabras, se debe decir si se va a eliminar un registro bajo la vista de 32 bits o de 64 bits. Aquí es donde juega mucho WOW64. Las dos alternativas son:

KEY_WOW64_32KEY y KEY_WOW64_64KEY.

DWORD Reserved: Como siempre, valor reservado y con un contenido de cero (0).

Si todo sale bien, el código de error que retorne debería ser cero (0), que corresponde a ERROR_SUCCESS.

Ejemplo práctico

Para poder ver esto un poco más allá de la simple documentación, y además para que cobre valor la función de RegOpenKeyEx visto en otro artículo de Wiki, pondremos como caso de uso una sub-clave de registro llamada DemoKey\Key, que pertenece a la clave de HKEY_CURRENT_USER. Básicamente, si la sub-clave existe y se puede abrir (Comprobándolo con RegOpenKeyEx), se procederá a eliminar, de lo contrario, se indicará un mensaje de error sencillo. La ruta completa de la sub-clave sería:
HKEY_CURRENT_USER\DemoKey\Key

Antes que nada, como siempre habría que crear el Proyecto de Win32 vacío, agregar el .cpp del código fuente y declarar el encabezado y función principal:

#include <Windows.h>
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
 
} //Fin del método principal

Después de esto, declarar las variables correspondientes a las dos funciones:

long R2;
    //Declaración para las dos funciones
    HKEY hKey = HKEY_CURRENT_USER;
    LPCTSTR lpSubKey = L"DemoKey\\Key";
 
    //Declaración de variables para RegOpenKeyEx
    DWORD ulOptions = 0;
    REGSAM samDesired = KEY_READ | KEY_WRITE;
    HKEY phkResult;
     
    //Declaración de variables para RegDeleteKeyEx
     
    REGSAM samDesired2 = KEY_WOW64_32KEY;
    DWORD Rererved = 0;

Nota: Como ambas funciones tienen samDesired, pero reciben declaraciones diferentes, nombré samDesired2 para la función RegDeleteKeyEx.

Primero hay que pasar a ver si se puede abrir la clave para trabajar con ella, por supuesto, hará una búsqueda previamente. Para esto, llamamos a la función RegOpenKeyEx, y le mandamos todos los valores que pide y que ya están declarados almacenando el valor que de vuelve en una variable long llamada R1:

long R1= RegOpenKeyEx(hKey, lpSubKey, ulOptions, samDesired, &phkResult);

*Nota: En la variable phkResult, se usa antes el sigo de & para indicar que apunte a la dirección de memoria donde reside.

Ahora, de acuerdo al resultado de la operación RegOpenKeyEx, procederemos con un switch a tomar la decisión adecuada. Si recibimos un código de completado, es decir ERROR_SUCCESS (0), llamaremos a la función RegDeleteKeyEx con las variables ya inicializadas y validaremos que esta operación también se complete sin ningún problema, de lo contrario, indicaremos hasta dónde llegó.

El código entonces quedaría así, incluyendo las respectivas explicaciones:

switch (R1) //Inicia el switch con el resultado de R1 (RegOpenKeyEx)
    {
    case ERROR_SUCCESS: //Si la sub-clave se abre.
 
        //Se llama a la función RegDeleteKeyEx para eliminar la sub-clave
        R2 = RegDeleteKeyEx(hKey, lpSubKey, samDesired2, Reserved);
 
        if (R2 == ERROR_SUCCESS) //Si se elimina la sub-clave
        {
            MessageBox(NULL, L"Se abrió y se eliminó la sub-clave.", L"Explorando la API", MB_OK | MB_ICONINFORMATION);
 
        }
        else if  (R2 == ERROR_ACCESS_DENIED) //Si hay acceso denegado al eliminar la sub-clave
        {
            MessageBox(NULL, L"Se abrió la clave, pero hubo acceso denegado al eliminarla.", L"Explorando la API", MB_OK | MB_ICONINFORMATION);
        }
        else //Cualquier otro error no contemplado. 
        {
            MessageBox(NULL, L"Se abrió la clave, pero no se pudo eliminar.", L"Explorando la API", MB_OK | MB_ICONINFORMATION);
        }
             
        break; //Cierra primer case
 
    case ERROR_FILE_NOT_FOUND: //Si no se encuentra la sub-clave
 
        MessageBox(NULL, L"No se encontró la clave.", L"Explorando la API", MB_ICONERROR);
        break; //Cierra segundo case
 
    case ERROR_ACCESS_DENIED: //Si hay acceso denegado al abrir la sub-clave
 
        MessageBox(NULL, L"Acceso denegado", L"Explorando la API", MB_ICONERROR);
        break; //Fin del tercer case
 
    default: //Otro error no contemplado al abrir la sub-clave
 
        MessageBox(NULL, L"Error al abrir la clave", L"Explorando la API", MB_ICONERROR);
        break; //Fin del default
 
    } //Fin del switch

Finalmente, como debe suceder con cualquier operación en el Registro de Windows, es necesario cerrar la sub-clave con la que se haya trabajado utilizando la función RegCloseKey:

//Cerrar la operación en la sub-clave
    RegCloseKey(phkResult);

El mensaje de Windows que indicamos sería similar al siguiente si se completa la operación:

Process Monitor nos mostrará todo de la siguiente forma:

Como ven, abre la clave con la operación RegOpenKey, que internamente llama a RegOpenKeyExW y a RegOpenKeyExInternalW para luego establecer información, abrirla nuevamente para establecer los derechos de acceso como DELETE:

Luego elimina la sub-clave utilizando la operación RegDeleteKey y finalmente la cierra con RegCloseKey. Internamente estas dos también llaman en la pila de ejecución a ExW e InternalW.

Pueden descargar el ejemplo completo de la solución en Visual Studio desde la siguiente galería:
Ejemplo: Uso de la función RegDeleteKeyEx de la API de Windows en C++

Espero sea de utilidad.

Ver también:
Explorando la API de Windows en C++: La función RegOpenKeyEx para abrir claves de Registro.
Explorando la API de Windows en C++: Creando mi primera clave de Registro con la función RegCreateKeyEx (es-ES).
Explorando la API de Windows en C++: Mi primera Valor de Registro utilizando las funciones RegCreateKeyEx y RegSetValueEx (es-ES)