উইন্ডোজ রেজিস্ট্রি থেকে কীভাবে কোনও মান পড়তে হয়


91

কিছু রেজিস্ট্রি মানের জন্য কী দেওয়া হয়েছে (যেমন HKEY_LOCAL_MACHINE \ blah \ blah \ blah \ foo) আমি কীভাবে পারি:

  1. নিরাপদে নির্ধারণ করুন যে এই জাতীয় কী বিদ্যমান।
  2. প্রোগ্রামগতভাবে (অর্থাত্ কোড সহ) এর মান পান।

রেজিস্ট্রিতে ফিরে কিছু লেখার আমার সম্পূর্ণ ইচ্ছা নেই (আমার ক্যারিয়ারের সময়কালের জন্য যদি আমি এটি সহায়তা করতে পারি)। সুতরাং আমি যদি ভুলভাবে রেজিস্ট্রি লিখি তবে আলোর গতিতে বিস্ফোরিত হওয়া আমার দেহের প্রতিটি অণু সম্পর্কে বক্তৃতাটি এড়িয়ে যেতে পারি।

সি ++ তে উত্তরগুলি অগ্রাধিকার দিন, তবে বেশিরভাগের জন্য বিশেষ উইন্ডোজ এপিআই অন্তর্ভুক্তির মূল্যটি কী তা পেতে হবে তা জানতে হবে।

উত্তর:


75

নিম্নলিখিতগুলি পুনরুদ্ধার করার জন্য এখানে কয়েকটি সিউডো কোড রয়েছে:

  1. যদি একটি রেজিস্ট্রি কী উপস্থিত থাকে
  2. সেই রেজিস্ট্রি কীটির জন্য ডিফল্ট মান কী
  3. একটি স্ট্রিং মান কি
  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;
}

11
যদি কিছু অনিচ্ছুক কারণে এটির কোনও চাবি খুঁজে না পাওয়া যায় তবে এটি 32-বিট / 64-বিট সমস্যা হতে পারে। দেখুন stackoverflow.com/q/15084380/482758
mkjeldsen

4
আপনার কোডটি উইন্ডোজ কোনও ইউনিকোড অক্ষর সেটকে কল করে তার সাথে ব্যবহার করার উদ্দেশ্যে এটি উল্লেখ করা সহায়ক হতে পারে। আমি ফাংশন কলগুলি RegOpenKeyExWএবং RegQueryValueExWতাদের "চরিত্র সেট" RegOpenKeyExRegQueryValueEx
অজিনস্টিক

ইউনিকোড ডিফল্ট, এটি কেবলমাত্র ব্যর্থ হবে যদি কেউ স্পষ্টভাবে
মাল্ট

8
এটি একটি দেরিতে মন্তব্য, তবে আমি আপনাকে মনে করিয়ে দিতে চাই যে আপনি যখন RegCloseKey কল করে এটি সম্পন্ন করবেন তখন আপনার রেজিস্ট্রি কীটি বন্ধ করা উচিত।
ক্যান

4
এটি সি আইপিআইয়ের মতো দেখায় এবং আমাদের 2016 আছে the

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

4
যাও? যুক্তি ছাড়াই CRegKey নির্মাণকারীর ব্যবহার কী? একটি অনির্বাচিত রেজিস্ট্রি কী উপস্থাপন করার প্রয়োজন নেই। এটিই বুস্ট :: alচ্ছিকের জন্য।

4
আপনার কোন লাইব্রেরি অন্তর্ভুক্ত করা দরকার?
ডোনাল্ড ডাক

CRegKeyএটিএল বা এমএফসি দেশের মতো শোনাচ্ছে।
kayleeFrye_onDeck

6

উইন্ডোজ> = ভিস্তা / সার্ভার ২০০৮ সাল থেকে, RegGetValue উপলভ্য, যা RegQueryValueEx এর চেয়ে নিরাপদ ফাংশন । জন্য কোন প্রয়োজন নেই , বা স্ট্রিং মূল্যবোধের পরিসমাপ্তি চেক ( , , )।RegOpenKeyExRegCloseKeyNULREG_SZREG_MULTI_SZREG_EXPAND_SZ

