读书人

注册表操作小结

发布时间: 2013-01-23 10:44:50 作者: rapoo

注册表操作总结

参考及摘抄自文章:http://www.cnblogs.com/lartely/archive/2011/04/10/2011770.html

http://blog.csdn.net/sunboy_2050/article/details/7753662

基础知识:

注册表的组织方式跟文件目录比较相似,主要分为根键、子键和键值项三部分,与文件目录对应的话就是根目录、子目录和文件。分别介绍一下这三部分:
1.根键:共有5个,分别为HKEY_CLASSES_ROOT,HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE,HKEY_USERS和HKEY_CURRENT_CONFIG,把它们理解成磁盘的五个分区可以了。
2.子键:可以有多个子键和键值项,就像一个目录中可以有多个子目录和多个文件一样。
3.键值项:可以理解为文件,它由三部分组成,分别为:名称、类型、数据。
类型又分为多种主要包括如下:
REG_BINARY 二进制数据
REG_DWORD 32位双字节数据
REG_SZ 以0结尾的字符串
REG_DWORD_BIG_ENDIAN 高位排在底位的双字
REG_EXPAND_SZ 扩展字符串,可以加入变量如%PATH%
REG_LINK UNICODE 符号链接
REG_RESOURCE_LIST 设备驱动程序资源列表
REG_MULTI_SZ 多字符串
注册表数据项的数据类型有8种,但最常用的主要是前3种。

常用API:

1.打开/关闭注册表键

LONG WINAPI RegOpenKeyEx(
_In_ HKEY hKey, // 父键句柄
_In_opt_ LPCTSTR lpSubKey, // 子键的名称
_Reserved_ DWORD ulOptions, // 保留项,传0即可
_In_ REGSAM samDesired, // 访问权限
_Out_ PHKEY phkResult // 返回子键的句柄
);

HKEY hKey------

父键的句柄,可为RegCreateKeyEx或RegOpenKeyEx返回的注册表键句柄

或为预定义的根键HKEY_CLASSES_ROOT,HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE,HKEY_USERS或HKEY_CURRENT_CONFIG

REGSAM samDesired------

访问权限,想方便的话可以指定为KEY_ALL_ACCESS,这样什么权限都有了。其他常用的权限还有KEY_READ,KEY_WRITE等。

成功开启子键则返回ERROR_SUCCESS

LONG WINAPI RegCloseKey(
_In_ HKEY hKey
);

这两个函数需配对使用


那么怎样用程序实现呢?环境变量的配置存储在注册表当中,可以通过读写注册表来实现读写环境变量。

系统变量存储在注册表的如下位置:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment

而用户变量则存储在注册表的如下位置:HKEY_CURRENT_USER\Environment

下面示例程序用于向系统变量中的Path环境变量中增加内容。

main函数中调用AddPathEnvValue(";HelloKitty")就用于向Path环境变量后面添加;HelloKitty。当然程序中有防呆机制,如果系统变量下刚开始没有Path环境变量则先新增Path环境变量。程序执行成功返回0,执行失败返回-1。

代码如下:

#include <windows.h>#include <iostream>using namespace std;//// 为系统变量下的Path环境变量增加内容lpszPathValue// 成功则返回0// 失败则返回-1// 若刚开始Path环境变量为"D:\\123"// 则调用AddPathEnvValue(";HelloKitty")后为"D:\\123;HelloKitty"//int AddPathEnvValue(LPCSTR lpszPathValue){int ret;// 打开注册表键----------------------------------------HKEY hKey;LPCSTR lpszSubKey = "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, lpszSubKey, 0, KEY_ALL_ACCESS, &hKey);if (ERROR_SUCCESS != ret){cout << "RegOpenKeyExA():Error" << endl;return -1;}// 读取注册表键的键值"Path"----------------------------// 1.获取KeyValueData即字符串的大小LPCSTR lpszKeyValueName = "Path";DWORD  dwKeyValueType = REG_EXPAND_SZ;DWORD  dwKeyValueDataSize = 0;   ret = RegQueryValueExA(hKey, lpszKeyValueName, NULL, &dwKeyValueType, NULL, &dwKeyValueDataSize);if (ret == ERROR_FILE_NOT_FOUND){//不存在Path环境变量则新增一个Path环境变量ret = RegSetValueExA(hKey, lpszKeyValueName, 0, REG_EXPAND_SZ, (const BYTE*)"", 1);if (ret != ERROR_SUCCESS){cout << "RegSetValueExA():Error" << endl;RegCloseKey(hKey);return -1;}}else if (ret != ERROR_SUCCESS){cout << "RegQueryValueExA():Error" << endl;RegCloseKey(hKey);return -1;}else if (dwKeyValueType != REG_EXPAND_SZ){cout << "It is impossible" << endl;cout << dwKeyValueType << endl;RegCloseKey(hKey);return -1;}// 2.获取KeyValueData即字符串的值CHAR *lpszKeyValueData = new CHAR[dwKeyValueDataSize + 1];memset(lpszKeyValueData, 0, dwKeyValueDataSize + 1);ret = RegQueryValueExA(hKey, lpszKeyValueName, NULL, &dwKeyValueType, (LPBYTE)lpszKeyValueData, &dwKeyValueDataSize);if (ret != ERROR_SUCCESS){cout << "RegQueryValueExA():Error" << endl;RegCloseKey(hKey);delete[] lpszKeyValueData;return -1;}// 在原注册表键值的基础上添加新的值unsigned int nLen = strlen(lpszPathValue);nLen += strlen(lpszKeyValueData);CHAR *lpszKeyValueData_New = new CHAR[nLen + 1];memset(lpszKeyValueData_New, 0, nLen + 1);sprintf(lpszKeyValueData_New, "%s%s", lpszKeyValueData, lpszPathValue);ret = RegSetValueExA(hKey, lpszKeyValueName, 0, REG_EXPAND_SZ, (const BYTE*)lpszKeyValueData_New, strlen(lpszKeyValueData_New) + 1);if (ret != ERROR_SUCCESS){cout << "RegSetValueExA:Error" << endl;RegCloseKey(hKey);delete[] lpszKeyValueData;delete[] lpszKeyValueData_New;return -1;}delete[] lpszKeyValueData;delete[] lpszKeyValueData_New;// 关闭注册表键----------------------------------------RegCloseKey(hKey);return 0;}int main(){cout << AddPathEnvValue(";HelloKitty") << endl;return 0;}



1楼zhoujielunzhimi昨天 16:01
我记得我以前也是这么枚举的,但好像获取不到google浏览器安装信息,但是360安全卫士却可以获取。你试试能不能?
Re: wangyao1052昨天 16:29
回复zhoujielunzhimi可以啊,我刚试过了
Re: zhoujielunzhimi昨天 16:32
回复wangyao1052nOK。看来是我记错了。不过,我的确在csdn看到过这样的帖子说这样枚举是不全的。
Re: wangyao1052昨天 16:36
回复zhoujielunzhimin哦,我也不是很懂,只是今天闲来无事就研究下注册表。呵呵,可否找到这个帖子,大家一起探讨下,TKS。

读书人网 >编程

热点推荐