none
RegEnumValue() 函数调用失败---System Error Code 87 RRS feed

  • 问题

  • 我用的是VS2008,调用RegEnumValue函数时,
    返回的值是87(System Error Code "87" 的含义是:The parameter is incorrect.),


    请问下是什么原因,是不是参数不可以为NULL?   要怎样赋值才行?


    全部代码如下:
    ---------------------------------------------------------------------------------
    #pragma comment(lib, "advapi32.lib")
    #include <windows.h>
    #include <stdio.h>

    main()
     {
      int i;
      DWORD dw;
         HKEY hkey;                                                               //保存句柄
         DWORD dwIndex = 0;                                               //索引
      LPTSTR lpValueName = NULL;                                   //键名
         LPDWORD lpcchValueName = NULL;                        //键名长度 
      LPDWORD lpType = NULL;                                        //键类型 
      LPBYTE lpData = NULL;                                             //键值
      LPDWORD lpcbData = NULL;                                    //键值长度

      const char* str = "SOFTWARE\\Tencent\\QQ2009\\";
      LPCTSTR subKey = (LPCTSTR) str;

       if( RegOpenKey(HKEY_LOCAL_MACHINE, subKey, &hkey) == ERROR_SUCCESS )       //打开子键
        {
        printf("打开成功!\n");
        }
       else
        {
       dw = GetLastError();
       printf("error=%d\n", dw);
        }

             for(i = 0; i <= 12; i++)
          {
         dw = RegEnumValue(hkey, dwIndex, lpValueName, lpcchValueName, NULL, lpType, lpData, lpcbData);
         printf("dw = %d,\t%u\t键名:%s\t键值:%s\n", dw, dwIndex, lpValueName, lpData);
          }
        
      
       if( hkey != NULL )
        {
        RegCloseKey(hkey);       //关闭
        printf("已关闭!\n");
        }

     }
    -------------------------------------------------------------------
    运行结果:
    -------------------------------------------------------------------
    打开成功!
    dw = 87, 0 键名:(null) 键值:(null)
    dw = 87, 0 键名:(null) 键值:(null)
    dw = 87, 0 键名:(null) 键值:(null)
    dw = 87, 0 键名:(null) 键值:(null)
    dw = 87, 0 键名:(null) 键值:(null)
    dw = 87, 0 键名:(null) 键值:(null)
    dw = 87, 0 键名:(null) 键值:(null)
    dw = 87, 0 键名:(null) 键值:(null)
    dw = 87, 0 键名:(null) 键值:(null)
    dw = 87, 0 键名:(null) 键值:(null)
    dw = 87, 0 键名:(null) 键值:(null)
    dw = 87, 0 键名:(null) 键值:(null)
    dw = 87, 0 键名:(null) 键值:(null)
    已关闭!
    --------------------------------------------------
    麻烦大家看下,谢谢!


    叶叶叶

    2009年5月27日 11:15

答案

  • 在for(i = 0; i <= 12; i++)
          {
    中重设lpcbData = 255; 
    或者
    for(i = 0; i <= 12; i++)
          {
    ++lpcbData;
     dw = RegEnumValue(hkey, i, valueName, &lpcchValueName, NULL, &lpType, lpData, &lpcbData);
         printf("dw = %3d,\t\ti = %d\t键名:%s\t\t键值:%s\n", dw, i, valueName, lpData);
    }


    麻烦把正确答案设为解答。
    • 已标记为答案 叶叶叶 2009年5月28日 13:49
    2009年5月27日 19:11
    版主
  • 先谢谢楼上的帮忙,
    还有一些问题不明白的,
    我把长度设为 255,有些返回值变成234了,System Error Code 234:More data is available
    是什么意思?难道是长度不度?

    char valueName[255];                                          //键名
         LPDWORD lpcchValueName ;                        //键名长度 
      LPDWORD lpType = NULL;                                        //键类型 
      LPBYTE lpData = NULL;                                             //键值
      LPDWORD lpcbData = 255;                                    //键值长度
    ...//省略了一部分
    for(i = 0; i <= 12; i++)
          {
         dw = RegEnumValue(hkey, i, valueName, &lpcchValueName, NULL, &lpType, lpData, &lpcbData);
         printf("dw = %3d,\t\ti = %d\t键名:%s\t\t键值:%s\n", dw, i, valueName, lpData);
          }

    运行结果:
    dw =   0,  i = 0 键名:version  键值:(null)
    dw = 234,  i = 1 键名:Instal  键值:(null)
    dw = 234,  i = 2 键名:Instal  键值:(null)
    dw = 234,  i = 3 键名:nQQGam  键值:(null)
    dw =   0,  i = 4 键名:nQQCom  键值:(null)
    dw = 234,  i = 5 键名:nQQCom  键值:(null)
    dw = 234,  i = 6 键名:nQQCom  键值:(null)
    dw = 234,  i = 7 键名:nQQCom  键值:(null)
    dw = 234,  i = 8 键名:nQQCom  键值:(null)
    dw = 234,  i = 9 键名:nQQCom  键值:(null)
    dw = 234,  i = 10 键名:nQQCom  键值:(null)
    dw = 259,  i = 11 键名:nQQCom  键值:(null)
    dw = 259,  i = 12 键名:nQQCom  键值:(null)

    ------------------------
    1.为什么键值会全部是NULL的?
    2. i (索引)  改变了,为什么键名不一定会变的?
    3.键名为什么会不完整?( i = 1,2,3 时,键名不完整)


    很多不懂的,希望大家继续帮帮忙!
    先谢谢!!

    叶叶叶


     int i;
     DWORD dw;
     HKEY hkey;                                      //保存句柄
     CHAR valueName[256];                    //键名
     DWORD cchValueName = 256           //键名长度 
     LPDWORD lpType = NULL;                //键类型 
     BYTE data[256];                            //键值
     DWORD cbData = 256;                    //键值长度

     ... ...

     lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, subKey, 0, KEY_ALL_ACCESS, &hkey);

     if(  lRet == ERROR_SUCCESS )       //打开子键
     {
      printf("打开成功!\n");
     }
     else
     {
      dw = GetLastError();
      printf("error=%d\n", dw);
     }

     for(i = 0; i < 12; i++)
     {
      valueName[0] = '\0';
      cchValueName = 256;
      data[0] = '\0';
      dw = RegEnumValue(hkey, i, valueName, &cchValueName, NULL, lpType, data, &cbData);

      printf("dw = %3d,\t\ti = %d\t键名:%s\t\t键值:%s\n", dw, i+1, valueName, data);
     }


    这样设计,可以读出键名和键值,而且不会出现键名和键值不完整的情况。但必须指出,要想上述代码运行正确,必须是未指定_UNICODE宏,即project menu->properties...->configuration Properties->General->Character Set:Not Set

    • 已编辑 Liu Zhi 2009年5月28日 4:29
    • 已标记为答案 叶叶叶 2009年5月28日 13:49
    2009年5月28日 4:22

全部回复

  • lpcchValueName 和lpcbData 不能是NULL。
    这两个值是inout类型。
    需要设置可以放置键名和键值长度的值。否则就会返回参数错误。
    麻烦把正确答案设为解答。
    2009年5月27日 12:29
    版主
  • lpcchValueName 和lpcbData 不能是NULL。
    这两个值是inout类型。
    需要设置可以放置键名和键值长度的值。否则就会返回参数错误。
    麻烦把正确答案设为解答。

    如果键名和键值的长度是是未知的怎么办?设置足够大就行了吗?
    叶叶叶
    2009年5月27日 12:41
  • 呵呵当然不是啦
    RegQueryInfoKey
    可以返回subkey最长的键值和键名长度。
    lpcMaxValueNameLen
    lpcMaxValueLen
    祝端午节快乐

    LONG WINAPI RegQueryInfoKey(
      __in         HKEY hKey,
      __out        LPTSTR lpClass,
      __inout_opt  LPDWORD lpcClass,
      __reserved   LPDWORD lpReserved,
      __out_opt    LPDWORD lpcSubKeys,
      __out_opt    LPDWORD lpcMaxSubKeyLen,
      __out_opt    LPDWORD lpcMaxClassLen,
      __out_opt    LPDWORD lpcValues,
      __out_opt    LPDWORD lpcMaxValueNameLen,
      __out_opt    LPDWORD lpcMaxValueLen,
      __out_opt    LPDWORD lpcbSecurityDescriptor,
      __out_opt    PFILETIME lpftLastWriteTime
    );
    

    麻烦把正确答案设为解答。
    2009年5月27日 14:47
    版主
  • 先谢谢楼上的帮忙,
    还有一些问题不明白的,
    我把长度设为 255,有些返回值变成234了,System Error Code 234:More data is available
    是什么意思?难道是长度不度?

    char valueName[255];                                          //键名
         LPDWORD lpcchValueName ;                        //键名长度 
      LPDWORD lpType = NULL;                                        //键类型 
      LPBYTE lpData = NULL;                                             //键值
      LPDWORD lpcbData = 255;                                    //键值长度
    ...//省略了一部分
    for(i = 0; i <= 12; i++)
          {
         dw = RegEnumValue(hkey, i, valueName, &lpcchValueName, NULL, &lpType, lpData, &lpcbData);
         printf("dw = %3d,\t\ti = %d\t键名:%s\t\t键值:%s\n", dw, i, valueName, lpData);
          }

    运行结果:
    dw =   0,  i = 0 键名:version  键值:(null)
    dw = 234,  i = 1 键名:Instal  键值:(null)
    dw = 234,  i = 2 键名:Instal  键值:(null)
    dw = 234,  i = 3 键名:nQQGam  键值:(null)
    dw =   0,  i = 4 键名:nQQCom  键值:(null)
    dw = 234,  i = 5 键名:nQQCom  键值:(null)
    dw = 234,  i = 6 键名:nQQCom  键值:(null)
    dw = 234,  i = 7 键名:nQQCom  键值:(null)
    dw = 234,  i = 8 键名:nQQCom  键值:(null)
    dw = 234,  i = 9 键名:nQQCom  键值:(null)
    dw = 234,  i = 10 键名:nQQCom  键值:(null)
    dw = 259,  i = 11 键名:nQQCom  键值:(null)
    dw = 259,  i = 12 键名:nQQCom  键值:(null)

    ------------------------
    1.为什么键值会全部是NULL的?
    2. i (索引)  改变了,为什么键名不一定会变的?
    3.键名为什么会不完整?( i = 1,2,3 时,键名不完整)


    很多不懂的,希望大家继续帮帮忙!
    先谢谢!!

    叶叶叶
    2009年5月27日 15:20
  • More data is available说明有更多数据
    传一个更大的缓冲区进去。

    MSMVP VC++
    2009年5月27日 16:20
    版主
  • 在for(i = 0; i <= 12; i++)
          {
    中重设lpcbData = 255; 
    或者
    for(i = 0; i <= 12; i++)
          {
    ++lpcbData;
     dw = RegEnumValue(hkey, i, valueName, &lpcchValueName, NULL, &lpType, lpData, &lpcbData);
         printf("dw = %3d,\t\ti = %d\t键名:%s\t\t键值:%s\n", dw, i, valueName, lpData);
    }


    麻烦把正确答案设为解答。
    • 已标记为答案 叶叶叶 2009年5月28日 13:49
    2009年5月27日 19:11
    版主
  • 先谢谢楼上的帮忙,
    还有一些问题不明白的,
    我把长度设为 255,有些返回值变成234了,System Error Code 234:More data is available
    是什么意思?难道是长度不度?

    char valueName[255];                                          //键名
         LPDWORD lpcchValueName ;                        //键名长度 
      LPDWORD lpType = NULL;                                        //键类型 
      LPBYTE lpData = NULL;                                             //键值
      LPDWORD lpcbData = 255;                                    //键值长度
    ...//省略了一部分
    for(i = 0; i <= 12; i++)
          {
         dw = RegEnumValue(hkey, i, valueName, &lpcchValueName, NULL, &lpType, lpData, &lpcbData);
         printf("dw = %3d,\t\ti = %d\t键名:%s\t\t键值:%s\n", dw, i, valueName, lpData);
          }

    运行结果:
    dw =   0,  i = 0 键名:version  键值:(null)
    dw = 234,  i = 1 键名:Instal  键值:(null)
    dw = 234,  i = 2 键名:Instal  键值:(null)
    dw = 234,  i = 3 键名:nQQGam  键值:(null)
    dw =   0,  i = 4 键名:nQQCom  键值:(null)
    dw = 234,  i = 5 键名:nQQCom  键值:(null)
    dw = 234,  i = 6 键名:nQQCom  键值:(null)
    dw = 234,  i = 7 键名:nQQCom  键值:(null)
    dw = 234,  i = 8 键名:nQQCom  键值:(null)
    dw = 234,  i = 9 键名:nQQCom  键值:(null)
    dw = 234,  i = 10 键名:nQQCom  键值:(null)
    dw = 259,  i = 11 键名:nQQCom  键值:(null)
    dw = 259,  i = 12 键名:nQQCom  键值:(null)

    ------------------------
    1.为什么键值会全部是NULL的?
    2. i (索引)  改变了,为什么键名不一定会变的?
    3.键名为什么会不完整?( i = 1,2,3 时,键名不完整)


    很多不懂的,希望大家继续帮帮忙!
    先谢谢!!

    叶叶叶


     int i;
     DWORD dw;
     HKEY hkey;                                      //保存句柄
     CHAR valueName[256];                    //键名
     DWORD cchValueName = 256           //键名长度 
     LPDWORD lpType = NULL;                //键类型 
     BYTE data[256];                            //键值
     DWORD cbData = 256;                    //键值长度

     ... ...

     lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, subKey, 0, KEY_ALL_ACCESS, &hkey);

     if(  lRet == ERROR_SUCCESS )       //打开子键
     {
      printf("打开成功!\n");
     }
     else
     {
      dw = GetLastError();
      printf("error=%d\n", dw);
     }

     for(i = 0; i < 12; i++)
     {
      valueName[0] = '\0';
      cchValueName = 256;
      data[0] = '\0';
      dw = RegEnumValue(hkey, i, valueName, &cchValueName, NULL, lpType, data, &cbData);

      printf("dw = %3d,\t\ti = %d\t键名:%s\t\t键值:%s\n", dw, i+1, valueName, data);
     }


    这样设计,可以读出键名和键值,而且不会出现键名和键值不完整的情况。但必须指出,要想上述代码运行正确,必须是未指定_UNICODE宏,即project menu->properties...->configuration Properties->General->Character Set:Not Set

    • 已编辑 Liu Zhi 2009年5月28日 4:29
    • 已标记为答案 叶叶叶 2009年5月28日 13:49
    2009年5月28日 4:22
  • 建议楼主不要再用RegOpenKey,改用RegOpenKeyEx。给你一段MSDN参考:Enumerating Registry Subkeys

    http://msdn.microsoft.com/en-us/library/ms724256(VS.85).aspx

    2009年5月28日 4:32
  • 很感谢各位大哥的帮助!!
    端午快乐!!

    叶叶叶
    2009年5月28日 13:50