#include <iostream>
#include <string>
#include <exception>
#include <windows.h>

/*! \brief                          Returns a value from HKLM as string.
    \exception  std::runtime_error  Replace with your error handling.
*/
std::wstring GetStringValueFromHKLM(const std::wstring& regSubKey, const std::wstring& regValue)
{
    size_t bufferSize = 0xFFF; // If too small, will be resized down below.
    std::wstring valueBuf; // Contiguous buffer since C++11.
    valueBuf.resize(bufferSize);
    auto cbData = static_cast<DWORD>(bufferSize * sizeof(wchar_t));
    auto rc = RegGetValueW(
        HKEY_LOCAL_MACHINE,
        regSubKey.c_str(),
        regValue.c_str(),
        RRF_RT_REG_SZ,
        nullptr,
        static_cast<void*>(valueBuf.data()),
        &cbData
    );
    while (rc == ERROR_MORE_DATA)
    {
        // Get a buffer that is big enough.
        cbData /= sizeof(wchar_t);
        if (cbData > static_cast<DWORD>(bufferSize))
        {
            bufferSize = static_cast<size_t>(cbData);
        }
        else
        {
            bufferSize *= 2;
            cbData = static_cast<DWORD>(bufferSize * sizeof(wchar_t));
        }
        valueBuf.resize(bufferSize);
        rc = RegGetValueW(
            HKEY_LOCAL_MACHINE,
            regSubKey.c_str(),
            regValue.c_str(),
            RRF_RT_REG_SZ,
            nullptr,
            static_cast<void*>(valueBuf.data()),
            &cbData
        );
    }
    if (rc == ERROR_SUCCESS)
    {
        cbData /= sizeof(wchar_t);
        valueBuf.resize(static_cast<size_t>(cbData - 1)); // remove end null character
        return valueBuf;
    }
    else
    {
        throw std::runtime_error("Windows system error code: " + std::to_string(rc));
    }
}

int main()
{
    std::wstring regSubKey;
#ifdef _WIN64 // Manually switching between 32bit/64bit for the example. Use dwFlags instead.
    regSubKey = L"SOFTWARE\\WOW6432Node\\Company Name\\Application Name\\";
#else
    regSubKey = L"SOFTWARE\\Company Name\\Application Name\\";
#endif
    std::wstring regValue(L"MyValue");
    std::wstring valueFromRegistry;
    try
    {
        valueFromRegistry = GetStringValueFromHKLM(regSubKey, regValue);
    }
    catch (std::exception& e)
    {
        std::cerr << e.what();
    }
    std::wcout << valueFromRegistry;
}

এর প্যারামিটারটি dwFlagsটাইপ সীমাবদ্ধতার জন্য পতাকাগুলি সমর্থন করে, ব্যর্থতায় শূন্য সহ ভ্যালু বাফারটি পূরণ করে ( RRF_ZEROONFAILURE) এবং bit৪ বিট প্রোগ্রামের জন্য 32/64 বিট রেজিস্ট্রি অ্যাক্সেস ( RRF_SUBKEY_WOW6464KEY, RRF_SUBKEY_WOW6432KEY) সরবরাহ করে।


এই কোডটি দেখে মনে হচ্ছে এটি আমার পক্ষে কাজ করার খুব কাছাকাছি, তবে প্যারামিটারটি সম্পর্কে আমাকে দুটি ত্রুটি দেয় static_cast<void*> (valueBuf.data())। আমি একটি ব্যবহার করতে অক্ষম const_cast, এবং সি-স্টাইলের কাস্ট ব্যবহার করে আমাকে কেবল রানটাইম ত্রুটি জালিয়ে তুলতে কম্পাইলার ত্রুটির আশেপাশে পেয়ে যায়। কোনও পরামর্শ?
স্কেওজো


4

RegQueryValueEx

এটি উপস্থিত থাকলে মান দেয় এবং কী উপস্থিত না থাকলে একটি ত্রুটি কোড ERROR_FILE_NOT_FOUND দেয়।

