关于RegQueryValueEx两个小问题

    最近使用到RegQueryValueEx这个函数,发现了两个小问题,总是解决不了,上网上找资料发现不是找不到就是找的不对,现在终于解决了,所以分享给大家来看看,给那些还在困惑中徘徊的和我一样的菜鸟看看,大牛就就直接飘过吧。

 

RegQueryValueEx这个函数MSDN是这样解释的

This function retrieves the type and data for a specified value name associated with an open registry key. 获取一个项的设置值

 

LONG RegQueryValueEx(

  HKEY hKey,

  LPCWSTR lpValueName,

  LPDWORD lpReserved,

  LPDWORD lpType,

  LPBYTE lpData,

  LPDWORD lpcbData

);

第一个参数hKey是一个已打开项的句柄,或者指定一个标准项名。

第二个参数lpValueName是要获取值的名字。

第三个参数lpReserved未用,设为零。

第四个参数lpType用于装载取回数据类型的一个变量。

第五个参数lpData用于装载指定值的一个缓冲区。

第六个参数lpcbData用于装载lpData缓冲区长度的一个变量。一旦返回,它会设为实际装载到缓冲区的字节数。

 

    这个都是很常规的事情,下面我们来看看今天我要说的两个关于这个函数极小的细节,也许会给你们编程带来一定的困难。

第一,无法获取长的键值名

    这里其实键值名的长度是有限制的应该是255吧,但是我发现我在使用这个函数的时候在规定的长度内,比如我写一个250的长度的键值名AAAAAAAAAAAAA……,这个函数就调用失败了,代码如下:

 

  1. #define MAX_KEY_LENGTH 1024   
  2. #define MAX_VALUE_NAME 2048   
  3.     TCHAR achClass[MAX_PATH]={0};  
  4.     DWORD cchClassName = MAX_PATH;   
  5.     DWORD cSubKeys=0;   
  6.     DWORD cbMaxSubKey;  
  7.     DWORD cchMaxClass;  
  8.     DWORD cValues;  
  9.     DWORD cType;  
  10.     DWORD cchMaxValue;  
  11.     DWORD cbMaxValueData;   
  12.     DWORD cbSecurityDescriptor;     
  13.     FILETIME ftLastWriteTime;  
  14.    
  15.     DWORD i, retCode;    
  16.    
  17.     TCHAR achValue[MAX_VALUE_NAME];    
  18.     TCHAR ValueInfo[MAX_VALUE_NAME];  
  19.     DWORD ValueSize=MAX_VALUE_NAME;  
  20.     DWORD cchValue=MAX_VALUE_NAME;   
  21.    
  22.     retCode = RegQueryInfoKey(hKey,achClass,&cchClassName,NULL,&cSubKeys,&cbMaxSubKey,  
  23.                               &cchMaxClass,&cValues,&cchMaxValue,&cbMaxValueData,  
  24.                               &cbSecurityDescriptor,&ftLastWriteTime);  
  25.     if (cValues)    
  26.     {  
  27.         printf( "/nNumber of values: %d/n", cValues);  
  28.         for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++)    
  29.         {    
  30.             achValue[0] = '/0';    
  31.             retCode = RegEnumValue(hKey,i,achValue,&cchValue,NULL,NULL,NULL,NULL);  
  32.             if (retCode == ERROR_SUCCESS )    
  33.             {    
  34.                 printf("(%d) %s/n",i+1,achValue);  
  35.             }   
  36.             ValueSize=MAX_VALUE_NAME;  
  37.             if(RegQueryValueEx(hKey,achValue,NULL,&cType,(LPBYTE)ValueInfo,&ValueSize)==ERROR_SUCCESS)  
  38.             {  
  39.                 if(cType==REG_EXPAND_SZ||cType==REG_SZ||cType==REG_MULTI_SZ)  
  40.                 {  
  41.                     printf("%s/n",ValueInfo);  
  42.                 }  
  43.                 else if(cType==REG_DWORD||cType==REG_BINARY)  
  44.                 {  
  45.                     printf("%d/n",(long)*(short *)ValueInfo);  
  46.                 }  
  47.             }  
  48.         }  
  49.     }  

    这是为什么呢?现在我来告诉你们,RegQueryValueEx在获取键内容的时候,首先需要获取键长度,否则以上一次获取的长度为准,也就是说要么你这样写:

[c-sharp] view plain copy print ?
  1. RegQueryValueEx(hKey,achValue,NULL,NULL,NULL,&ValueSize)==ERROR_SUCCESS;  
  2. RegQueryValueEx(hKey,achValue,NULL,&cType,(LPBYTE)ValueInfo,&ValueSize)==ERROR_SUCCESS;  

    要么你就在每次调用

RegQueryValueEx(hKey,achValue,NULL,&cType,(LPBYTE)ValueInfo,&ValueSize)==ERROR_SUCCESS函数之前写上ValueSize=MAX_VALUE_NAME,这个在之前的宏定义中有,是2048。

这样就可以读出长文件名了。

第二,如何读出REG_DWORD值

    关于这条我也在网上找了好久,都没有什么结果,有人说用一个union结构体来解决,但是没有说具体怎么解决,如果直接用printf(“%d”,(DWORD)ValueInfo);来强制转换的话,我们会发现虽然不报错,但是数值并不对。最终这个问题是这样解决的,正如上面的代码:

 

  1. else if(cType==REG_DWORD||cType==REG_BINARY)  
  2. {  
  3. printf("%d/n",(long)*(short *)ValueInfo);  
  4. }  

    这样转换一下就可以了,菜鸟们可以自己去思考一下。

    今天就写到这,菜鸟言论,大牛飘过。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值