【问题标题】:RegQueryValueEx - What code add to this function to show ERROR_SUCCESSRegQueryValueEx - 向此函数添加什么代码以显示 ERROR_SUCCESS
【发布时间】:2009-10-03 16:46:06
【问题描述】:

什么代码添加到这个函数中才能正常工作? (ERROR_SUCCESS)

我有代码,可以检查注册表中的值。

函数RegQueryValueEx 是错误。 当oldValuenewValue 长几个字母时,函数显示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!";
  }
 }

}

【问题讨论】:

    标签: c++ winapi registry


    【解决方案1】:

    ERROR_MORE_DATA 表示您需要传入更大的字符串缓冲区。您需要使用的典型模式是调用一次以获取大小,然后分配适当大小的缓冲区,然后再次调用。或者,您也可以猜测一个大小,传入该大小的缓冲区,如果返回 ERROR_MORE_DATA,则增加大小。

    顺便说一句,您也错误地计算了大小。而且您没有关闭注册表项。而且您不准备支持在 unicode 或非 unicode 模式下编译。

    这里有一些修改后的代码可以解决这些问题。

    #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;
    }
    

    【讨论】:

    • 感谢 Justin Grant 提供完整的代码,我现在知道我做错了什么:*
    • 但是当我添加到注册表数据“foo”并使用新数据“foo”运行这个程序时,它显示:旧数据是 foo 新数据是 foo 字符串 1 和字符串 2 不同但是 foo 和 foo是相同的值。如何更改此代码才能正常工作?
    • 不确定。也许其中一个字符串包含空终止符而一个不包含,导致长度不同?在任何情况下,逐个字符地查看字符串,您就会知道它们有何不同以及如何解决问题。
    • 是的,字符串末尾是 '\0' 字符。删除后,字符串相等。 :)
    • newValue.compare(oldValue) != 0 应该写成newValue != oldValue
    【解决方案2】:

    ERROR_MORE_DATA 表示您提供的用于保存数据的缓冲区不够大。

    你的问题是多方面的:

    1. 当您说 sizeof(string) 时,您得到的是字符串数据类型的大小,而不是字符串的长度。您应该调用 string::size() 来获取字符串的长度。
    2. 您不能只将字符串转换为LPBYTE。那将惨遭失败。注册表 API 并非设计为与 strings 一起使用,它们旨在与 char*WCHAR* 类型一起使用。您需要声明一个本地字符数组(例如char *foo = new char[256])然后传递它。如果你得到ERROR_MORE_DATA,请声明一个更大的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 2016-08-03
      • 2022-07-04
      • 1970-01-01
      • 1970-01-01
      • 2014-03-19
      • 1970-01-01
      相关资源
      最近更新 更多