(আমার লিঙ্কটি কাজ করছে কি না তা আমি বলতে পারি না তবে আপনি যদি কেবল "রেজিকিউরিভ্যালুএক্স" এর জন্য গুগল করেন তবে প্রথম হিটটি এমএসডিএন ডকুমেন্টেশন)


1

সাধারণত রেজিস্টার কী এবং মান প্রোগ্রামে ধ্রুবক হয়। যদি তা হয়, তবে এখানে একটি উদাহরণ কীভাবে ডিডবর্ডার রেজিস্ট্রি মান পড়বেন Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled:

#include <windows.h>

DWORD val;
DWORD dataSize = sizeof(val);
if (ERROR_SUCCESS == RegGetValueA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\FileSystem", "LongPathsEnabled", RRF_RT_DWORD, nullptr /*type not required*/, &val, &dataSize)) {
  printf("Value is %i\n", val);
  // no CloseKey needed because it is a predefined registry key
}
else {
  printf("Error reading.\n");
}

অন্যান্য মান ধরণের জন্য মানিয়ে নিতে, সম্পূর্ণ নির্দিষ্টকরণের জন্য https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-reggetvaluea দেখুন ।


0

এই কনসোল অ্যাপ্লিকেশনটি বেশিরভাগ সম্ভাব্য রেজিস্ট্রি মানগুলির জন্য একটি রেজিস্ট্রি কী থেকে সমস্ত মান এবং তাদের ডেটা তালিকাভুক্ত করবে। এমন কিছু অদ্ভুত জিনিস রয়েছে যা প্রায়শই ব্যবহৃত হয় না। আপনার যদি তাদের সকলের সমর্থন করার প্রয়োজন হয় তবে এই রেজিস্ট্রি মান ধরণের ডকুমেন্টেশন উল্লেখ করার সময় এই উদাহরণ থেকে প্রসারিত করুন ।

এটি কোনও .regফাইল ফর্ম্যাট থেকে আমদানি করতে পারেন এমন রেজিস্ট্রি কী সামগ্রী হতে দিন :

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\added\subkey]
"String_Value"="hello, world!"
"Binary_Value"=hex:01,01,01,01
"Dword value"=dword:00001224
"QWord val"=hex(b):24,22,12,00,00,00,00,00
"multi-line val"=hex(7):4c,00,69,00,6e,00,65,00,20,00,30,00,00,00,4c,00,69,00,\
  6e,00,65,00,20,00,31,00,00,00,4c,00,69,00,6e,00,65,00,20,00,32,00,00,00,00,\
  00
"expanded_val"=hex(2):25,00,55,00,53,00,45,00,52,00,50,00,52,00,4f,00,46,00,49,\
  00,4c,00,45,00,25,00,5c,00,6e,00,65,00,77,00,5f,00,73,00,74,00,75,00,66,00,\
  66,00,00,00

কনসোল অ্যাপ্লিকেশন নিজেই:

#include <Windows.h>
#include <iostream>
#include <string>
#include <locale>
#include <vector>
#include <iomanip>

