So lesen Sie einen Wert aus der Windows-Registrierung

Lesezeit: 10 Minuten

So lesen Sie einen Wert aus der Windows Registrierung
nolandda

Wie kann ich angesichts des Schlüssels für einen Registrierungswert (z. B. HKEY_LOCAL_MACHINE\blah\blah\blah\foo):

  1. Stellen Sie sicher fest, dass ein solcher Schlüssel vorhanden ist.
  2. Programmatisch (dh mit Code) erhält seinen Wert.

Ich habe absolut nicht die Absicht, irgendetwas in die Registrierung zurückzuschreiben (für die Dauer meiner Karriere, wenn ich es vermeiden kann). Also können wir den Vortrag über jedes Molekül in meinem Körper, das mit Lichtgeschwindigkeit explodiert, überspringen, wenn ich falsch in das Register schreibe.

Bevorzugen Sie Antworten in C++, müssen aber meistens nur wissen, was die spezielle Windows-API-Beschwörung ist, um den Wert zu erhalten.

So lesen Sie einen Wert aus der Windows Registrierung
Brian R. Bondy

Hier ist ein Pseudo-Code, um Folgendes abzurufen:

  1. Wenn ein Registrierungsschlüssel vorhanden ist
  2. Was der Standardwert für diesen Registrierungsschlüssel ist
  3. Was ein Stringwert ist
  4. Was ein DWORD-Wert ist

Beispielcode:

Schließen Sie die Bibliotheksabhängigkeit ein: 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;
}

  • Wenn dies aus unerklärlichen Gründen nie einen Schlüssel zu finden scheint, kann es sich um ein 32-Bit/64-Bit-Problem handeln. Siehe stackoverflow.com/q/15084380/482758

    – mkjeldsen

    7. September 2013 um 7:47 Uhr

  • Es könnte hilfreich sein zu erwähnen, dass Ihr Code für die Verwendung mit dem verwendet werden soll, was Windows einen Unicode-Zeichensatz nennt. Ich würde die Funktionsaufrufe ändern RegOpenKeyExW und RegQueryValueExW zu ihrem “zeichensatz”-agnostischen Äquivalent RegOpenKeyEx und RegQueryValueEx

    – Hamster

    21. Januar 2014 um 15:38 Uhr


  • Unicode ist Standard, es schlägt nur fehl, wenn jemand das Projekt explizit in Multi-Byte ändert, wozu es keinen Grund gibt

    – paulm

    23. Juli 2015 um 14:53 Uhr

  • Dies ist ein sehr später Kommentar, aber ich möchte alle daran erinnern, dass Sie den Registrierungsschlüssel schließen sollten, wenn Sie damit fertig sind, indem Sie RegCloseKey aufrufen.

    – Kann knospen

    12. Januar 2016 um 15:26 Uhr

  • Das sieht aus wie eine C-API und wir haben 2016. Wickeln Sie die passende Win32-API in C++ ein und nutzen Sie RAII für Ressourcen wie einen HKEY.

    Benutzer4590120

    13. April 2016 um 14:22 Uhr

1646217009 827 So lesen Sie einen Wert aus der Windows Registrierung
Gishu

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

  • gehe zu? Was ist die Verwendung des CRegKey-Konstruktors ohne Argument? Es besteht keine Notwendigkeit, einen nicht initialisierten Registrierungsschlüssel darzustellen. Dafür ist boost::optional gedacht.

    Benutzer4590120

    13. April 2016 um 14:24 Uhr

  • Welche Bibliothek müssen Sie einbinden?

    – Donald Duck

    12. September 2016 um 12:31 Uhr

  • CRegKey klingt nach ATL oder MFC Country.

    – kayleeFrye_onDeck

    29. Oktober 2018 um 20:32 Uhr


1646217010 653 So lesen Sie einen Wert aus der Windows Registrierung
Roi Danton

Seit Windows >=Vista/Server 2008, RegGetValue vorhanden ist, welche ist eine sicherere Funktion als RegQueryValueEx. Kein Bedarf für RegOpenKeyEx, RegCloseKey oder NUL Beendigungsprüfungen von Zeichenfolgenwerten (REG_SZ, REG_MULTI_SZ, REG_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;
}

Sein Parameter dwFlags unterstützt Flags zur Typeinschränkung und füllt den Wertpuffer bei Fehlern mit Nullen (RRF_ZEROONFAILURE) und 32/64-Bit-Registrierungszugriff (RRF_SUBKEY_WOW6464KEY, RRF_SUBKEY_WOW6432KEY) für 64-Bit-Programme.

  • Dieser Code scheint so nah dran zu sein, für mich zu funktionieren, gibt mir aber 2 Fehler, beide in Bezug auf den Parameter static_cast<void*> (valueBuf.data()). Ich kann a nicht verwenden const_cast, und die Verwendung einer Umwandlung im C-Stil scheint mich um den Compilerfehler herumzubringen, nur um mir einen Laufzeitfehler zu bescheren. Irgendwelche Vorschläge?

    – Skewjo

    16. Dezember 2020 um 21:13 Uhr

1646217011 885 So lesen Sie einen Wert aus der Windows Registrierung
Serge

Das Paar RegOpenKey und RegQueryKeyEx wird den Trick machen.

Wenn Sie MFC verwenden CRegKey Klasse ist eine noch einfachere Lösung.

1646217011 33 So lesen Sie einen Wert aus der Windows Registrierung
Tyler

RegQueryValueEx

Gibt den Wert an, falls vorhanden, und gibt einen Fehlercode ERROR_FILE_NOT_FOUND zurück, falls der Schlüssel nicht vorhanden ist.

(Ich kann nicht sagen, ob mein Link funktioniert oder nicht, aber wenn Sie einfach nach “RegQueryValueEx” googeln, ist der erste Treffer die msdn-Dokumentation.)

Typischerweise sind Registerschlüssel und -wert Konstanten im Programm. Wenn dies der Fall ist, finden Sie hier ein Beispiel zum Lesen eines DWORD-Registrierungswerts 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");
}

Informationen zur Anpassung an andere Werttypen finden Sie unter https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-reggetvaluea für komplette spez.

1646217011 54 So lesen Sie einen Wert aus der Windows Registrierung
kayleeFrye_onDeck

Diese Konsolen-App listet alle Werte und ihre Daten aus einem Registrierungsschlüssel für die meisten potenziellen Registrierungswerte auf. Es gibt einige seltsame, die nicht oft verwendet werden. Wenn Sie alle unterstützen müssen, erweitern Sie dieses Beispiel, während Sie darauf verweisen Registrierungswerttyp Dokumentation.

Lassen Sie dies den Inhalt des Registrierungsschlüssels sein, den Sie aus a importieren können .reg Datei Format:

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

Die Konsolen-App selbst:

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

Erwartete Konsolenausgabe:

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

911170cookie-checkSo lesen Sie einen Wert aus der Windows-Registrierung

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy