C/C++ 实现Windows注册表操作
Windows注册表(Registry)是Windows操作系统中用于存储系统配置信息、用户设置和应用程序数据的一个集中式数据库。它是一个层次结构的数据库,由键(Key)和值(Value)组成,这些键和值被用于存储各种系统和应用程序的配置信息。
以下是注册表的一些基本概念:
- 键(Key): 注册表中的数据结构,类似于文件夹,用于组织和存储相关的信息。每个键可以包含子键和/或值。
- 子键(Subkey): 位于注册表中的键的层次结构中的更深一层的键。子键可以包含其他子键或值。
- 值(Value): 存储在注册表中的数据单元,通常与键相关联。值可以包含配置信息、用户设置等数据。
- 数据类型(Data Type): 值的数据类型定义了值的内容和用途。常见的数据类型包括字符串、整数、二进制数据等。
- 根键(Root Key): 注册表的最顶层,有几个根键,常见的包括
HKEY_CLASSES_ROOT、HKEY_CURRENT_USER、HKEY_LOCAL_MACHINE等。
Windows注册表的作用包括:
- 存储系统配置信息: 注册表中存储了操作系统的配置信息,包括系统启动时需要加载的驱动程序、系统服务、文件关联等。
- 存储用户设置: 注册表中存储了用户特定的设置,如桌面背景、主题、鼠标指针样式等。
- 应用程序配置: 许多应用程序使用注册表存储其配置信息。当应用程序安装时,它可能会在注册表中创建相关的键和值来保存配置。
- 组织系统和应用程序数据: 注册表提供了一个结构化的方式来组织系统和应用程序需要存储的数据,使得操作系统和应用程序可以轻松地检索和修改配置信息。
- 提供对系统设置的访问: 通过注册表,用户和系统管理员可以访问和修改系统的各种设置,从而对系统行为进行调整和优化。
枚举注册表项
RegOpenKeyEx 是一个用于打开指定的注册表键的 Windows API 函数。它允许应用程序访问和操作 Windows 注册表的子键。在较新的 Windows 版本中,例如 Windows 10,RegOpenKeyEx 已被推荐的函数 RegOpenKey 和 RegOpenKeyEx 代替。以下是 RegOpenKeyEx 的一般用法:
LSTATUS RegOpenKeyEx(
HKEY hKey,
LPCTSTR lpSubKey,
DWORD ulOptions,
REGSAM samDesired,
PHKEY phkResult
);
参数说明:
hKey: 指定要打开的基础键的句柄,可以是HKEY_CLASSES_ROOT、HKEY_CURRENT_USER、HKEY_LOCAL_MACHINE等。lpSubKey: 指定相对于hKey的子键路径。ulOptions: 保留参数,通常可以设置为 0。samDesired: 指定键的访问权限,例如KEY_READ或KEY_WRITE。phkResult: 接收指向打开的注册表键的句柄的指针。
函数返回值:
- 如果函数调用成功,返回
ERROR_SUCCESS。 - 如果函数调用失败,返回一个错误代码。
RegEnumValue 用于列举指定注册表键中的值。它可以用来遍历注册表键中的所有值,以便你可以获取键中包含的信息。以下是 RegEnumValue 的一般用法:
LSTATUS RegEnumValue(
HKEY hKey,
DWORD dwIndex,
LPTSTR lpValueName,
LPDWORD lpcchValueName,
LPDWORD lpReserved,
LPDWORD lpType,
LPBYTE lpData,
LPDWORD lpcbData
);
参数说明:
hKey: 指定要列举值的注册表键的句柄。dwIndex: 指定要检索的值的索引。从 0 开始,逐渐递增。lpValueName: 接收值的名称的缓冲区。lpcchValueName: 接收值名称的缓冲区大小的指针。在调用函数之前,你应该将其设置为缓冲区大小。lpReserved: 保留参数,通常可以设置为 NULL。lpType: 接收值的数据类型的指针。lpData: 接收值的数据的缓冲区。lpcbData: 接收数据缓冲区大小的指针。在调用函数之前,你应该将其设置为缓冲区大小。
函数返回值:
- 如果函数调用成功,返回
ERROR_SUCCESS。 - 如果函数调用失败,返回一个错误代码。
枚举指定键值对中是否存在值,如果存在则循环将其输出。
#include <stdio.h>
#include <Windows.h>
void Enum_Regedit(HKEY Reg_Root,const char *Reg_Path)
{
HKEY hKey = NULL;
DWORD dwType = 0;
char szValueName[MAXBYTE], szValueKey[MAXBYTE] = { 0 };
DWORD dwBufferSize = MAXBYTE, dwKeySize = MAXBYTE;
// 打开注册表项
LONG lRet = RegOpenKeyEx(Reg_Root, Reg_Path, 0, KEY_ALL_ACCESS, &hKey);
int index = 0;
while (1)
{
// 枚举注册表键项
lRet = RegEnumValue(hKey, index, szValueName, &dwBufferSize, NULL,
&dwType, (unsigned char *)szValueKey, &dwKeySize);
if (lRet == ERROR_NO_MORE_ITEMS)
break;
printf("序号: %3d 名称: %-25s 值: %-50s 类型: ", index, szValueName, szValueKey);
switch (dwType)
{
case 1: printf("REG_SZ \n"); break;
case 2: printf("REG_EXPAND_SZ \n"); break;
case 4: printf("REG_DWORD \n"); break;
case 7: printf("REG_MULTI_SZ \n"); break;
default: printf("None \n"); break;
}
dwBufferSize = MAXBYTE;
dwKeySize = MAXBYTE;
index++;
}
RegCloseKey(hKey);
}
int main(int argc, char *argv[])
{
// 枚举普通启动项
Enum_Regedit(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run");
Enum_Regedit(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run");
// 枚举Boot启动项
// HKLM\System\CurrentControlSet\Control\Session Manager\BootExecute
Enum_Regedit(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Session Manager\\");
// 枚举ActiveX启动项,在子键中添加SubPath即可完成开机自启动.
Enum_Regedit(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\");
system("pause");
return 0;
}
添加注册表项
RegCreateKey 是用于创建或打开指定的注册表键。如果键不存在,则它将被创建;如果存在,则它将被打开。以下是 RegCreateKey 的一般用法:
LSTATUS RegCreateKey(
HKEY hKey,
LPCTSTR lpSubKey,
PHKEY phkResult
);
参数说明:
hKey: 指定要创建或打开的基础键的句柄,可以是HKEY_CLASSES_ROOT、HKEY_CURRENT_USER、HKEY_LOCAL_MACHINE等。lpSubKey: 指定相对于hKey的子键路径。phkResult: 接收指向创建或打开的注册表键的句柄的指针。
函数返回值:
- 如果函数调用成功,返回
ERROR_SUCCESS。 - 如果函数调用失败,返回一个错误代码。
RegSetValueEx 是用于在指定的注册表键中设置一个值。它可以用于创建新的键值,也可以用于修改现有键值。以下是 RegSetValueEx 的一般用法:
LSTATUS RegSetValueEx(
HKEY hKey,
LPCTSTR lpValueName,
DWORD Reserved,
DWORD dwType,
const BYTE *lpData,
DWORD cbData
);
参数说明:
hKey: 指定要设置值的注册表键的句柄。lpValueName: 指定要设置的值的名称。Reserved: 保留参数,通常可以设置为 0。dwType: 指定值的数据类型,例如REG_SZ表示字符串。lpData: 指定要设置的值的数据。cbData: 指定数据的大小。
函数返回值:
- 如果函数调用成功,返回
ERROR_SUCCESS。 - 如果函数调用失败,返回一个错误代码。
通过获取自身进程名称,并将该进程路径写入到CurrentVersion变量中实现开机自启。
#include <stdio.h>
#include <Windows.h>
#define Reg_Path "Software\\Microsoft\\Windows\\CurrentVersion\\Run"
BOOL Reg_Regedit(HKEY Reg_Root,char *lpszFileName, char *lpszValueName)
{
HKEY hKey;
if (ERROR_SUCCESS != RegOpenKeyEx(Reg_Root, Reg_Path, 0, KEY_WRITE, &hKey))
{
return FALSE;
}
if (ERROR_SUCCESS != RegSetValueEx(hKey, lpszValueName, 0, REG_SZ, (BYTE *)lpszFileName, (1 + ::lstrlen(lpszFileName))))
{
RegCloseKey(hKey);
return FALSE;
}
RegCloseKey(hKey);
return TRUE;
}
int main(int argc, char *argv[])
{
TCHAR szPath[MAX_PATH] = { 0 };
if (GetModuleFileName(NULL, szPath, MAX_PATH))
{
int ret = Reg_Regedit(HKEY_CURRENT_USER, szPath, "main");
if (ret == 1)
printf("添加自身启动项成功 \n");
}
system("pause");
return 0;
}
注册表项不仅可以实现开机自启动,由于Win系统都是在注册表之上工作的,只要向指定位置写入键值,即可实现许多不可思议的功能。
// 禁用系统任务管理器
void RegTaskmanagerForbidden()
{
HKEY hkey;
DWORD value = 1;
RegCreateKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", &hkey);
RegSetValueEx(hkey, "DisableTaskMgr", NULL, REG_DWORD, (LPBYTE)&value, sizeof(DWORD));
RegCloseKey(hkey);
}
// 禁用注册表编辑器
void RegEditForbidden()
{
HKEY hkey;
DWORD value = 1;
RegCreateKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", &hkey);
RegSetValueEx(hkey, "DisableRegistryTools", NULL, REG_DWORD, (LPBYTE)&value, sizeof(DWORD));
RegCloseKey(hkey);
}
// 干掉桌面壁纸
void RegModifyBackroud()
{
DWORD value = 1;
HKEY hkey;
RegCreateKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", &hkey);
RegSetValueEx(hkey, "Wallpaper", NULL, REG_SZ, (unsigned char *)"c://", 3);
RegSetValueEx(hkey, "WallpaperStyle", NULL, REG_DWORD, (LPBYTE)&value, sizeof(DWORD));
}
判断键值状态
RegQueryValueEx 是用于检索指定注册表键中的指定值。它可以用来获取注册表键中的数据,例如字符串、整数等。以下是 RegQueryValueEx 的一般用法:
LSTATUS RegQueryValueEx(
HKEY hKey,
LPCTSTR lpValueName,
LPDWORD lpReserved,
LPDWORD lpType,
LPBYTE lpData,
LPDWORD lpcbData
);
参数说明:
hKey: 指定要查询值的注册表键的句柄。lpValueName: 指定要查询的值的名称。lpReserved: 保留参数,通常可以设置为 NULL。lpType: 接收值的数据类型的指针。lpData: 接收值的数据的缓冲区。lpcbData: 接收数据缓冲区大小的指针。在调用函数之前,你应该将其设置为缓冲区大小。
函数返回值:
- 如果函数调用成功,返回
ERROR_SUCCESS。 - 如果函数调用失败,返回一个错误代码。
判断指定键值对是否存在,是否被设置过.
#include <stdio.h>
#include <Windows.h>
#define Reg_Path "Software\\Microsoft\\Windows\\CurrentVersion\\Run"
BOOL Check_Regedit(HKEY Reg_Root,char * name)
{
HKEY hKey;
if (ERROR_SUCCESS == RegOpenKeyEx(Reg_Root, Reg_Path, NULL, KEY_ALL_ACCESS, &hKey))
{
DWORD dwSize = 255, dwType = REG_SZ;
char String[256];
if (ERROR_SUCCESS == RegQueryValueEx(hKey, name, 0, &dwType, (BYTE *)String, &dwSize))
{
return true;
}
}
RegCloseKey(hKey);
return false;
}
int main(int argc, char *argv[])
{
int ret = Check_Regedit(HKEY_CURRENT_USER, "ctfmon");
printf("启动项存在: %d \n", ret);
system("pause");
return 0;
}
删除键值对
RegDeleteValue 是用于删除指定注册表键中的指定值。它可以用来删除注册表键中的数据值。以下是 RegDeleteValue 的一般用法:
LSTATUS RegDeleteValue(
HKEY hKey,
LPCTSTR lpValueName
);
参数说明:
hKey: 指定要删除值的注册表键的句柄。lpValueName: 指定要删除的值的名称。
函数返回值:
- 如果函数调用成功,返回
ERROR_SUCCESS。 - 如果函数调用失败,返回一个错误代码。
传入需要删除的注册表位置,以及该表中键值对的名字即可完成删除。
#include <stdio.h>
#include <Windows.h>
void Delete_Regedit(const char *Reg_Path,const char *Key_Name)
{
char szKeyName[MAXBYTE] = { 0 };
HKEY hKey = NULL;
LONG lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, Reg_Path, 0, KEY_ALL_ACCESS, &hKey);
RegDeleteValue(hKey, Key_Name);
RegCloseKey(hKey);
}
int main(int argc, char *argv[])
{
Delete_Regedit("Software\\Microsoft\\Windows\\CurrentVersion\\Run", "main1");
system("pause");
return 0;
}
C/C++ 实现Windows注册表操作的更多相关文章
- Windows 注册表操作
经常操作注册表,然后得到一份操作注册表函数实现.这里备份下. #ifndef _REGEDIT_H #define _REGEDIT_H int RegRead_S (struct HKEY__*Re ...
- 《天书夜读:从汇编语言到windows内核编程》八 文件操作与注册表操作
1)Windows运用程序的文件与注册表操作进入R0层之后,都有对应的内核函数实现.在windows内核中,无论打开的是文件.注册表或者设备,都需要使用InitializeObjectAttribut ...
- winreg操作windows注册表详解示例
#coding:utf-8 #=====================================================================#=====本程序演示了WINR ...
- 使用Java修改Windows注册表
使用Java修改Windows注册表,使用最基本的就是cmd命令. 事例和运行结果如下所示: package day01; import java.io.IOException; /* 1,reg a ...
- Java 修改Windows注册表,以实现开机自启动应用程序。
使用Java修改Windows注册表,使用最基本的就是cmd命令. 事例和运行结果如下所示: package day01; import java.io.IOException; /* 1,reg a ...
- delphi 注册表操作(读取、添加、删除、修改)完全手册
DELPHI VS PASCAL(87) 32位Delphi程序中可利用TRegistry对象来存取注册表文件中的信息. 一.创建和释放TRegistry对象 1.创建TRegistry对象.为了操 ...
- CRegKey 注册表操作
CRegKey 注册表操作 标签: accessnulluserpathbyteie 2011-11-03 13:55 3477人阅读 评论(0) 收藏 举报 分类: win32(7) 1.简介 ...
- Windows注册表的基本知识及应用
转帖:Windows注册表的基本知识及应用 2009-12-23 11:30:56 分类: Windows注册表的基本知识及应用 一.注册表的重要性 在DOS年代,对计算机的内存管理及系统配置主要通 ...
- Delphi的注册表操作
转帖:Delphi的注册表操作 2009-12-21 11:12:52 分类: Delphi的注册表操作 32位Delphi程序中可利用TRegistry对象来存取注册表文件中的信息. 一.创 ...
- 10#Windows注册表的那些事儿
引言 用了多年的Windows系统,其实并没有对Windows系统进行过深入的了解,也正是由于Windows系统不用深入了解就可以简单上手所以才有这么多人去使用.笔者是做软件开发的,使用的基本都是Wi ...
随机推荐
- 【django-vue】 项目上线 uuid重复问题 内网穿透 支付宝验签 nginx集群 远程连接redis 使用uwsgi启动django
目录 上节回顾 uuid重复问题 内网穿透 支付宝验签 今日内容 1 上线架构图 2 阿里云购买 3 安装git和其他依赖 4 云服务器安装mysql 5 云服务器安装redis(源码安装) 远程连接 ...
- C# 内存缓存工具类 MemoryCacheUtil
C# 内存缓存工具类 MemoryCacheUtil using System; using System.Collections.Concurrent; using System.Collectio ...
- 汇编 | CPU物理地址本质理解
物理地址 我们知道,CPU访问内存单元时,要给出内存单元的地址.所有的内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间中都有唯一的地址,我们将这个唯一的地址称为物理地址. CPU通 ...
- vivo 全球商城:从 0 到 1 代销业务的融合之路
代销是 vivo 商城已经落地的成熟业务,本文提供给各位读者 vivo 商城代销业务中两个异构系统业务融合的对接经验和架构思路. 一.业务背景 近两年,内销商城业务的发展十分迅速,vivo 商城系统的 ...
- Intellij IDEA安装与配置教程(Windows版)
Intellij IDEA(简称IDEA)是Java语言的集成开发环境,在业界公认为是一款优秀的Java开发工具.分为Community社区版(免费)和Untimate终极版(付费). IDEA是一款 ...
- vue中class样式与内联样式
(1):style使用 <div class="score" :style="{ color: colorComputed(item.status) }" ...
- Kafka 社区KIP-405中文译文(分层存储)
原文链接:https://cwiki.apache.org/confluence/display/KAFKA/KIP-405%3A+Kafka+Tiered+Storage 译者:Kafka KIP- ...
- [QML]从零开始QML开发(二)QML开发,浅谈控件、槽函数、锚等基本概念。QML和C++怎么交互?贯彻落实MVC原则
[QML]从零开始QML开发(二)QML开发,浅谈控件.槽函数.锚等基本概念.QML和C++怎么交互?贯彻落实MVC原则 先看代码: import QtQuick 2.12 import QtQuic ...
- 阿里巴巴MYSQL 开发规范
转载请注明出处: (一) 建表规约 1. [强制]表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类型是 unsigned tinyint(1 表示是,0 表示否). 说明:任何字段如果 ...
- spring boot 整合kafka
本文为博主原创,未经允许不得转载: 1. 引入spring boot kafka依赖 <dependency> <groupId>org.springframework.kaf ...