Windows系统编程 - 注册表

news2024/11/24 2:04:17

文章目录

  • 前言
    • 注册表介绍
    • 打开和关闭注册表
      • 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);

	}

在这里插入图片描述

总结

  • 介绍了注册表的概念,打开关闭注册表,创建和删除子键,写入删除键值,以及枚举

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2246362.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Jenkins + gitee 自动触发项目拉取部署(Webhook配置)

目录 前言 Generic Webhook Trigger 插件 下载插件 ​编辑 配置WebHook 生成tocken 总结 前言 前文简单介绍了Jenkins环境搭建&#xff0c;本文主要来介绍一下如何使用 WebHook 触发自动拉取构建项目&#xff1b; Generic Webhook Trigger 插件 实现代码推送后&#xff0c;触…

Failed to start Docker Application Container Engine

说明&#xff1a; 1&#xff09;访问应用业务&#xff0c;读取不到数据&#xff0c;show databases;查看数据库报错 2&#xff09;重启docker服务&#xff0c;服务启动失败&#xff0c;查看日志报错如下图所示 3&#xff09;报错信息&#xff1a;chmod /data/docker: read-only…

1、HCIP之RSTP协议与STP相关安全配置

目录 RSTP—快速生成树协议 STP STP的缺点&#xff1a; STP的选举&#xff08;Listening状态中&#xff09;&#xff1a; RSTP P/A&#xff08;提议/同意&#xff09;机制 同步机制&#xff1a; 边缘端口的配置&#xff1a; RSTP的端口角色划分&#xff1a; ensp模拟…

Kafka 生产者优化与数据处理经验

Kafka&#xff1a;分布式消息系统的核心原理与安装部署-CSDN博客 自定义 Kafka 脚本 kf-use.sh 的解析与功能与应用示例-CSDN博客 Kafka 生产者全面解析&#xff1a;从基础原理到高级实践-CSDN博客 Kafka 生产者优化与数据处理经验-CSDN博客 Kafka 工作流程解析&#xff1a…

Hello-Go

Hello-Go 环境变量 GOPATH 和 GOROOT &#xff1a;不同于其他语言&#xff0c;go中没有项目的说法&#xff0c;只有包&#xff0c;其中有两个重要的路径&#xff0c;GOROOT 和 GOPATH Go开发相关的环境变量如下&#xff1a; GOROOT&#xff1a;GOROOT就是Go的安装目录&…

android 实现答题功能

一、效果 二、实现思路 1、界面实现 实现起来其实不难&#xff0c;首先我们可以看到&#xff0c;界面是由答题进度、题目、选项ABCD组成&#xff0c;现在就是要考虑实现方式&#xff0c;答题进度可以使用Textviewprogressbar实现&#xff0c;题目直接使用Textview&#xff0c;…

基于Java Springboot高校工作室管理系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

React(二)

文章目录 项目地址七、数据流7.1 子组件传递数据给父组件7.1.1 方式一:給父设置回调函数,传递给子7.1.2 方式二:直接将父的setState传递给子7.2 给props传递jsx7.2.1 方式一:直接传递组件给子类7.2.2 方式二:传递函数给子组件7.3 props类型验证7.4 props的多层传递7.5 cla…

浅谈丨功能安全测试,汽车的守护者

随着新能源汽车迅猛的发展&#xff0c;各类车型频频面世&#xff0c;同时辅助驾驶/自动驾驶等智驾功能也在不断迭代&#xff0c;使得整个汽车系统的复杂性越来越高&#xff0c;最终导致消费者不得不对如今的汽车质量和安全性提出质疑。 如何打破质疑&#xff1f; 那就不得不搬…

bridge-multicast-igmpsnooping

# 1.topo # 2.创建命名空间 ip netns add ns0 ip netns add ns1 ip netns add ns2 ip netns add ns3 # 3.创建veth设备 ip link add ns0-veth0 type veth peer name hn0-veth0 ip link add ns1-veth0 type veth peer name hn1-veth0 ip link add ns2-veth0 type veth pe…

密码学11

