2008-08-29 25 views
63

Với chìa khóa cho một số giá trị registry (ví dụ HKEY_LOCAL_MACHINE \ blah \ blah \ blah \ foo) làm thế nào tôi có thể:Làm thế nào để đọc một giá trị từ Windows registry

  1. an toàn xác định rằng một chìa khóa như vậy tồn tại.
  2. Lập trình (tức là với mã) nhận được giá trị của nó.

Tôi hoàn toàn không có ý định viết bất kỳ thứ gì vào sổ đăng ký (trong suốt thời gian tôi làm việc nếu tôi có thể trợ giúp). Vì vậy, chúng ta có thể bỏ qua bài giảng về mọi phân tử trong cơ thể của tôi đang bùng nổ ở tốc độ ánh sáng nếu tôi viết vào sổ đăng ký không chính xác.

Ưu tiên câu trả lời trong C++, nhưng chủ yếu chỉ cần biết câu lệnh Windows API đặc biệt để nhận được giá trị là gì.

Trả lời

49

Dưới đây là một số mã giả để lấy như sau:

  1. Nếu một khóa registry tồn tại
  2. gì giá trị mặc định là dành cho registry key
  3. Thật là một chuỗi giá trị là
  4. Giá trị DWORD là gì
đang

Ví dụ:

Bao gồm các phụ thuộc thư viện: 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

Nếu vì một số lý do không giải thích được, điều này dường như không bao giờ tìm thấy khóa, đó có thể là vấn đề 32 bit/64 bit. Xem http://stackoverflow.com/q/15084380/482758 – mkjeldsen

+1

Nó có thể được giúp đỡ để đề cập đến rằng mã của bạn được thiết kế để được sử dụng với những gì Windows gọi một bộ ký tự Unicode. Tôi sẽ thay đổi các chức năng gọi là 'RegOpenKeyExW' và 'RegQueryValueExW' thành" ký tự "tương đương với số nguyên" RegOpenKeyEx' và 'RegQueryValueEx' – HaMster

+0

Unicode mặc định, nó sẽ chỉ thất bại nếu một số thay đổi rõ ràng dự án thành nhiều byte mà không có Lý do để làm – paulm

4

RegQueryValueEx

này cung cấp cho các giá trị nếu nó tồn tại, và trả về một mã ERROR_FILE_NOT_FOUND lỗi nếu chìa khóa không tồn tại.

(Tôi không thể nói nếu liên kết của tôi đang làm việc hay không, nhưng nếu bạn chỉ cần google cho "RegQueryValueEx" hit đầu tiên là tài liệu 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? Việc sử dụng các hàm tạo CRegKey mà không có một đối số là gì? Không cần phải đại diện cho một khóa registry chưa được khởi tạo. Đây là những gì tăng :: tùy chọn là cho. –

+0

Bạn cần bao gồm thư viện nào? –

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; 
    } 
Các vấn đề liên quan