2008-08-29 14 views
63

biorąc pod uwagę klucz dla niektórych wartości rejestru (np HKEY_LOCAL_MACHINE \ blah \ blah \ blah \ foo) jak mogę:Jak odczytać wartość z rejestru Windows

  1. Bezpiecznie ustalenia, że ​​taki klucz istnieje.
  2. Programowo (tj. Z kodem) otrzymują jego wartość.

Nie mam absolutnie żadnego zamiaru pisać niczego z powrotem do rejestru (na czas mojej kariery, jeśli mogę pomóc). Możemy więc pominąć wykład na temat każdej cząsteczki w moim ciele eksplodującej z prędkością światła, jeśli piszę do rejestru nieprawidłowo.

Preferuj odpowiedzi w C++, ale przede wszystkim musisz tylko wiedzieć, jaka jest specjalna inkantacja Windows API, aby uzyskać wartość.

Odpowiedz

49

Oto niektóre pseudo-kod aby pobrać następujące:

  1. Jeśli klucz rejestru istnieje
  2. Co Domyślną wartością jest dla tego klucza rejestru
  3. Co wartość łańcuchową jest
  4. Co to jest wartość DWORD

Przykładowy kod:

Dołącz zależność Biblioteka: 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

Jeśli z jakiegoś niewytłumaczalnego powodu nigdy nie znajdzie klucza, może to być problem 32-bitowy/64-bitowy. Zobacz http://stackoverflow.com/q/15084380/482758 – mkjeldsen

+1

Warto wspomnieć, że twój kod jest przeznaczony do użycia z tym, co Windows wywołuje zestaw znaków Unicode. Chciałbym zmienić wywołania funkcji "RegOpenKeyExW" i "RegQueryValueExW" na ich "zestaw znaków" agnostyczny odpowiednik "RegOpenKeyEx" i "RegQueryValueEx" – HaMster

+0

Unicode jest domyślne, to się nie powiedzie, jeśli ktoś jednoznacznie zmieni projekt na wielobajtowy, który nie ma powód, aby zrobić – paulm

4

RegQueryValueEx

Daje to wartość, jeśli istnieje, i zwraca kod ERROR_FILE_NOT_FOUND błędzie, jeśli klucz nie istnieje.

(nie mogę powiedzieć, czy mój związek działa, czy nie, ale jeśli po prostu google „RegQueryValueEx” pierwszym hitem jest w dokumentacji 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? Co to jest użycie konstruktora CRegKey bez argumentów? Nie ma potrzeby reprezentowania niezainicjowanego klucza rejestru. Oto, do czego służy: opcjonalne. –

+0

Jaką bibliotekę należy dołączyć? –

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; 
    } 
Powiązane problemy