如何从Windowsregistry中读取值

给定一些registry值的关键(例如HKEY_LOCAL_MACHINE \ blah \ blah \ blah \ foo)我怎么能:

  1. 安全地确定这样的密钥存在。
  2. 以编程方式(即用代码)得到它的价值。

我绝对不打算把任何东西写回registry(在我的职业生涯期间,如果我可以帮助它的话)。 所以我们可以跳过关于我身体中每个分子以光速爆炸的讲座,如果我不正确地写入registry。

更喜欢C ++中的答案,但大多只需要知道什么特殊的Windows API咒语得到的价值是。

这里是一些伪代码来检索以下内容:

  1. 如果registry项存在
  2. 该registry项的默认值是什么
  3. 什么是string值
  4. 什么是DWORD值

示例代码:

包含库依赖项: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; } 
 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 

这对RegOpenKey和RegQueryKeyEx将做的伎俩。

如果使用MFC, CRegKey类更容易解决。

的RegQueryValueEx

如果该值存在,则给出该值,如果该密钥不存在则返回错误码ERROR_FILE_NOT_FOUND。

(我不知道我的链接是否工作,但如果你只是谷歌的“RegQueryValueEx”第一个命中是MSDN文件。)

  #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; }