[Win32] 注册表操作(1)基本操作和创建开机自启动

时间:2022-09-04 16:05:23
本文由CSDN用户zuishikonghuan所作,转载请注明出处:http://blog.csdn.net/zuishikonghuan/article/details/46967369

想必注册表大家都不陌生,微软自然也提供了注册表操作的API,通过这些API,我们可以修改注册表达到很多目的,比如添加关联,修改系统设置等。

注意:绝大多数的注册表键的ACL都是不允许标准用户权限的程序写入的,因此,请使用管理员权限运行程序。

一。基本感念:

1。键(项),值项

注册表编辑器左侧的那些文件树中的每个都叫“键”(也叫项),右侧的那些叫值项(也可叫“键值”)。

子键(子项):一个键下面的分支

2。数据类型:

REG_SZ:字符串
REG_MULTI_SZ:多字符串
REG_BINARY :二进制数
REG_DWORD :这个就不用我说了吧,看名字就知道是DWORD
(typedef unsigned long DWORD;)

更多数据类型参见MSDN:https://msdn.microsoft.com/en-us/library/windows/desktop/ms724884(v=vs.85).aspx

二。关于WOW64的问题:

32位程序运行在64位系统上操作注册表会出现问题,在下面会有说明。

三。创建注册表键

MSDN:https://msdn.microsoft.com/en-us/library/windows/desktop/ms724844(v=vs.85).aspx

函数原型:

LONG WINAPI RegCreateKeyEx(
_In_ HKEY hKey,
_In_ LPCTSTR lpSubKey,
_Reserved_ DWORD Reserved,
_In_opt_ LPTSTR lpClass,
_In_ DWORD dwOptions,
_In_ REGSAM samDesired,
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
_Out_ PHKEY phkResult,
_Out_opt_ LPDWORD lpdwDisposition
);

提示:这个也可以用来打开一项。

hKey:要打开键的句柄或以下预定义句柄
HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

lpSubKey:要创建的子键的名称

Reserved:必须为0

lpClass:置NULL

dwOptions:一般用不到,为0即可

