RegQueryValueEx - Какой код добавить в эту функцию, чтобы показать ERROR_SUCCESS - PullRequest
1 голос
/ 03 октября 2009

Какой код добавить к этой функции, чтобы работать хорошо? (ERROR_SUCCESS)

У меня есть код, который проверяет значение в реестре.

В функции RegQueryValueEx ошибка. Когда oldValue на несколько букв длиннее newValue, функция показывает ERROR_MORE_DATA, но я хочу хотеть ERROR_SUCCESS

Какой код добавить к этой функции, чтобы сделать это?

void function(string newValue, string key, string name)

{

 // string key - key in registry, ie Myapp\\Options
 // string name - name in registry
 // string newValue - data in REG_SZ


 string oldValue;
 DWORD keytype = REG_SZ;
    HKEY keyHandle;
 DWORD size = sizeof(string);
 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, key.c_str(),0L,KEY_ALL_ACCESS,&keyHandle) == ERROR_SUCCESS)
 {


  LONG isgood = RegQueryValueEx(keyHandle, name.c_str(), 0, &keytype, (LPBYTE)&oldValue, &size);
  if(isgood == ERROR_MORE_DATA)
   {
    cout << "Error more data\n"; 
   }
  if(isgood == ERROR_SUCCESS)
  {
   cout << "Old data is " << oldValue.c_str() << endl;
   cout << "New data is " << newValue.c_str() << endl;
   if(strcmp(newValue.c_str(), oldValue.c_str()) != 0) // compare 2 strings, if
   {
    cout << "String 1 and string 2 are different";

   }
   else
   {
    cout << "String 1 and string 2 are the same";
   }
  }
  if(isgood == ERROR_FILE_NOT_FOUND)
  {
   cout << "Name in registry not found!";
  }
 }

}

Ответы [ 2 ]

2 голосов
/ 03 октября 2009

ERROR_MORE_DATA означает, что буфер, который вы указали для хранения данных, недостаточно велик.

У вас много проблем:

  1. Когда вы говорите sizeof (string), вы получаете размер строкового типа данных, а не длину строки. Вы должны вызвать string :: size (), чтобы получить длину строки.
  2. Вы не можете просто привести строку к LPBYTE. Это с треском провалится. Реестр API не предназначен для работы с string s, он предназначен для работы с типами char* и WCHAR*. Вам нужно объявить локальный массив символов (например, char *foo = new char[256]), а затем передать его. Если вы получите ERROR_MORE_DATA, объявите большее.
2 голосов
/ 03 октября 2009

ERROR_MORE_DATA означает, что вам нужно передать больший строковый буфер. Типичный шаблон, который вам нужно использовать, - это один раз позвонить, чтобы получить размер, затем выделить буфер правильного размера и снова вызвать. Или, в качестве альтернативы, вы можете угадать размер, передать буфер этого размера и увеличить размер, если вернете ERROR_MORE_DATA.

Кстати, вы также неправильно вычисляете размер. И вы не закрываете ключ реестра. И вы не готовы поддерживать компиляцию в режимах Юникод или не Юникод.

Вот некоторый пересмотренный код, который решает эти проблемы.

#include <string>
#include <vector>
#include <iostream>

#include <windows.h>
using namespace std;

namespace std
{
#ifdef _UNICODE
    #define tcout wcout
    #define tcin wcin
    typedef wstring tstring;
#else
    #define tcout cout
    #define tcin cin
    typedef string tstring;
#endif
};

void function(tstring newValue, tstring key, tstring name)
{
    // string key - key in registry, ie Myapp\\Options
    // string name - name in registry
    // string newValue - data in REG_SZ
    HKEY keyHandle;
    if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, key.c_str(),0L,KEY_ALL_ACCESS,&keyHandle) == ERROR_SUCCESS)
    {
        DWORD size = 500;   // initial size
        vector<TCHAR> buf(size);
        tstring oldValue;
        DWORD keytype = REG_SZ;

        LONG isgood = RegQueryValueEx(keyHandle, name.c_str(), 0, &keytype, (LPBYTE) &buf[0], &size);
        if(isgood == ERROR_SUCCESS)
        {
            oldValue.assign (&buf[0], size);
        }
        else if(isgood == ERROR_MORE_DATA)
        {
            buf.reserve (size); // expand to however large we need
            isgood = RegQueryValueEx(keyHandle, name.c_str(), 0, &keytype, (LPBYTE)&buf[0], &size);
            if(isgood == ERROR_SUCCESS)
                oldValue.assign (&buf[0], size);
        }
        RegCloseKey (keyHandle);    // remember to close this!
        if(isgood == ERROR_SUCCESS)
        {
            tcout << _T("Old data is ") << oldValue << endl;
            tcout << _T("New data is ") << newValue << endl;
            if(newValue.compare(oldValue) != 0) // compare 2 strings, if
            {
                tcout << _T("String 1 and string 2 are different");

            }
            else
            {
                tcout << _T("String 1 and string 2 are the same");
            }
        }
        if(isgood == ERROR_FILE_NOT_FOUND)
        {
            tcout << _T("Name in registry not found!");
        }
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    tstring val;
    function (val, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"), _T("CommonFilesDir"));
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...