C++中注册表操作

C++接触了一段时间,最近在捣鼓PatrolBot移动机器人小车,在看源码的时候发现有对注册表操作的代码,第一次接触,便来此记录一番。

首先把用到注册表操作的这个函数(ArUtil类的成员函数)搬上来,该函数功能是从注册表中获取一个字符串

AREXPORT bool ArUtil::getStringFromRegistry(REGKEY root,
						   const char *key,
						   const char *value,
						   char *str,
						   int len)
{
#ifndef WIN32
  return false;
#else // WIN32

  HKEY hkey;
  int err;
  unsigned long numKeys;
  unsigned long longestKey;
  unsigned long numValues;
  unsigned long longestValue;
  unsigned long longestDataLength;
  char *valueName;
  unsigned long valueLength;
  unsigned long type;
  char *data;
  unsigned long dataLength;
  HKEY rootKey;


  switch (root)
  {
  case REGKEY_CLASSES_ROOT:
    rootKey = HKEY_CLASSES_ROOT;
    break;
  case REGKEY_CURRENT_CONFIG:
    rootKey = HKEY_CURRENT_CONFIG;
    break;
  case REGKEY_CURRENT_USER:
    rootKey = HKEY_CURRENT_USER;
    break;
  case REGKEY_LOCAL_MACHINE:
    rootKey = HKEY_LOCAL_MACHINE;
    break;
  case REGKEY_USERS:
    rootKey=HKEY_USERS;
    break;
  default:
    ArLog::log(ArLog::Terse, 
	       "ArUtil::getStringFromRegistry: Bad root key given.");
    return false;
  }

  /// 打开一个指定的注册表键
  if ((err = RegOpenKeyEx(rootKey, key, 0, KEY_READ, &hkey)) == ERROR_SUCCESS)
  {
    //printf("Got a key\n");
    if (RegQueryInfoKey(hkey, NULL, NULL, NULL, &numKeys, &longestKey, NULL, 
			&numValues, &longestValue, &longestDataLength, NULL, NULL) == ERROR_SUCCESS)
    { 
      data = new char[longestDataLength+2];
      valueName = new char[longestValue+2];
      for (unsigned long i = 0; i < numValues; ++i)
      {
	dataLength = longestDataLength+1;
	valueLength = longestValue+1;
	if ((err = RegEnumValue(hkey, i, valueName, &valueLength, NULL, 		//用来枚举指定项的值。
				&type, (unsigned char *)data, &dataLength)) == ERROR_SUCCESS)
	{
		//printf("Enumed value %d, name is %s, value is %s\n", i, valueName, data);
	  if (strcmp(value, valueName) == 0)
	  {
	    if (len < dataLength)
	    {
	      ArLog::log(ArLog::Terse,"ArUtil::getStringFromRegistry: str passed in not long enough for data.");
	      delete data;
	      delete valueName;
	      return false;
	    }
	    strncpy(str, data, len);
	    delete data;
	    delete valueName;
	    return true;
	  }
	}
      }
      delete data;
      delete valueName;
    }
  }
  return false;
#endif
}

其中,关于注册表操作的函数只要三个:

1. RegOpenKeyEx

2. RegQueryInfoKey

3. RegEnumValue

下面,我们逐一介绍这三个函数。


1. RegOpenKeyEx

WINADVAPI LSTATUS APIENTRY RegOpenKeyEx (HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult);

函数功能:打开一个指定的注册表键

参数hKey:需要打开的主键的名称,HKEY_CLASSES_ROOT / HKEY_CURRENT_CONFIG / HKEY_CURRENT_USER / HKEY_LOCAL_MACHINE / HKEY_USERS,这五个中的一个哦~

参数lpSubKey:需要打开的子键的名称

参数ulOptions:保留,设为0

参数samDesired:安全访问标记,也就是权限。主要用到的是KEY_READ。

参数phkResult:输出参数,保存将要打开键的句柄。

返回值:零(ERROR_SUCCESS)表示成功。其他任何值都代表一个错误代码。


举例说明:


看到没有,主键只有这五种情况~

假如我想要主键HKEY_LOCAL_MACHINE下面的Aria子键,那么,

参数hKey要设为HKEY_LOCAL_MACHINE

参数lpSubKey要设为"SOFTWARE\\ActivMedia Robotics\\Aria"

C++中注册表操作_第1张图片


2. RegQueryInfoKey

RegQueryInfoKey(
HKEY hkey, 			//要获取信息的句柄
LPWSTR lpClass, 		//接受创建健时的Class字符串
LPDWORD lpcbClass, 		//lpClass的长度
LPDWORD lpReserved, 		//系统保留,指定为0
LPDWORD lpcSubKeys,		//子键数量
LPDWORD lpcbMaxSubKeyLen, 	//子键中最长名称的长度
LPDWORD lpcbMaxClassLen, 	//子键中最长Class字符串长度
LPDWORD lpcVlaues, 		//键值数量
LPDWORD lpcbMaxValueNameLen, 	//键值项中最长名称的长度
LPDWORD lpcbMaxValueLen, 	//键值项数据最大长度
LPDWORD lpcbSecurityDescriptor, //安全描述符长度
FILETIME lpftLastWriteTime, 	//FILETIME结构,最后修改时间
);

函数功能:获取键的统计信息,查看将要读取的字符串长度是否小于键值数据的最大长度。

参数太多,下面只说明重要的参数吧~

参数hkey:指定要获取信息的键句柄,键的打开方式中必须包括KEY_QUERY_VALUE。

参数lpcSubKeys:指向一个双字,用来返回键中的子键数量

参数lpcbMaxSubKeyLen:指向一个双字,用来返回所有子键中最长的名称字符串长度,返回的长度不包括字符串结尾的0字符。

参数lpcVlaues:指向一个双字,用来返回键下面的键值项数量

参数lpcbMaxValueNameLen:指向一个双字,用来返回所有键值项中最长的名称字符串长度,返回的长度不包括字符串结尾的0字符。

参数lpcbMaxValueLen:指向一个双字,用来返回所有键值数据的最大长度

返回值:零(ERROR_SUCCESS)表示成功。其他任何值都代表一个错误代码。
如一个缓冲区的长度不够,不能容下返回的数据,则函数会返回ERROR_MORE_DATA


例子回头再举吧。。。


3. RegEnumValue

RegEnumValue(
Long hkey, //被枚举的键句柄
Long dwIndex, //子键索引编号
String lpValueName, //键值名称
Long lpcbValueName, //键值名称长度
Long lpReserved, //系统保留,指定为0
Long lpType, //键值数据类型
Byte lpDate, //键值数据
Long lpcbDate //键值数据长度
);

函数功能:用来枚举指定项的值



你可能感兴趣的:(C++,patrolBot,Windows)