2008-08-29 13 views
63

Dada la clave para un cierto valor de registro (por ejemplo, HKEY_LOCAL_MACHINE \ bla \ bla \ bla \ foo) ¿Cómo puedo:Cómo leer un valor del registro de Windows

  1. determinar con seguridad que existe dicha clave.
  2. Programáticamente (es decir, con código) obtiene su valor.

No tengo ninguna intención de escribir nada en el registro (durante mi carrera si puedo evitarlo). Así que podemos omitir la conferencia sobre cada molécula de mi cuerpo explotando a la velocidad de la luz si escribo incorrectamente en el registro.

Prefiera las respuestas en C++, pero sobre todo solo necesita saber cuál es el encantamiento especial de API de Windows para obtener el valor.

Respuesta

49

Aquí es un poco de pseudo-código para recuperar el siguiente:

  1. Si existe una clave del Registro
  2. Lo que el valor predeterminado es para que la clave de registro
  3. Qué valor de cadena es
  4. Qué valor DWORD es
código

Ejemplo:

Incluir la dependencia de biblioteca: Advapi32.lib

HKEY hKey; 
LONG lRes = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Perl", 0, KEY_READ, &hKey); 
bool bExistsAndSuccess (lRes == ERROR_SUCCESS); 
bool bDoesNotExistsSpecifically (lRes == ERROR_FILE_NOT_FOUND); 
std::wstring strValueOfBinDir; 
std::wstring strKeyDefaultValue; 
GetStringRegKey(hKey, L"BinDir", strValueOfBinDir, L"bad"); 
GetStringRegKey(hKey, L"", strKeyDefaultValue, L"bad"); 

LONG GetDWORDRegKey(HKEY hKey, const std::wstring &strValueName, DWORD &nValue, DWORD nDefaultValue) 
{ 
    nValue = nDefaultValue; 
    DWORD dwBufferSize(sizeof(DWORD)); 
    DWORD nResult(0); 
    LONG nError = ::RegQueryValueExW(hKey, 
     strValueName.c_str(), 
     0, 
     NULL, 
     reinterpret_cast<LPBYTE>(&nResult), 
     &dwBufferSize); 
    if (ERROR_SUCCESS == nError) 
    { 
     nValue = nResult; 
    } 
    return nError; 
} 


LONG GetBoolRegKey(HKEY hKey, const std::wstring &strValueName, bool &bValue, bool bDefaultValue) 
{ 
    DWORD nDefValue((bDefaultValue) ? 1 : 0); 
    DWORD nResult(nDefValue); 
    LONG nError = GetDWORDRegKey(hKey, strValueName.c_str(), nResult, nDefValue); 
    if (ERROR_SUCCESS == nError) 
    { 
     bValue = (nResult != 0) ? true : false; 
    } 
    return nError; 
} 


LONG GetStringRegKey(HKEY hKey, const std::wstring &strValueName, std::wstring &strValue, const std::wstring &strDefaultValue) 
{ 
    strValue = strDefaultValue; 
    WCHAR szBuffer[512]; 
    DWORD dwBufferSize = sizeof(szBuffer); 
    ULONG nError; 
    nError = RegQueryValueExW(hKey, strValueName.c_str(), 0, NULL, (LPBYTE)szBuffer, &dwBufferSize); 
    if (ERROR_SUCCESS == nError) 
    { 
     strValue = szBuffer; 
    } 
    return nError; 
} 
+6

Si por alguna razón inexplicable, parece que nunca encuentra una clave, puede tratarse de un problema de 32 bits/64 bits. Consulte http://stackoverflow.com/q/15084380/482758 – mkjeldsen

+1

. Puede ser útil mencionar que su código está destinado a ser utilizado con lo que Windows llama un conjunto de caracteres Unicode. Cambiaría las llamadas de función 'RegOpenKeyExW' y' RegQueryValueExW' a su "equivalente de conjunto de caracteres" equivalente agnóstico 'RegOpenKeyEx' y' RegQueryValueEx' – HaMster

+0

Unicode es predeterminado, solo fallará si alguien cambia explícitamente proyecto a byte múltiple que no existe razón para hacer – paulm

4

RegQueryValueEx

Esto da el valor si es que existe, y devuelve un código de error si ERROR_FILE_NOT_FOUND no existe la clave.

(no puedo decir si mi enlace está funcionando o no, pero si sólo Google para "RegQueryValueEx" el primer golpe es la documentación de MSDN.)

9
const CString REG_SW_GROUP_I_WANT = _T("SOFTWARE\\My Corporation\\My Package\\Group I want"); 
const CString REG_KEY_I_WANT= _T("Key Name"); 

CRegKey regKey; 
DWORD dwValue = 0; 