概论 计算机安全的最核心三个关键目标&#xff08;指标&#xff09;/为&#xff1a;保密性 Confidentiality、完整性 Integrity、可用性 Availability &#xff0c;三者称为 CIA三元组 数据保密性&#xff1a;确保隐私或是秘密信息不向非授权者泄漏&#xff0c;也不被非授权者使…

MIT 6.S081 | 操作系统 | Lab1: Xv6 and Unix utilities

Lab1: Xv6 and Unix utilities 文章目录 Lab1: Xv6 and Unix utilities实验任务1.启动XV6(easy)2.Sleep(easy)-练手的&#xff0c;就是熟悉一下怎么在xv6项目中加.c文件&#xff0c;生成可执行程序并进行测试的1.解析rm.c2.argc 如何被赋值3.Sleep代码4.makefile编辑5.通过make…

在SpringBoot项目中集成MongoDB

文章目录 1. 准备工作2. 在SpringBoot项目中集成MongoDB2.1 引入依赖2.2 编写配置文件2.3 实体类 3. 测试4. 文档操作4.1 插入操作4.1.1 单次插入4.1.2 批量插入 4.2 查询操作4.2.1 根据id查询4.2.2 根据特定条件查询4.2.3 正则查询4.2.4 查询所有文档4.2.5 排序后返回 4.3 删除…

美团-Leaf ID算法集成到SpringBoot项目

提前准备 下载源码 GitHub地址&#xff1a;https://github.com/Meituan-Dianping/Leaf 下载下来 然后 maven install 安装到本地仓库 再需要用到该ID算法的项目中引入 以下内容 <!-- 本地仓库中的Leaf --> <dependency><artifactId>leaf-boot-starte…

AI+若依框架项目

基础应用篇 1.若依搭建 技术选型 RuoYi-Vue版本&#xff0c;采用了前后端分离的单体架构设计&#xff1a; 软件环境&#xff1a;JDK、MySQL 、Redis 、Maven、Node 技术选型&#xff1a;Spring Boot、Spring Security、MyBatis、Jwt、V 官方推荐 课程版本 JDK > 1.8 …

RabbitMQ高可用延迟消息惰性队列

目录 生产者确认 消息持久化 消费者确认 TTL延迟队列 TTL延迟消息 惰性队列 生产者确认 生产者确认就是&#xff1a;发送消息的人&#xff0c;要确保消息发送给了消息队列&#xff0c;分别是确保到了交换机&#xff0c;确保到了消息队列这两步。 1、在发送消息服务的ap…

将django+vue项目发布部署到服务器

1.部署django后端服务 部署架构 1.1 下载依赖插件 pip3.8 freeze > requirements.txt1.2 安装依赖插件 pip3 install -r requirements.txt1.3 安装mysql数据库 apt install mysql-server初始化数据库 CREATE USER admin% IDENTIFIED WITH mysql_native_password BY 123…

论文阅读:SIMBA: single-cell embedding along with features

Chen, H., Ryu, J., Vinyard, M.E. et al. SIMBA: single-cell embedding along with features. Nat Methods 21, 1003–1013 (2024). 论文地址&#xff1a;https://doi.org/10.1038/s41592-023-01899-8 代码地址&#xff1a;https://github.com/pinellolab/simba. 摘要 大多…

商业物联网:拥抱生产力的未来

在现代商业格局中&#xff0c;数据占据至高无上的地位。物联网&#xff08;IoT&#xff09;站在这场数字革命的前沿&#xff0c;将以往模糊不清的不确定因素转变为可衡量、可付诸行动的深刻见解。物联网技术为日常物品配备传感器与连接功能&#xff0c;使其能够实时收集并传输数…

【FRP 内网穿透 从0到1 那些注意事项】

【摘要】 最近跟第三方团队调试问题&#xff0c;遇到一个比较烦的操作。就是&#xff0c;你必须要发个版到公网环境&#xff0c;他们才能链接到你的接口地址&#xff0c;才能进行调试。按理说&#xff0c;也没啥&#xff0c;就是费点时间。但是&#xff0c;在调试的时候&#…