Registry returning FILE_NOT_FOUND
-
I'm using a class to work with the registry that I downloaded from an MSDN article. The problem is that whenever I go to read a string (REG_SZ), the RegGetValue call fails with ERROR_FILE_NOT_FOUND (#2). In fact no matter what I've tried, it insists on returning that error. I've tried building the program for 64-bit as well as 32 - no difference. I've made sure that the key is being opened properly. That succeeds, but reading a string value does not. I'm now pulling my hair out. Does anyone know why it's returning ERROR_FILE_NOT_FOUND? This is the code that's calling RegGetValue:
inline std::wstring RegGetString(HKEY hKey, const std::wstring& subKey, const std::wstring& value)
{
//
// Request the size of the string, in bytes
//
DWORD dataSize{};
LONG retCode = ::RegGetValue(
hKey,
subKey.c_str(),
value.c_str(),
RRF_RT_REG_SZ,
nullptr,
nullptr,
&dataSize);
if (retCode != ERROR_SUCCESS)
{
throw RegistryError{ "Cannot read string from registry", retCode };
}These are the relevant values: hKey is HKEY_CURRENT_USER, subKey is "Software\Microsoft\Windows\CurrentVersion\Run" The string is properly escaped. and value is a REG_SZ entry.
The difficult we do right away... ...the impossible takes slightly longer.
-
I'm using a class to work with the registry that I downloaded from an MSDN article. The problem is that whenever I go to read a string (REG_SZ), the RegGetValue call fails with ERROR_FILE_NOT_FOUND (#2). In fact no matter what I've tried, it insists on returning that error. I've tried building the program for 64-bit as well as 32 - no difference. I've made sure that the key is being opened properly. That succeeds, but reading a string value does not. I'm now pulling my hair out. Does anyone know why it's returning ERROR_FILE_NOT_FOUND? This is the code that's calling RegGetValue:
inline std::wstring RegGetString(HKEY hKey, const std::wstring& subKey, const std::wstring& value)
{
//
// Request the size of the string, in bytes
//
DWORD dataSize{};
LONG retCode = ::RegGetValue(
hKey,
subKey.c_str(),
value.c_str(),
RRF_RT_REG_SZ,
nullptr,
nullptr,
&dataSize);
if (retCode != ERROR_SUCCESS)
{
throw RegistryError{ "Cannot read string from registry", retCode };
}These are the relevant values: hKey is HKEY_CURRENT_USER, subKey is "Software\Microsoft\Windows\CurrentVersion\Run" The string is properly escaped. and value is a REG_SZ entry.
The difficult we do right away... ...the impossible takes slightly longer.
Hmmmm, Your code works for me. Here is how I am calling your function:
HKEY hKey; DWORD dwResult = RegOpenKeyEx(HKEY\_CURRENT\_USER, nullptr, 0, KEY\_READ, &hKey); if (ERROR\_SUCCESS == dwResult) { std::wstring subkey = L"Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run"; std::wstring value = L"OneDrive"; RegGetString(hKey, subkey, value); } RegCloseKey(hKey);
Best Wishes, -David Delaune
-
I'm using a class to work with the registry that I downloaded from an MSDN article. The problem is that whenever I go to read a string (REG_SZ), the RegGetValue call fails with ERROR_FILE_NOT_FOUND (#2). In fact no matter what I've tried, it insists on returning that error. I've tried building the program for 64-bit as well as 32 - no difference. I've made sure that the key is being opened properly. That succeeds, but reading a string value does not. I'm now pulling my hair out. Does anyone know why it's returning ERROR_FILE_NOT_FOUND? This is the code that's calling RegGetValue:
inline std::wstring RegGetString(HKEY hKey, const std::wstring& subKey, const std::wstring& value)
{
//
// Request the size of the string, in bytes
//
DWORD dataSize{};
LONG retCode = ::RegGetValue(
hKey,
subKey.c_str(),
value.c_str(),
RRF_RT_REG_SZ,
nullptr,
nullptr,
&dataSize);
if (retCode != ERROR_SUCCESS)
{
throw RegistryError{ "Cannot read string from registry", retCode };
}These are the relevant values: hKey is HKEY_CURRENT_USER, subKey is "Software\Microsoft\Windows\CurrentVersion\Run" The string is properly escaped. and value is a REG_SZ entry.
The difficult we do right away... ...the impossible takes slightly longer.
-
I'm using a class to work with the registry that I downloaded from an MSDN article. The problem is that whenever I go to read a string (REG_SZ), the RegGetValue call fails with ERROR_FILE_NOT_FOUND (#2). In fact no matter what I've tried, it insists on returning that error. I've tried building the program for 64-bit as well as 32 - no difference. I've made sure that the key is being opened properly. That succeeds, but reading a string value does not. I'm now pulling my hair out. Does anyone know why it's returning ERROR_FILE_NOT_FOUND? This is the code that's calling RegGetValue:
inline std::wstring RegGetString(HKEY hKey, const std::wstring& subKey, const std::wstring& value)
{
//
// Request the size of the string, in bytes
//
DWORD dataSize{};
LONG retCode = ::RegGetValue(
hKey,
subKey.c_str(),
value.c_str(),
RRF_RT_REG_SZ,
nullptr,
nullptr,
&dataSize);
if (retCode != ERROR_SUCCESS)
{
throw RegistryError{ "Cannot read string from registry", retCode };
}These are the relevant values: hKey is HKEY_CURRENT_USER, subKey is "Software\Microsoft\Windows\CurrentVersion\Run" The string is properly escaped. and value is a REG_SZ entry.
The difficult we do right away... ...the impossible takes slightly longer.
Richard Andrew x64 wrote:
I've tried building the program for 64-bit as well as 32 - no difference. I've made sure that the key is being opened properly. That succeeds, but reading a string value does not. I'm now pulling my hair out.
Well, how did you try with "building the program for 64-bit as well as 32"? Did you use the RRF_SUBKEY_WOW6464KEY and RRF_SUBKEY_WOW6432KEY flags? Or somehow else? Also it would be not bad to see how exactly you call this RegGetString function.
-
Hmmmm, Your code works for me. Here is how I am calling your function:
HKEY hKey; DWORD dwResult = RegOpenKeyEx(HKEY\_CURRENT\_USER, nullptr, 0, KEY\_READ, &hKey); if (ERROR\_SUCCESS == dwResult) { std::wstring subkey = L"Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run"; std::wstring value = L"OneDrive"; RegGetString(hKey, subkey, value); } RegCloseKey(hKey);
Best Wishes, -David Delaune
Thank you for your response. The code you posted works for me too. I notice that you opened the HKEY without specifying a subkey in the call to RegOpenKeyEx. You only specified the subkey in the call to RegGetString. Is that the way it's supposed to work? Should I not pass a subkey to RegOpenKeyEx?
The difficult we do right away... ...the impossible takes slightly longer.
-
Thank you for your response. The code you posted works for me too. I notice that you opened the HKEY without specifying a subkey in the call to RegOpenKeyEx. You only specified the subkey in the call to RegGetString. Is that the way it's supposed to work? Should I not pass a subkey to RegOpenKeyEx?
The difficult we do right away... ...the impossible takes slightly longer.
Richard,
Richard Andrew x64 wrote:
I notice that you opened the HKEY without specifying a subkey in the call to RegOpenKeyEx. You only specified the subkey in the call to RegGetString. Is that the way it's supposed to work? Should I not pass a subkey to RegOpenKeyEx?
No. Your sample code works even if I open the subkey in the call to RegOpenKeyEx.
HKEY hKey; DWORD dwResult = RegOpenKeyEx(HKEY\_CURRENT\_USER, L"Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run", 0, KEY\_READ, &hKey); if (ERROR\_SUCCESS == dwResult) { std::wstring subkey = L"Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run"; std::wstring value = L"OneDrive"; RegGetString(hKey, subkey, value); } RegCloseKey(hKey);
Your original bug is due to the fact that you are sending an empty string instead of a null pointer. Make the following change:
inline std::wstring RegGetString(HKEY hKey, const std::wstring& subKey, const std::wstring& value)
{
//
// Request the size of the string, in bytes
//
DWORD dataSize{};
LONG retCode = ::RegGetValue(
hKey,
nullptr, //NULL POINTER ... NOT AN EMPTY STRING
value.c_str(),
RRF_RT_REG_SZ,
nullptr,
nullptr,
&dataSize);
if (retCode != ERROR_SUCCESS)
{
int iDebug = 0;
}
return L"";
}The MSDN documentation is poorly written. You should be following the rules described in the documentation for the RegOpenKeyEx function[^] lpSubKey parameter. The lpSubKey parameter can be NULL only if hKey is one of the predefined keys. If lpSubKey is NULL and hKey is HKEY_CLASSES_ROOT, phkResult receives a new handle to the key specified by hKey. Otherwise, phkResult receives the same hKey handle passed in to the function. Use the 'Is this Page Helpful' button at the bottom of the MSDN documentation for the RegGetValue function[^] and report the discrepancy. Best Wishes, -David Delaune
-
Richard,
Richard Andrew x64 wrote:
I notice that you opened the HKEY without specifying a subkey in the call to RegOpenKeyEx. You only specified the subkey in the call to RegGetString. Is that the way it's supposed to work? Should I not pass a subkey to RegOpenKeyEx?
No. Your sample code works even if I open the subkey in the call to RegOpenKeyEx.
HKEY hKey; DWORD dwResult = RegOpenKeyEx(HKEY\_CURRENT\_USER, L"Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run", 0, KEY\_READ, &hKey); if (ERROR\_SUCCESS == dwResult) { std::wstring subkey = L"Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run"; std::wstring value = L"OneDrive"; RegGetString(hKey, subkey, value); } RegCloseKey(hKey);
Your original bug is due to the fact that you are sending an empty string instead of a null pointer. Make the following change:
inline std::wstring RegGetString(HKEY hKey, const std::wstring& subKey, const std::wstring& value)
{
//
// Request the size of the string, in bytes
//
DWORD dataSize{};
LONG retCode = ::RegGetValue(
hKey,
nullptr, //NULL POINTER ... NOT AN EMPTY STRING
value.c_str(),
RRF_RT_REG_SZ,
nullptr,
nullptr,
&dataSize);
if (retCode != ERROR_SUCCESS)
{
int iDebug = 0;
}
return L"";
}The MSDN documentation is poorly written. You should be following the rules described in the documentation for the RegOpenKeyEx function[^] lpSubKey parameter. The lpSubKey parameter can be NULL only if hKey is one of the predefined keys. If lpSubKey is NULL and hKey is HKEY_CLASSES_ROOT, phkResult receives a new handle to the key specified by hKey. Otherwise, phkResult receives the same hKey handle passed in to the function. Use the 'Is this Page Helpful' button at the bottom of the MSDN documentation for the RegGetValue function[^] and report the discrepancy. Best Wishes, -David Delaune
Thank you, David. I have it working now. You saved what's left of my hair. :laugh:
The difficult we do right away... ...the impossible takes slightly longer.