C++ 为什么 RegQueryValueEx() 函数在尝试从注册表项读取时返回 ERROR_FILE_NOT_FOUND?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8588909/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:50:27  来源:igfitidea点击:

Why does the RegQueryValueEx() function return ERROR_FILE_NOT_FOUND while trying to read from a registry key?

c++windowsregistryregistrykey

提问by killdaclick

System: Windows 7 32bit
Language: C++

系统:Windows 7 32bit
语言:C++

I have tried to access register HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0, key Driver(type REG_SZ) -- no problem.

我试图访问 register HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0, key Driver(type REG_SZ) - 没问题。

The same for reading from HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM, all keys (types REG_SZ) got slashes, for example \Device\Serial0.

与读取相同HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM,所有键(类型REG_SZ)都有斜线,例如\Device\Serial0

While reading such keys it always returns 2 (no such file) with following example code:

在读取此类密钥时,它始终返回 2(没有此类文件),并带有以下示例代码:

HKEY hKey = 0;
DWORD dwType = REG_SZ;
char buf[255] = {0};
DWORD dwBufSize = sizeof(buf);

if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("HARDWARE\DEVICEMAP\SERIALCOMM"), 0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS ) 
{
  auto ret = RegQueryValueEx( hKey, TEXT("\Device\Serial0"), 0, &dwType, (LPBYTE)buf, &dwBufSize );
  // ret always == 2 for key with slashes
--- CUT ---

What is the proper way to read key values with slashes in name?

读取名称中带有斜杠的键值的正确方法是什么?



Above has been properly answered by Cody Gray.以上已由 Cody Gray 正确回答。

Below another issue.下面另一个问题。



Im getting the same problem when Im using variable instead of a text string.
Iv considered both approaches with single and double slashes:

当我使用变量而不是文本字符串时,我遇到了同样的问题。
Iv 考虑了单斜杠和双斜杠的两种方法:

HKEY hKey = 0;
DWORD keyType = REG_SZ;
TCHAR buf[255] = {0};
DWORD bufSize = sizeof(buf);

QSettings winReg("HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM", QSettings::NativeFormat);
auto comsKey = winReg.allKeys();

FOREACH( auto com, comsKey )
{
  // FOREACH - boost macro
  // comsKey = QList<QString> (list of key names) [from Qt framework]
  // com = QString (single key name) [from Qt framework]
  if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\DEVICEMAP\SERIALCOMM"), 0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS )
  {
    wchar_t* keyw = new wchar_t();
    //com.replace("/", "\\"); <- checked both variants commented and not commented; com == /Device/Serial0 so im converting to \Device\Serial0
    int size = com.size();
    mbstowcs( keyw, com.toStdString().data(), size );
    //auto ret = RegQueryValueEx( hKey, TEXT("\Device\Serial0"), 0, &keyType, (LPBYTE)buf, &bufSize ); // <- this works!
    auto ret = RegQueryValueExW( hKey, (LPCWSTR)&keyw, 0, &keyType, (LPBYTE)buf, &bufSize ); // <- this one not works!

I have tried all variants with "\Device..", "/Device", "\Device", etc.

我已经尝试了所有带有“\Device..”、“/Device”、“\Device”等的变体。

采纳答案by Cody Gray

You have to escape the slashes, just like you did in the first line...

你必须逃避斜线,就像你在第一行做的那样......

if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("HARDWARE\DEVICEMAP\SERIALCOMM"), 0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS ) 
{
  auto ret = RegQueryValueEx( hKey, TEXT("\Device\Serial0"), 0, &dwType, (LPBYTE)buf, &dwBufSize );
  // ret always == 2 for key with slashes

If you don't, the RegQueryValueExfunction can't find the specified key, and it returns ERROR_FILE_NOT_FOUND(== 2).

如果不这样做,该RegQueryValueEx函数将找不到指定的键,并返回ERROR_FILE_NOT_FOUND(== 2)。



But there's another problem. You should be declaring the buffer array as type wchar_t(or TCHAR), rather than char:

但还有一个问题。您应该将缓冲区数组声明为类型wchar_t(或TCHAR),而不是char

TCHAR buf[255] = {0};

Otherwise, the RegQueryValueExfunction is going to attempt to fill the array with a Unicode string read from the specified registry key, and you're going to get something unreadable.

否则,该RegQueryValueEx函数将尝试用从指定的注册表项读取的 Unicode 字符串填充数组,并且您将得到一些不可读的东西。