samDesired:访问权限,创建一般用不到,为0即可;打开的权限参见“四。打开注册表键”(对于64位系统上运行的32位程序,即WOW64环境,此参数应该有KEY_WOW64_64KEY,才能正常访问注册表,可以使用一个叫IsWow64Process的函数判断当前环境是否为WOW64

lpSecurityAttributes: 确定是否可以由子进程继承返回的句柄的SECURITY_ATTRIBUTES 结构的指针。如果 lpSecurityAttributes 为 NULL,该句柄不能被继承。
一般置NULL即可

phkResult:一个用于接收句柄的指针

lpdwDisposition:一个用于接收结果的指针
可能的结果有:REG_CREATED_NEW_KEY创建成功;REG_OPENED_EXISTING_KEY:键已存在

返回值:成功返回ERROR_SUCCESS

四。打开注册表键

MSDN:https://msdn.microsoft.com/en-us/library/windows/desktop/ms724897(v=vs.85).aspx

函数原型:

LONG WINAPI RegOpenKeyEx(
_In_ HKEY hKey,
_In_opt_ LPCTSTR lpSubKey,
_In_ DWORD ulOptions,
_In_ REGSAM samDesired,
_Out_ PHKEY phkResult
);

hKey:要打开键的句柄或以下预定义句柄
HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

lpSubKey:要打开的子键的名称

ulOptions:一般为0

samDesired:访问权限(对于64位系统上运行的32位程序,即WOW64环境,此参数应该具有KEY_WOW64_64KEY,才能正常访问注册表,可以使用一个叫IsWow64Process的函数判断当前环境是否为WOW64

KEY_ALL_ACCESS:所有权限
KEY_CREATE_SUB_KEY:需要创建注册表项的子项。
KEY_ENUMERATE_SUB_KEYS:所需枚举注册表项的子项。
KEY_EXECUTE:相当于 KEY_READ。
KEY_NOTIFY:所需要求更改通知的某个注册表项或注册表项的子项。
KEY_QUERY_VALUE:所需查询注册表项的值。
KEY_READ:结合STANDARD_RIGHTS_READ、 KEY_QUERY_VALUE、 KEY_ENUMERATE_SUB_KEYS 和 KEY_NOTIFY
KEY_SET_VALUE:需要创建、 删除或设置注册表值。
KEY_WRITE:结合STANDARD_RIGHTS_WRITE、KEY_SET_VALUE 和 KEY_CREATE_SUB_KEY

phkResult:一个用于接收句柄的指针

返回值:成功返回ERROR_SUCCESS

五。删除注册表键

MSDN:https://msdn.microsoft.com/en-us/library/windows/desktop/ms724845(v=vs.85).aspx

函数原型:

LONG WINAPI RegDeleteKey(
_In_ HKEY hKey,
_In_ LPCTSTR lpSubKey
);

hKey:要删除键的句柄或以下预定义句柄
HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

lpSubKey:要删除的子键的名称

返回值:成功返回ERROR_SUCCESS

六。创建/修改值项

MSDN:https://msdn.microsoft.com/en-us/library/windows/desktop/ms724923(v=vs.85).aspx

函数原型:

LONG WINAPI RegSetValueEx(
_In_ HKEY hKey,
_In_opt_ LPCTSTR lpValueName,
_Reserved_ DWORD Reserved,
_In_ DWORD dwType,
_In_ const BYTE *lpData,
_In_ DWORD cbData
);

hKey:要打开键的句柄或以下预定义句柄
HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

lpValueName:要创建、打开的键值的名称

Reserved:必须为0

dwType:数据类型(参见上面的说明)

lpData:要存储的数据。对于基于字符串的类型,例如 REG_SZ,字符串必须是 null 终止。与 REG_MULTI_SZ 数据类型,字符串必须终止与两个 null 字符。

cbData:指 lpData 参数,以字节为单位的信息的大小。如果数据类型为 REG_SZ,REG_EXPAND_SZ 或 REG_MULTI_SZ,cbData 必须包括终止 null 字符或字符的大小。

返回值:成功返回ERROR_SUCCESS

七。读取值项

MSDN:https://msdn.microsoft.com/en-us/library/windows/desktop/ms724911(v=vs.85).aspx

函数原型:

LONG WINAPI RegQueryValueEx(
_In_ HKEY hKey,
_In_opt_ LPCTSTR lpValueName,
_Reserved_ LPDWORD lpReserved,
_Out_opt_ LPDWORD lpType,
_Out_opt_ LPBYTE lpData,
_Inout_opt_ LPDWORD lpcbData
);

hKey:要读取键的句柄或以下预定义句柄
HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_PERFORMANCE_DATA
HKEY_PERFORMANCE_NLSTEXT
HKEY_PERFORMANCE_TEXT
HKEY_USERS

lpValueName:要读取的键值的名称

lpReserved:必须为NULL

lpType:数据类型(参见上面的说明)

lpData:接收数据的缓冲区指针

lpcbData:要接收的长度

返回值:

如果此函数成功,返回值是ERROR_SUCCESS
如果 lpData 缓冲区太小,无法接收数据,则函数返回ERROR_MORE_DATA
如果 lpValueName 注册表值不存在,则函数返回 ERROR_FILE_NOT_FOUND。

八。删除值项

MSDN:https://msdn.microsoft.com/en-us/library/windows/desktop/ms724851(v=vs.85).aspx

函数原型:

LONG WINAPI RegDeleteValue(
_In_ HKEY hKey,
_In_opt_ LPCTSTR lpValueName
);

hKey:要删除键的句柄或以下预定义句柄
HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

lpValueName:要删除的键值的名称

返回值:成功返回ERROR_SUCCESS

九。关闭句柄

键句柄使用完成后,应使用RegCloseKey关闭句柄,释放资源

MSDN:https://msdn.microsoft.com/en-us/library/windows/desktop/ms724837(v=vs.85).aspx

函数原型:

LONG WINAPI RegCloseKey(
_In_ HKEY hKey
);

hKey:要关闭的键句柄

返回值:成功返回ERROR_SUCCESS

例子:利用注册表实现开机自启动

#include <stdio.h>
#include <windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
LPCTSTR path = TEXT("程序路径");
//判断环境是否为WOW64
BOOL isWOW64;
REGSAM p;
IsWow64Process(GetCurrentProcess(),&isWOW64);
if (isWOW64){
p = KEY_WRITE | KEY_WOW64_64KEY;
}
else{
p = KEY_WRITE;
}
HKEY hKey;
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run"), 0, NULL, 0, p, NULL, &hKey, NULL) != ERROR_SUCCESS){
//失败
return 0;
}
if (RegSetValueEx(hKey, TEXT("这里设置一个你喜欢的值_不能和其他程序重了"), 0, REG_SZ, (BYTE*)path, sizeof(path)*sizeof(TCHAR))!= ERROR_SUCCESS){
//失败
return 0;
}
RegCloseKey(hKey);
return 0;
}

效果图:
[Win32] 注册表操作(1)基本操作和创建开机自启动

[Win32] 注册表操作(1)基本操作和创建开机自启动

(汗,那个QQ游戏是俺老爸装的,俺不玩游戏[Win32] 注册表操作(1)基本操作和创建开机自启动

PS:关于枚举子键和枚举值项的方法,且听下回分解。