Registry Werte auslesen.



  • Abend,

    ich möchte Registy-Werte auslesen (später eventuell auch schreiben)
    Leider liefert mein Code nicht die entsprechenden Werte, obwohl diese vorhanden sind...
    Stattdessen wird mir gesagt ich kann die Werte nicht auslesen.

    Folgenden Code habe ich geschrieben:

    Öffnen eines Reg-Keys

    RegKey::RegKey(HKEY hKeyParent, const std::wstring& subKey) {
        DWORD dwDisposition;
        HKEY hKey;
        DWORD retCode;
    
        retCode = static_cast<DWORD>(RegOpenKeyEx(hKeyParent, reinterpret_cast<LPCSTR>(subKey.c_str()), 0, KEY_ALL_ACCESS, &hKey));
    
        if (ERROR_FILE_NOT_FOUND == retCode){
            std::cout << "Create Key." << std::endl;
            retCode = static_cast<DWORD>(RegCreateKeyEx(hKeyParent, reinterpret_cast<LPCSTR>(subKey.c_str()), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition));
        }
    
        if (retCode != ERROR_SUCCESS) {
            std::cout << "Error opening or creating new key." << std::endl;
        }
    
        this->m_hKey = hKey;
    }
    

    DWORD auslesen

    DWORD RegKey::GetDwordValue(const std::wstring& valueName) {
    
        DWORD retValue;
    
        DWORD data;
        DWORD dataSize = sizeof(DWORD);//size of data
    
        retValue = RegQueryValueEx(this->m_hKey, reinterpret_cast<LPCSTR>(valueName.c_str()), NULL, NULL, (LPBYTE) (&data), &dataSize);
    
        if (retValue != ERROR_SUCCESS) {
            std::cout << "Cannot get DWORD value: RegGetValue failed." << std::endl;
        }
    
        return data;
    }
    

    String Value auslesen

    std::wstring RegKey::GetStringValue(const std::wstring &valueName) {
        DWORD dataSize = 0; // size of data, in bytes
        const DWORD flags = RRF_RT_REG_SZ;
        LONG retCode = ::RegGetValue(
                m_hKey,
                nullptr, // no subkey
                reinterpret_cast<LPCSTR>(valueName.c_str()),
                flags,
                nullptr, // type not required
                nullptr, // output buffer not needed now
                &dataSize
        );
        if (retCode != ERROR_SUCCESS) {
            std::cout << "Cannot get size of string value: RegGetValue failed." << std::endl;
        }
    
        std::wstring result;
        result.resize(dataSize / sizeof(wchar_t));
    
        retCode = ::RegGetValue(
                m_hKey,
                nullptr,    // no subkey
                reinterpret_cast<LPCSTR>(valueName.c_str()),
                flags,
                nullptr,    // type not required
                &result[0], // output buffer
                &dataSize
        );
        if (retCode != ERROR_SUCCESS) {
            std::cout << "Cannot get string value: RegGetValue failed." << std::endl;
        }
    
        result.resize((dataSize / sizeof(wchar_t)) - 1);
    
        return result;
    

    und hier meine Test Main

    int main() {
        cout << "Try to Open Reg" << endl;
        RegKey key(HKEY_CURRENT_USER, L"Software\\GioTest");
        DWORD dw    = key.GetDwordValue(L"TestDword");
        wstring s   = key.GetStringValue(L"TestString");
        cout << "DWORD: " << dw << endl;
    }
    

    Folgende Meldung wird ausgespuckt:

    Try to Open Reg
    Cannot get DWORD value: RegGetValue failed.
    Cannot get string value: RegGetValue failed.
    terminate called after throwing an instance of 'std::length_error'
    Cannot get size of string value: RegGetValue failed.
      what():  basic_string::_M_replace_aux
    

    Vielleicht kann mir jemand sagen was falsch läuft.

    Gruß Swoopo



  • Warum reinterpret_cast<LPCSTR>(...)?

    Wenn es einen Compilerfehler gibt, dann solltest du dir überlegen, warum (und dann die Ursache beheben und nicht den Fehler zu unterdrücken)?
    Stichwort: ANSI <-> UNICODE



  • Unter MSVC definieren im Präprozessor (ich gehe einfach mal davon aus, dass GCC das schluckt)

    _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
    

    Dann

    #include <iostream>
    #include <locale>
    #include <codecvt>
    #include <string>
    
    #include <windows.h>
    
    int main()
    {
    
    	std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    	const std::wstring str{ L"This\\Is\\A\\Test" };
    	std::wcout << L"str:\t" << str << '\n';
    	std::cout << "wrong:\t" << reinterpret_cast<LPCSTR>(str.c_str()) << '\n';
    	std::cout << "right:\t" << converter.to_bytes(str) << '\n';
    
    	// Geht evtl. auch? --- vorsicht.... warum? Weil beim Hantieren mit Buffern gaaanz schnell Sicherheitslücken entstehen (können)
    	int size = WideCharToMultiByte(CP_UTF8, 0, str.data(), str.size(), NULL, 0, NULL, NULL);
    	if (size) {
    		std::string conv;
    		conv.resize(size);
    		WideCharToMultiByte(CP_UTF8, 0, str.data(), str.size(), conv.data(), size, NULL, NULL);
    		std::cout << "ok too:\t" << conv << '\n';
    	}
    }
    

    Output:

    str:    This\Is\A\Test
    wrong:  T
    right:  This\Is\A\Test
    ok too: This\Is\A\Test
    


  • @swoopo sagte in Registry Werte auslesen.:

    retCode = static_cast<DWORD>(RegOpenKeyEx(hKeyParent, reinterpret_cast<LPCSTR>(subKey.c_str()), 0, KEY_ALL_ACCESS, &hKey));
    if (ERROR_FILE_NOT_FOUND == retCode){
    

    Warum testest du retCode auf ERROR_FILE_NOT_FOUND und willst dann einen Key erstellen? Wenn man in die MSDN schaut steht da eindeutig das bei Erfolg die Funktion ERROR_SUCCESS zurück gibt.



  • @CTecS Ja ..., bei Erfolg ist der Schlüssel ja schon da, und braucht nicht mehr angelegt zu werden 😜
    Das Problem hat doch Th69 aufgezeigt:
    Entweder im Multibyte-Modus erstellen und dann string, char usw. benutzen, oder im Unicode-Modus erstellen und dann wstring, wchar usw. benutzen - also einfach nur durchgängig für eins von beiden entscheiden und nicht mischen.


Log in to reply