if(ERROR_SUCCESS != regKey.Open(HKEY_LOCAL_MACHINE, REG_SW_GROUP_I_WANT)) 
{ 
    m_pobLogger->LogError(_T("CRegKey::Open failed in Method")); 
    regKey.Close(); 
    goto Function_Exit; 
} 
if(ERROR_SUCCESS != regKey.QueryValue(dwValue, REG_KEY_I_WANT)) 
{ 
    m_pobLogger->LogError(_T("CRegKey::QueryValue Failed in Method")); 
    regKey.Close(); 
    goto Function_Exit; 
} 

// dwValue has the stuff now - use for further processing 
+0

Goto? ¿Cuál es el uso del constructor CRegKey sin un argumento? No es necesario representar una clave de registro no inicializada. Esto es para lo que boost :: optional es para. –

+0

¿Qué biblioteca necesita incluir? –

0
#include <windows.h> 
    #include <map> 
    #include <string> 
    #include <stdio.h> 
    #include <string.h> 
    #include <tr1/stdint.h> 
    using namespace std; 
    void printerr(DWORD dwerror) { 
     LPVOID lpMsgBuf; 
     FormatMessage(
      FORMAT_MESSAGE_ALLOCATE_BUFFER | 
      FORMAT_MESSAGE_FROM_SYSTEM | 
      FORMAT_MESSAGE_IGNORE_INSERTS, 
      NULL, 
      dwerror, 
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language 
      (LPTSTR) &lpMsgBuf, 
      0, 
      NULL 
     ); 
     // Process any inserts in lpMsgBuf. 
     // ... 
     // Display the string. 
     if (isOut) { 
      fprintf(fout, "%s\n", lpMsgBuf); 
     } else { 
      printf("%s\n", lpMsgBuf); 
     } 
     // Free the buffer. 
     LocalFree(lpMsgBuf); 
    } 



    bool regreadSZ(string& hkey, string& subkey, string& value, string& returnvalue, string& regValueType) { 
     char s[128000]; 
     map<string,HKEY> keys; 
     keys["HKEY_CLASSES_ROOT"]=HKEY_CLASSES_ROOT; 
     keys["HKEY_CURRENT_CONFIG"]=HKEY_CURRENT_CONFIG; //DID NOT SURVIVE? 
     keys["HKEY_CURRENT_USER"]=HKEY_CURRENT_USER; 
     keys["HKEY_LOCAL_MACHINE"]=HKEY_LOCAL_MACHINE; 
     keys["HKEY_USERS"]=HKEY_USERS; 
     HKEY mykey; 

     map<string,DWORD> valuetypes; 
     valuetypes["REG_SZ"]=REG_SZ; 
     valuetypes["REG_EXPAND_SZ"]=REG_EXPAND_SZ; 
     valuetypes["REG_MULTI_SZ"]=REG_MULTI_SZ; //probably can't use this. 

     LONG retval=RegOpenKeyEx(
      keys[hkey],   // handle to open key 
      subkey.c_str(), // subkey name 
      0, // reserved 
      KEY_READ, // security access mask 
      &mykey // handle to open key 
     ); 
     if (ERROR_SUCCESS != retval) {printerr(retval); return false;} 
     DWORD slen=128000; 
     DWORD valuetype = valuetypes[regValueType]; 
     retval=RegQueryValueEx(
      mykey,   // handle to key 
      value.c_str(), // value name 
      NULL, // reserved 
      (LPDWORD) &valuetype,  // type buffer 
      (LPBYTE)s,  // data buffer 
      (LPDWORD) &slen  // size of data buffer 
     ); 
     switch(retval) { 
      case ERROR_SUCCESS: 
       //if (isOut) { 
       // fprintf(fout,"RegQueryValueEx():ERROR_SUCCESS:succeeded.\n"); 
       //} else { 
       // printf("RegQueryValueEx():ERROR_SUCCESS:succeeded.\n"); 
       //} 
       break; 
      case ERROR_MORE_DATA: 
       //what do I do now? data buffer is too small. 
       if (isOut) { 
        fprintf(fout,"RegQueryValueEx():ERROR_MORE_DATA: need bigger buffer.\n"); 
       } else { 
        printf("RegQueryValueEx():ERROR_MORE_DATA: need bigger buffer.\n"); 
       } 
       return false; 
      case ERROR_FILE_NOT_FOUND: 
       if (isOut) { 
        fprintf(fout,"RegQueryValueEx():ERROR_FILE_NOT_FOUND: registry value does not exist.\n"); 
       } else { 
        printf("RegQueryValueEx():ERROR_FILE_NOT_FOUND: registry value does not exist.\n"); 
       } 
       return false; 
      default: 
       if (isOut) { 
        fprintf(fout,"RegQueryValueEx():unknown error type 0x%lx.\n", retval); 
       } else { 
        printf("RegQueryValueEx():unknown error type 0x%lx.\n", retval); 
       } 
       return false; 

     } 
     retval=RegCloseKey(mykey); 
     if (ERROR_SUCCESS != retval) {printerr(retval); return false;} 

     returnvalue = s; 
     return true; 
    } 
Cuestiones relacionadas