最初是发现有款软件是根据注册表的数据判断限免额度,但手动更改注册表比较麻烦,然后尝试用bat写一个一键更改的,但bat写条件判断比较麻烦,然后想到了C语言可以直接编译exe执行文件,后来就在网上翻Windows api的文章,但大部分都零零碎碎,也有很多报错的地方。然后一直找相关解决方式,终于是把这个小小的程序给写出来了。下面会直观简单的解释一下代码。
还有一篇省略版,直接贴代码,点击跳转
一、注册表的结构命名 (重点)
我看其他文章太乱了看晕了,于是整理了一下再加上点自己的理解
只是个人理解哦
![image]()
句柄,什么是句柄,我也很懵,我找不到详细的解释,我认为大概就是像注册表的路径一样的存在,那就看有没大佬懂了。
![image]()
本文章主要对值和值的数据进行操作
二、主要函数说明
①、RegCreateKeyEx (根据句柄创建子键)
LONG RegCreateKeyEx(
HKEY hKey, //打开注册表项的句柄。
LPCTSTR lpSubKey,//子项,此功能打开或创建子键。
DWORD Reserved,//为零
LPTSTR lpClass,//此参数可以为null
DWORD dwOptions,//一般使用REG_OPTION_NON_VOLATILE
REGSAM samDesired,//定义访问权限
LPSECURITY_ATTRIBUTES lpSecurityAttributes,//此参数可以为null
PHKEY phkResult,//放接收句柄的变量指针,该函数运行会为这个变量赋值
LPDWORD lpdwDisposition//此参数可以为null
);
该函数由hKey参数标识的键打开一个新句柄,所以不需要在之前加上RegOpenKeyEx函数。
②、RegSetValueEx (设置子键的值和数据)
LONG RegSetValueEx(
HKEY hKey, // 打开注册表项的句柄。
LPCTSTR lpValueName, // 值的名称
DWORD Reserved, // 为0
DWORD dwType, // 要设置的键值的数据类型(本文代码默认REG_SZ,可以根据需求更改)
CONST BYTE *lpData, // 要设置的数据
DWORD cbData // 数据的缓存大小
);
③、RegOpenKeyEx (打开一个新的句柄)
LONG RegOpenKeyEx(
HKEY hKey, // 打开注册表项的句柄。
LPCTSTR lpSubKey, // 子项,此功能打开或创建子键。
DWORD ulOptions, // 为零
REGSAM samDesired, // 定义访问权限,不同权限可能导致无法创建或打开,本文用KEY_ALL_ACCESS
PHKEY phkResult //用于接收句柄的变量指针,该函数运行会为这个变量赋值
);
该函数由hKey参数标识的键打开一个新句柄
④、RegQueryValueEx (查询句柄所关联的值,返回数据)
LONG RegQueryValueEx(
HKEY hKey, // 打开注册表项的句柄。
LPTSTR lpValueName, // 值的名称
LPDWORD lpReserved, // 为0
LPDWORD lpType, // 可以为null
LPBYTE lpData, // 用于接收查询到的值的变量
LPDWORD lpcbData // 数据的缓存大小
);
⑤、RegDeleteValue (根据句柄删除关联的值)
LONG RegDeleteValue (
HKEY hKey, //打开注册表项的句柄。
LPCWSTR lpValueName //要删除的值的名称
);
以上函数成功运行返回值为ERROR_SUCCESS,否则返回非零的数值
RegSetValueEx、RegQueryValueEx、RegDeleteValue的使用都要求先打开句柄(子键)
三、主要代码
①头文件
#include <stdio.h>
#include <Windows.h>
②创建和修改注册表值与数据
如果路径不存在会自动创建
void CreateReg(HKEY RootKey,const char* SubKey,const char* Valuename,const char* Data)
{
HKEY hKey;//句柄
//创建值
long CReg = RegCreateKeyEx(RootKey,SubKey,0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hKey,NULL);
if (CReg == ERROR_SUCCESS)
{
//设置值的数据
printf("设置值与数据为(值:数据):\n%s:%s\n", Valuename,Data);
long SRet = RegSetValueEx(hKey,Valuename, 0, REG_SZ, (BYTE*)Data, strlen(Data));
if (SRet == ERROR_SUCCESS)
{
printf("设置成功!\n");
}
}
RegCloseKey(hKey);
getchar();
return;
}
③查询注册表中子健的值的数据
查询返回值的数据保存在buf中。
void QueryReg(HKEY RootKey,const char* SubKey,const char* Valuename){
HKEY hKey;//句柄
DWORD size=ULONG_MAX; //数据缓存大小地址
char buf[UCHAR_MAX]; //数据缓存地址
long ORet = RegOpenKeyEx(RootKey,SubKey,0,KEY_ALL_ACCESS,&hKey);
if (ORet != ERROR_SUCCESS){
printf("无效的路径:%s-%s\n",SubKey,Valuename);
return;
}else{
long QRet = RegQueryValueEx(hKey,Valuename,0,NULL,(BYTE*)buf, &size);
printf("查询结果(值:数据):\n%s:%s\n",Valuename,buf);
RegCloseKey(hKey);
getchar();
return;
}
}
④删除注册表中子键的值,不存在则退出
对单个值进行删除操作,当然也有直接删除子键的方法。
void DeleteReg(HKEY RootKey,const char* SubKey,const char* Valuename){
HKEY hKey;//句柄
long ORet = RegOpenKeyEx(RootKey,SubKey,0,KEY_ALL_ACCESS,&hKey);
if (ORet != ERROR_SUCCESS){
printf("无效的路径:%s-%s\n",SubKey,Valuename);
return;
}else{
// long DReg = RegDeleteKey(RootKey,SubKey); //直接删除子键(要求子键下面没有其他子键)
long DReg = RegDeleteValue(hKey,Valuename);
if (DReg == ERROR_SUCCESS){
printf("删除成功\n");
}
RegCloseKey(hKey);
getchar();
return;
}
}
⑤主函数
可以根据需求更改参数数据,参数有对应的解释。
int main(int argc,char *argv[])
{
//创建或修改值与数据
//CreateReg(根键,子键,值,数据);
CreateReg(HKEY_CURRENT_USER,"SOFTWARE\\1demo\\cs","vlauename","data");
//查询值的数据
//QueryReg(根键,子键,值);
QueryReg(HKEY_CURRENT_USER,"SOFTWARE\\1demo\\cs","vlauename");
//删除值
//DeleteReg(根键,子键,值);
DeleteReg(HKEY_CURRENT_USER,"SOFTWARE\\1demo\\cs","vlauename");
return 0;
}
四、实现效果
①注册表初始状态
![]()
②执行CreateReg方法创建
![]()
③执行QueryReg方法查询
![]()
④执行DeleteReg方法删除
![]()
文章参考
玩转注册表,这几个windowsAPI函数就够了
C语言对注册表的简单操作
本文旨在用C实现简单的注册表操作,并作为模板方便改写使用,本人学识浅薄,第一次做博客,理解的不够深入,代码比较粗糙,还请见谅。
END 😃