文章目录
- 前言
- 注册表介绍
- 打开和关闭注册表
- 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);
}
总结
- 介绍了注册表的概念,打开关闭注册表,创建和删除子键,写入删除键值,以及枚举