Почему функция RegQueryValueEx () возвращает файл ошибки, не найденный при попытке чтения из раздела реестра?

система: Windows 7 32bit
Язык: C++

Я попытался получить доступ к регистру HKEY_LOCAL_MACHINEHARDWAREDEVICEMAPScsiScsi Port 0 ключи Driver (типа REG_SZ) -- не проблема.

то же самое для чтения из HKEY_LOCAL_MACHINEHARDWAREDEVICEMAPSERIALCOMM, все ключи (типа REG_SZ) получил косые черты, например DeviceSerial0.

при чтении таких ключей он всегда возвращает 2 (нет такого файла) со следующим примером кода:

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

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

каков правильный способ чтения ключевых значений с косыми чертами в имя?


выше был правильно ответил Коди Грей.
Ниже Еще одна проблема.

Im получает ту же проблему, когда Im использует переменную вместо текстовой строки.
Iv рассмотрел оба подхода с одинарными и двойными косыми чертами:

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

QSettings winReg("HKEY_LOCAL_MACHINEHARDWAREDEVICEMAPSERIALCOMM", 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("HARDWAREDEVICEMAPSERIALCOMM"), 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 DeviceSerial0
    int size = com.size();
    mbstowcs( keyw, com.toStdString().data(), size );
    //auto ret = RegQueryValueEx( hKey, TEXT("DeviceSerial0"), 0, &keyType, (LPBYTE)buf, &bufSize ); // <- this works!
    auto ret = RegQueryValueExW( hKey, (LPCWSTR)&keyw, 0, &keyType, (LPBYTE)buf, &bufSize ); // <- this one not works!

Я пробовал все варианты с " Device..", "/Устройство", "устройство " и т. д.

2 ответов


вы должны избежать косых черт, так же, как вы сделали в первой строке...

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

если вы этого не сделаете,RegQueryValueEx функция не может найти указанный ключ, и он возвращает ERROR_FILE_NOT_FOUND (== 2).


но есть еще одна проблема. Вы должны объявить буферный массив как тип wchar_t (или TCHAR), а не char:

TCHAR buf[255] = {0};

иначе RegQueryValueEx функция попытается заполнить массив строкой Unicode, считанной из указан ключ реестра, и вы получите что-то нечитаемое.


using System;
using System.IO.Ports;

namespace SerialPortExample
{
    class SerialPortExample
    {
        public static void Main()
        {
            // Get a list of serial port names. 
            string[] ports = SerialPort.GetPortNames();

            Console.WriteLine("The following serial ports were found:");

            // Display each port name to the console. 
            foreach(string port in ports)
            {
                Console.WriteLine(port);
            }

            Console.ReadLine();
        }

    }
}

см http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.getportnames(v=vs. 110).aspx