文章目录
- 前言
- 注册表介绍
- 打开和关闭注册表
- RegOpenKeyEx
- RegCloseKey
- 测试案例
- 创建删除子键
- RegCreateKeyEx
- 创建子键
- RegDeleteKey
- 删除子键
- 写入删除键值
- RegQueryValueEx
- RegSetValueEx
- RegDeleteValue
- 测试案例
- 子键和项的枚举
- RegEnumKeyEx
- RegEnumValue
- RegQueryInfoKey
- 测试案例
- 总结
前言
- 各位师傅大家好,我是qmx_07,今天给大家讲解注册表的相关知识点
注册表介绍
- 概述:注册表是Windows操作系统、硬件设备以及客户应用程序得以正常运行和保存设置的核心"数据库",也可以说是一个非常巨大的树状分层结构的数据库系统
- 用于存储计算机上的硬件、安装的软件、系统设置以及用户账户配置等重要信息,记录了用户安装在计算机上的软件和每个程序的相互关联信息,包括了计算机的硬件配置,包括自动配置的即插即用的设备和已有的各种设备说明、状态属性以及各种状态信息和数据
- 早期的注册表以ini为扩展名的文本文件的配置文件
- 特点:
1.注册表允许对硬件、系统参数、应用程序和设备驱动程序进行跟踪配置,这使得修改某些设置后不用重新启动成为可能。
2.注册表中登录的硬件部分数据可以支持高版本Windows的即插即用特性。当Windows检测到机器上的新设备时,就把有关数据保存到注册表中,另外,还可以避免新设备与原有设备之间的资源冲突。
3.管理人员和用户通过注册表可以在网络上检查系统的配置和设置,使得远程管理得以实现
注册表查看:Win + R 运行 regedit 。可以改动的区域 - HKEY_CURRENT_USER - SOFTWARE
根键说明:
注册表的取值:
字符串值(REG_Sz):固定长度的文本字符串
二进制值(REG_BINARY):原始二进制数据。多数硬件组件信息都以二进制数据存储
DWORD值(REG_DWORD):数据由4字节长的数表示。设备驱动程序和服务的很多参数都是这种类型
QWORD值(REG_QwORD):数据由8字节长的数表示
多字符串值(REG_MULTl_SZ):多重字符串。包含列表或多值的值通常为该类型
可扩充字符串值(REG_EXPAND_Z):长度可变的数据串。该数据类型包含在程序或服务使用该数据时解析的变量
打开和关闭注册表
RegOpenKeyEx
- 介绍:打开注册表
LSTATUS RegOpenKeyExA([in] HKEY hKey,//根键[in, optional] LPCSTR lpSubKey,//项[in] DWORD ulOptions,//指定打开注册表的选项,通常为0 默认访问选项[in] REGSAM samDesired,//访问权限 KEY_READ、KEY_WRIT 等[out] PHKEY phkResult//指向HKEY类型的指针,用于接收打开的注册表项的句柄
);
- 返回值: LSTATUS类型,表示注册表的状态码,成功为 ERROR_SUCESS ,失败返回错误码
RegCloseKey
- 介绍: 关闭注册表句柄
LSTATUS RegCloseKey([in] HKEY hKey //要关闭的注册表句柄
);
测试案例
//打开注册表HKEY hKey;LPCSTR lpSubKey = R"(SOFTWARE\Microsoft\Windows\CurrentVersion)";//打开注册表LSTATUS result = RegOpenKeyExA(HKEY_CURRENT_USER, lpSubKey, 0, KEY_READ, &hKey);//判断是否存在if (result == ERROR_SUCCESS){//存在之后 可以做增删改查等操作cout << "成功打开注册表!" << endl;//关闭句柄RegCloseKey(hKey);}else{//打开失败,显示错误码 寻找错误原因cout << "打开注册表失败!/t" << "错误码是:" << result << endl;}
- 判断打开HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion是否成功
创建删除子键
RegCreateKeyEx
- 介绍:用于创建注册表子键
LSTATUS RegCreateKeyExA([in] HKEY hKey,//根键[in] LPCSTR lpSubKey,//要创建键的路径DWORD Reserved,//保留字段,填写为0[in, optional] LPSTR lpClass,//用户定义类类型,可以填写为NULL[in] DWORD dwOptions,//创建或打开注册表时的选项[in] REGSAM samDesired,//访问权限[in, optional] const LPSECURITY_ATTRIBUTES lpSecurityAttributes,//安全属性 可以填写为NULL[out] PHKEY phkResult,//用于接收创建或打开的注册表项的句柄[out, optional] LPDWORD lpdwDisposition//返回操作的结果信息
);
创建子键
HKEY hKey;LPCSTR lpSubKey = R"(SOFTWARE\Microsoft\CR41)";DWORD dwDispoosition = 0;LSTATUS result = RegCreateKeyEx(HKEY_CURRENT_USER, lpSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDispoosition);if (result == ERROR_SUCCESS){cout << "成功创建子键!" << endl;RegCloseKey(hKey);}else{cout << "创建子键失败!/t" << "错误码是:" << result << endl;}
- 创建HKEY_CURRENT_USER\SOFTWARE\Microsoft\CR41
RegDeleteKey
- 介绍:删除注册表子键
LSTATUS RegDeleteKeyA([in] HKEY hKey,//根键[in] LPCSTR lpSubKey//要删除的子键
);
删除子键
LPCSTR lpSubKey = R"(SOFTWARE\Microsoft\CR41)";LSTATUS result = RegDeleteKey(HKEY_CURRENT_USER, lpSubKey);if (result == ERROR_SUCCESS){cout << "子键删除成功!" << endl;}else{cout << "子键删除失败!\t" << "错误码:" << result << endl;}
- 删除子键HKEY_CURRENT_USER\SOFTWARE\Microsoft\CR41
写入删除键值
RegQueryValueEx
- 介绍:查询键值数据
LSTATUS RegQueryValueExA([in] HKEY hKey,//根键[in, optional] LPCSTR lpValueName,//要查询的注册表的键名LPDWORD lpReserved,//保留参数,填写NULL[out, optional] LPDWORD lpType,//用于查询接收值的数据类型[out, optional] LPBYTE lpData,//用于查询接收值的数据[in, out, optional] LPDWORD lpcbData//用于接收实际写入缓冲区的数据大小
);
RegSetValueEx
- 介绍:设置键值
LSTATUS RegSetValueExA([in] HKEY hKey,//根键[in, optional] LPCSTR lpValueName,//键名称DWORD Reserved,//保留参数,填写NULL[in] DWORD dwType,//表示要设置的数据类型[in] const BYTE *lpData,//要设置的数据缓冲区指针[in] DWORD cbData//表示要设置的数据大小
);
RegDeleteValue
- 介绍:删除键值
LSTATUS RegDeleteValueA([in] HKEY hKey,//根键[in, optional] LPCSTR lpValueName//键名称
);
测试案例
//创建案例
//打开注册表HKEY hKey;LSTATUS result = RegOpenKeyExA(HKEY_CURRENT_USER, R"(SOFTWARE\Microsoft\CR41)", 0, KEY_ALL_ACCESS, &hKey);if (result == ERROR_SUCCESS){//存在之后 可以做增删改查等操作//创建字符串char szBuf[] = { "一刀封喉" };result = RegSetValueEx(hKey,"小李飞刀",0,REG_SZ,(LPBYTE)szBuf,sizeof(szBuf));if (result != ERROR_SUCCESS){cout << "创建失败!" << endl;}//创建数字DWORD dwData = 100;result = RegSetValueEx(hKey,"数字",0,REG_DWORD,(LPBYTE)&dwData,sizeof(dwData));if (result != ERROR_SUCCESS){cout << "创建失败!" << endl;}}else{cout << "RegOpenKey Failed!" << endl;}
- 判断子键是否存在,创建字符串 和 数字项
//查询数据
//打开注册表HKEY hKey;LSTATUS result = RegOpenKeyExA(HKEY_CURRENT_USER, R"(SOFTWARE\Microsoft\CR41)", 0, KEY_ALL_ACCESS, &hKey);if (result == ERROR_SUCCESS){//用来存储 读取到的数据DWORD dwType;DWORD dwValue = 0;DWORD dwSize = sizeof(dwSize);//判断是否查询成功if (RegQueryValueEx(hKey, "数字", 0, &dwType, (LPBYTE)&dwValue, &dwSize) == ERROR_SUCCESS){cout << "数字 :"<< dwValue << endl;}else{cout << "查询失败:" << GetLastError()<< endl;}}else{cout << "RegOpenKey Failed!" << endl;}
//删除值
//打开注册表HKEY hKey;LSTATUS result = RegOpenKeyExA(HKEY_CURRENT_USER, R"(SOFTWARE\Microsoft\CR41)", 0, KEY_ALL_ACCESS, &hKey);// 判断是否查询成功if (result == ERROR_SUCCESS){if (RegDeleteValue(hKey, "数字") == ERROR_SUCCESS) {std::cout << "成功删除!" << std::endl;}else {std::cout << "删除失败!" << std::endl;}}else{cout << "查询失败" << endl;}}
- 判断项是否存在,删除
子键和项的枚举
RegEnumKeyEx
- 介绍:枚举注册表项的子项
LSTATUS RegEnumKeyExA([in] HKEY hKey,//根键[in] DWORD dwIndex,//要枚举的子项索引[out] LPSTR lpName,//用于存储返回的子项名称[in, out] LPDWORD lpcchName,//存储缓冲区的大小LPDWORD lpReserved,//保留参数,填写NULL[in, out] LPSTR lpClass,//返回子项的类名[in, out, optional] LPDWORD lpcchClass,//存储缓冲区的大小[out, optional] PFILETIME lpftLastWriteTime//上次写入时间
);
RegEnumValue
- 介绍:枚举键值
LSTATUS RegEnumValueA([in] HKEY hKey,//根键[in] DWORD dwIndex,//要枚举键值的索引[out] LPSTR lpValueName,//返回值的名称[in, out] LPDWORD lpcchValueName,//用于缓冲区大小LPDWORD lpReserved,//保留参数,填写NULL[out, optional] LPDWORD lpType,//用于接收值的类型[out, optional] LPBYTE lpData,//用于接收值的数据[in, out, optional] LPDWORD lpcbData//用于指定缓冲区的大小
);
RegQueryInfoKey
- 介绍:存储有关注册表的相关信息
LSTATUS RegQueryInfoKeyA([in] HKEY hKey,//根键[out, optional] LPSTR lpClass,//键的类名[in, out, optional] LPDWORD lpcchClass,//存储lpClass的缓冲区大小LPDWORD lpReserved,//保留参数,填写NULL[out, optional] LPDWORD lpcSubKeys,//子键的数量[out, optional] LPDWORD lpcbMaxSubKeyLen,//用于接收子键名称最大长度[out, optional] LPDWORD lpcbMaxClassLen,//用于接收子键类的最大长度[out, optional] LPDWORD lpcValues,//用于接收键值[out, optional] LPDWORD lpcbMaxValueNameLen,//用于接收所查询键下最长值项名称的长度[out, optional] LPDWORD lpcbMaxValueLen,//用于接收所查询键下最长值项数据的长度[out, optional] LPDWORD lpcbSecurityDescriptor,//接收所查询键的安全描述符的大小[out, optional] PFILETIME lpftLastWriteTime//表示所查询键的最后写入时间
);
测试案例
遍历键值:
//打开注册表,判断是否存在HKEY hKey;LSTATUS result = RegOpenKeyExA(HKEY_CURRENT_USER, R"(SOFTWARE\Microsoft\CR41)", 0, KEY_ALL_ACCESS, &hKey);if (result != ERROR_SUCCESS){printf("打开失败!");}//获取值的数量DWORD dwValNumber = 0;RegQueryInfoKey(hKey,NULL, NULL, NULL, NULL, NULL, NULL,&dwValNumber,//值的个数NULL, NULL, NULL, NULL);//使用RegEnumValue循环获取值的内容 名字,类型,值for (DWORD i = 0; i < dwValNumber; i++){char szValueName[MAXBYTE] = {};DWORD dwNameBufLen = sizeof(szValueName);DWORD dwType = 0;BYTE aryDataBuf[MAXBYTE] = {};DWORD aryDataBufLen = sizeof(aryDataBuf);RegEnumValue(hKey, i,szValueName, &dwNameBufLen,//获取值名称数据NULL,&dwType,//获取值类型aryDataBuf, &aryDataBufLen);//获取值数据//按照类型打印输出switch (dwType){case REG_SZ:printf("name:%s\t REG_SZ\t\t value:%s\n", szValueName, aryDataBuf);break;case REG_DWORD:printf("name:%s\t REG_DWORD\t value:%08X\n", szValueName, *(LPDWORD)aryDataBuf);break;default:printf("name:%s\t UNKNOWN\n");break;}}
遍历项:
HKEY hKey;LSTATUS result = RegOpenKeyExA(HKEY_CURRENT_USER, R"(SOFTWARE\Lenovo)", 0, KEY_ALL_ACCESS, &hKey);//获取值的数量DWORD dwSubKeyCount = 0;RegQueryInfoKey(hKey,NULL, NULL, NULL,&dwSubKeyCount,NULL, NULL,NULL,//值的个数NULL, NULL, NULL, NULL);for (DWORD i = 0; i < dwSubKeyCount; i++){char szValueName[MAXBYTE] = {};DWORD dwNameBufLen = sizeof(szValueName);RegEnumKeyEx(hKey, i,szValueName, &dwNameBufLen,//获取值名称数据NULL,NULL,//获取值类型NULL,NULL);//获取值数据printf("name:%s\t\n ", szValueName);}
总结
- 介绍了注册表的概念,打开关闭注册表,创建和删除子键,写入删除键值,以及枚举