int wmain()
{
    const auto hKey = HKEY_CURRENT_USER;
    constexpr auto lpSubKey = TEXT("added\\subkey");
    auto openedKey = HKEY();
    auto status = RegOpenKeyEx(hKey, lpSubKey, 0, KEY_READ, &openedKey);

    if (status == ERROR_SUCCESS) {
        auto valueCount = static_cast<DWORD>(0);
        auto maxNameLength = static_cast<DWORD>(0);
        auto maxValueLength = static_cast<DWORD>(0);
        status = RegQueryInfoKey(openedKey, NULL, NULL, NULL, NULL, NULL, NULL,
            &valueCount, &maxNameLength, &maxValueLength, NULL, NULL);

        if (status == ERROR_SUCCESS) {
            DWORD type = 0;
            DWORD index = 0;
            std::vector<wchar_t> valueName = std::vector<wchar_t>(maxNameLength + 1);
            std::vector<BYTE> dataBuffer = std::vector<BYTE>(maxValueLength);

            for (DWORD index = 0; index < valueCount; index++) {
                DWORD charCountValueName = static_cast<DWORD>(valueName.size());
                DWORD charBytesData = static_cast<DWORD>(dataBuffer.size());
                status = RegEnumValue(openedKey, index, valueName.data(), &charCountValueName,
                    NULL, &type, dataBuffer.data(), &charBytesData);

                if (type == REG_SZ) {
                    const auto reg_string = reinterpret_cast<wchar_t*>(dataBuffer.data());
                    std::wcout << L"Type: REG_SZ" << std::endl;
                    std::wcout << L"\tName: " << valueName.data() << std::endl;
                    std::wcout << L"\tData : " << reg_string << std::endl;
                }
                else if (type == REG_EXPAND_SZ) {
                    const auto casted = reinterpret_cast<wchar_t*>(dataBuffer.data());
                    TCHAR buffer[32000];
                    ExpandEnvironmentStrings(casted, buffer, 32000);
                    std::wcout << L"Type: REG_EXPAND_SZ" << std::endl;
                    std::wcout << L"\tName: " << valueName.data() << std::endl;
                    std::wcout << L"\tData: " << buffer << std::endl;
                }
                else if (type == REG_MULTI_SZ) {
                    std::vector<std::wstring> lines;
                    const auto str = reinterpret_cast<wchar_t*>(dataBuffer.data());
                    auto line = str;
                    lines.emplace_back(line);
                    for (auto i = 0; i < charBytesData / sizeof(wchar_t) - 1; i++) {
                        const auto c = str[i];
                        if (c == 0) {
                            line = str + i + 1;
                            const auto new_line = reinterpret_cast<wchar_t*>(line);
                            if (wcsnlen_s(new_line, 1024) > 0)
                                lines.emplace_back(new_line);
                        }
                    }
                    std::wcout << L"Type: REG_MULTI_SZ" << std::endl;
                    std::wcout << L"\tName: " << valueName.data() << std::endl;
                    std::wcout << L"\tData: " << std::endl;
                    for (size_t i = 0; i < lines.size(); i++) {
                        std::wcout << L"\t\tLine[" << i + 1 << L"]: " << lines[i] << std::endl;
                    }
                }
                if (type == REG_DWORD) {
                    const auto dword_value = reinterpret_cast<unsigned long*>(dataBuffer.data());
                    std::wcout << L"Type: REG_DWORD" << std::endl;
                    std::wcout << L"\tName: " << valueName.data() << std::endl;
                    std::wcout << L"\tData : " << std::to_wstring(*dword_value) << std::endl;
                }
                else if (type == REG_QWORD) {
                    const auto qword_value = reinterpret_cast<unsigned long long*>(dataBuffer.data());
                    std::wcout << L"Type: REG_DWORD" << std::endl;
                    std::wcout << L"\tName: " << valueName.data() << std::endl;
                    std::wcout << L"\tData : " << std::to_wstring(*qword_value) << std::endl;
                }
                else if (type == REG_BINARY) {
                    std::vector<uint16_t> bins;
                    for (auto i = 0; i < charBytesData; i++) {
                        bins.push_back(static_cast<uint16_t>(dataBuffer[i]));
                    }
                    std::wcout << L"Type: REG_BINARY" << std::endl;
                    std::wcout << L"\tName: " << valueName.data() << std::endl;
                    std::wcout << L"\tData:";
                    for (size_t i = 0; i < bins.size(); i++) {
                        std::wcout << L" " << std::uppercase << std::hex << \
                            std::setw(2) << std::setfill(L'0') << std::to_wstring(bins[i]);
                    }
                    std::wcout << std::endl;
                }
            }
        }
    }

    RegCloseKey(openedKey);
    return 0;
}

প্রত্যাশিত কনসোল আউটপুট:

Type: REG_SZ
        Name: String_Value
        Data : hello, world!
Type: REG_BINARY
        Name: Binary_Value
        Data: 01 01 01 01
Type: REG_DWORD
        Name: Dword value
        Data : 4644
Type: REG_DWORD
        Name: QWord val
        Data : 1188388
Type: REG_MULTI_SZ
        Name: multi-line val
        Data:
                Line[1]: Line 0
                Line[2]: Line 1
                Line[3]: Line 2
Type: REG_EXPAND_SZ
        Name: expanded_val
        Data: C:\Users\user name\new_stuff

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;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.