TDM Geschrieben 25. Januar 2007 Geschrieben 25. Januar 2007 Hallo, ich möchte für ein Programm Daten aus der Windowsregistry laden. Dazu habe ich einen Singleton mit folgendem Konstruktor implementiert: CSettings::CSettings() { auto HRESULT a_hr; auto HKEY a_sHkey; auto HKEY a_sKey = HKEY_LOCAL_MACHINE; a_hr = RegOpenKeyEx(a_sKey, (LPCTSTR) this -> m_seMembers.a_lpRegKey, 0, KEY_ALL_ACCESS, &a_sHkey); _ASSERT(SUCCEEDED(a_hr)); if (SUCCEEDED(a_hr)) { { auto CString a_lpBuffer = _T(""); auto DWORD a_dwValueType = 0; auto DWORD a_dwValueLen = 0; RegQueryValueEx(a_sHkey, BZR_REG_PDATA_PATH, NULL, &a_dwValueType, (LPBYTE) a_lpBuffer.GetBuffer(a_lpBuffer.GetLength()), &a_dwValueLen); if (_T("") == a_lpBuffer) { GetCurrentDirectory(_MAX_PATH, (LPSTR) a_lpBuffer.GetBuffer(a_lpBuffer.GetLength())); a_lpBuffer += _T("\\AV100b.doc"); a_hr = RegSetValueEx(a_sHkey, BZR_REG_PDATA_PATH, 0, REG_SZ, (LPBYTE) (LPCTSTR) a_lpBuffer, a_lpBuffer.GetLength()); _ASSERT(SUCCEEDED(a_hr)); a_hr = RegFlushKey(a_sHkey); _ASSERT(SUCCEEDED(a_hr)); } } RegCloseKey(a_sHkey); } } Daran gibt es jetzt allerdings 2 Probleme: 1. a_lpBuffer ist nach dem Aufruf von RegQueryValueEx immer leer (egal ob ein Wert vorhanden ist oder nicht). 2. Bei GetCurrentDirectory wird zwar der richtige Wert in a_lpBuffer geschrieben, aber nach dem folgenden Verkettungsoperator besitzt a_lpBuffer einen Wert von "\AV100b.doc". Sollte += nicht eigentlich eine Art append sein ? Zitieren
Klotzkopp Geschrieben 25. Januar 2007 Geschrieben 25. Januar 2007 1. a_lpBuffer ist nach dem Aufruf von RegQueryValueEx immer leer (egal ob ein Wert vorhanden ist oder nicht).Das liegt daran, dass du als Puffergröße (a_dwValueLen) 0 übergibst. 2. Bei GetCurrentDirectory wird zwar der richtige Wert in a_lpBuffer geschrieben, aber nach dem folgenden Verkettungsoperator besitzt a_lpBuffer einen Wert von "\AV100b.doc".Das liegt daran, dass du GetBuffer ohne ReleaseBuffer benutzt. Du musst übrigens bei GetBuffer schon so viel Platz fordern, dass die Werte auch reinpassen. GetLength wird dir wohl, so wie der Code jetzt aussieht, 0 liefern, da passt nicht viel rein Zitieren
TDM Geschrieben 25. Januar 2007 Autor Geschrieben 25. Januar 2007 m'kay, jetzt geht das erstmal: CSettings::CSettings() { auto HRESULT a_hr; auto HKEY a_sHkey; auto HKEY a_sKey = HKEY_LOCAL_MACHINE; a_hr = RegOpenKeyEx(a_sKey, (LPCTSTR) this -> m_seMembers.a_lpRegKey, 0, KEY_ALL_ACCESS, &a_sHkey); _ASSERT(SUCCEEDED(a_hr)); if (SUCCEEDED(a_hr)) { { auto HRESULT a_hr; auto CString a_lpBuffer = _T(""); auto DWORD a_dwValueType = 0; auto DWORD a_dwValueLen = _MAX_PATH; RegQueryValueEx(p_sHkey, BZR_REG_WORD_SRC_PATH, NULL, &a_dwValueType, (LPBYTE) a_lpBuffer.GetBuffer(_MAX_PATH), &a_dwValueLen); a_lpBuffer.ReleaseBuffer(); if (_T("") == a_lpBuffer) { GetCurrentDirectory(_MAX_PATH, (LPSTR) a_lpBuffer.GetBuffer(_MAX_PATH)); a_lpBuffer.ReleaseBuffer(); a_lpBuffer += _T("\\AV100b.doc"); a_hr = RegSetValueEx(p_sHkey, BZR_REG_WORD_SRC_PATH, 0, REG_SZ, (LPBYTE) (LPCTSTR) a_lpBuffer, a_lpBuffer.GetLength()); _ASSERT(SUCCEEDED(a_hr)); a_hr = RegFlushKey(p_sHkey); _ASSERT(SUCCEEDED(a_hr)); } this -> m_seMembers.m_lpeWordSource = a_lpBuffer; } RegCloseKey(a_sHkey); } } Danke. Zitieren
Klotzkopp Geschrieben 25. Januar 2007 Geschrieben 25. Januar 2007 Da ist noch ein möglicher Bug drin: Du kannst dich nicht darauf verlassen, dass ein String, den du mit RegQueryValueEx ausliest, nullterminiert ist. Du musst also bei ReleaseBuffer explizit die Länge angeben. Aber die sollte nach dem Aufruf in a_dwValueLen stehen. Und wenn du das irgendwann mal mit UNICODE kompilieren willst, müssen da noch ein paar Umrechnungen rein. Zitieren
TDM Geschrieben 25. Januar 2007 Autor Geschrieben 25. Januar 2007 Da ist noch ein möglicher Bug drin: Du kannst dich nicht darauf verlassen, dass ein String, den du mit RegQueryValueEx ausliest, nullterminiert ist. Du musst also bei ReleaseBuffer explizit die Länge angeben. Aber die sollte nach dem Aufruf in a_dwValueLen stehen. Und wenn du das irgendwann mal mit UNICODE kompilieren willst, müssen da noch ein paar Umrechnungen rein. Das hatte ich vorhin schon probiert - da bekomm ich allerdings immer einen Assert strcore.cpp Line 512 btw: Wieso eigentlich Umrechnung bei UNICODE ? Dachte da wird statt RegQueryValueExA einfach RegQueryValueExW benutzt. Zitieren
Klotzkopp Geschrieben 25. Januar 2007 Geschrieben 25. Januar 2007 Das hatte ich vorhin schon probiert - da bekomm ich allerdings immer einen Assert strcore.cpp Line 512Da ich nicht weiß, welche Version von Visual C++ du verwendest, und ich auch nicht alle hier habe, müsstest du schon sagen, was da mit Assert geprüft wird. Wieso eigentlich Umrechnung bei UNICODE ? Dachte da wird statt RegQueryValueExA einfach RegQueryValueExW benutzt.Ja, aber RegQueryValueEx rechnet in Byte, und GetBuffer/ReleaseBuffer rechnet in Zeichen. Und bei UNICODE ist das nicht mehr gleich. Zitieren
TDM Geschrieben 25. Januar 2007 Autor Geschrieben 25. Januar 2007 VS 6.0 Aber ich nehms zurück - hatte aus Versehen die Variable für den Typ (a_dwValueType ) genommen. :floet: Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.