注册表和文件的操作差不多,也存在打开,关闭,写入,查询等操作,使用的所有API函数皆以Reg开头。
1. 打开和关闭注册表
对注册表操作前,需通过API函数打开注册表,并返回用于操作注册表的句柄,通过此句柄,来对注册表进行读写操作。
打开注册表
LONG RegOpenKeyEx(
HKEY hKey, // handle to open key
LPCTSTR lpSubKey, // address of name of subkey to open
DWORD ulOptions, // reserved
REGSAM samDesired, // security access mask
PHKEY phkResult // address of handle to open key
);
LONG RegOpenKeyEx(
HKEY hKey, // handle to open key
LPCTSTR lpSubKey, // address of name of subkey to open
DWORD ulOptions, // reserved
REGSAM samDesired, // security access mask
PHKEY phkResult // address of handle to open key
);
在Win16下,还有一个RegOpenKey()函数,如今虽仍可使用,但RegOpenKeyEx()兼容性更好。
打开注册表,实质是打开注册表的某一个子键,然后进行操作。
参数说明:
- hKey:指定一个父键句柄。
- lpSubKey:指向一个字符串,用来表示要打开的子键名称。
- ulOptions:系统保留,必须为0。
- samDesired:打开注册表的存取权限,通常为KEY_ALL_ACCESS。
- phkResult:指向一个双子变量,用来接收打开的子键句柄。
Return Value:
- succeed:返回ERROR_SUCCEDD,并在phkResult中保存返回打开子键的句柄。
操作完注册表后,也需要关闭句柄以释放资源。函数如下:
LONG RegCloseKey(
HKEY hKey //handle to key to close
);
LONG RegCloseKey(
HKEY hKey //handle to key to close
);
2. 创建和删除子键
创建子键
LONG RegCreateKeyEx(
HKEY hKey, // handle to an open key
LPCTSTR lpSubKey, // address of subkey name
DWORD Reserved, // reserved
LPTSTR lpClass, // address of class string
DWORD dwOptions, // special options flag
REGSAM samDesired, // desired security access
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
// address of key security structure
PHKEY phkResult, // address of buffer for opened handle
LPDWORD lpdwDisposition // address of disposition value buffer
);
LONG RegCreateKeyEx(
HKEY hKey, // handle to an open key
LPCTSTR lpSubKey, // address of subkey name
DWORD Reserved, // reserved
LPTSTR lpClass, // address of class string
DWORD dwOptions, // special options flag
REGSAM samDesired, // desired security access
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
// address of key security structure
PHKEY phkResult, // address of buffer for opened handle
LPDWORD lpdwDisposition // address of disposition value buffer
);
当需要创建的子键以存在时,该函数与RegOpenKeyEx()函数的作用相同。
参数说明:
- hKey:指定父键句柄。
- lpSubKey:指向一个字符串,用来表示要打开的子键名称。
- Reserved:系统保留,必须为0。
- lpClass:子键类名,常为NULL。
- dwOptions:创建子键时的选项,通常使用REG_OPTION_NON_VOLATILE,表示创建的子键被创建到注册表文件中,而非内存。
- samDesired:打开注册表的存取权限,通常为KEY_ALL_ACCESS即可。
- lpSecurityAttributes:指向一个SECURITY_ATTRIBUTES结构体,用来指定安全属性,常为NULL。
- phkResult:指向一个双子变量,用来接收打开的子键句柄。
- lpdwDisposition:常为NULL。
Return Value:
- succeed:返回ERROR_SUCCESS,并在phkResult中保存返回创建子键的句柄。
删除子键
LONG RegDeleteKey(
HKEY hKey, //父键句柄
LPCTSTR lpSubKey //指向要删除的子键名称字符串
);
LONG RegDeleteKey(
HKEY hKey, //父键句柄
LPCTSTR lpSubKey //指向要删除的子键名称字符串
);
该函数的值能用来删除键值项,即函数只能删除最下一层的子键。
3. 查询、写入与删除
读取键名称中的数据或查询键名称的属性,使用此函数:
LONG RegQueryValueEx(
HKEY hKey, // handle to key to query
LPTSTR lpValueName, // address of name of value to query
LPDWORD lpReserved, // reserved
LPDWORD lpType, // address of buffer for value type
LPBYTE lpData, // address of data buffer
LPDWORD lpcbData // address of data buffer size
);
LONG RegQueryValueEx(
HKEY hKey, // handle to key to query
LPTSTR lpValueName, // address of name of value to query
LPDWORD lpReserved, // reserved
LPDWORD lpType, // address of buffer for value type
LPBYTE lpData, // address of data buffer
LPDWORD lpcbData // address of data buffer size
);
参数说明:
- hKey:指定要读取的键值项所处的子键句柄。
- lpValueName:指定要读取的键值项的名称。
- lpReserved:保留,常为NULL。
- lpType:接收返回的键值类型,若不需返回键值类型,可为NULL。
- lpData:指向一个缓冲区,用来接收返回的键值数据。
- lpcbData:调用该函数时,此参数用来指定缓冲区的长度;函数返回时,该变量保存缓冲区实际接收到的长度。
写入键值项
LONG RegSetValueEx(
HKEY hKey, // handle to key to set value for
LPCTSTR lpValueName, // name of the value to set
DWORD Reserved, // reserved
DWORD dwType, // flag for value type
CONST BYTE *lpData, // address of value data
DWORD cbData // size of value data
);
LONG RegSetValueEx(
HKEY hKey, // handle to key to set value for
LPCTSTR lpValueName, // name of the value to set
DWORD Reserved, // reserved
DWORD dwType, // flag for value type
CONST BYTE *lpData, // address of value data
DWORD cbData // size of value data
);
参数说明:
- hKey:指定要写入的键值所处的子键句柄。
- lpValueName:指向定义键值项名称的字符串。
- Reserved:保留,必须为0.
- dwType:要写入的键值数据的类型。
- lpData:要写入键值数据的缓冲区。
- cbData:要写入键值数据的缓冲区长度。
删除键值项
LONG RegDeleteValue(
HEKY hKey, //指定删除的句柄
LPCTSTR lpValueName //被删除键值项的名称
);
LONG RegDeleteValue(
HEKY hKey, //指定删除的句柄
LPCTSTR lpValueName //被删除键值项的名称
);
4. 子键和键值的枚举
枚举即逐一获取。子键的枚举对指定键下的子键进行逐一获取。键值的枚举是对指定子键下的键值进行逐一获取。
枚举子键
LONG RegEnumKeyEx(
HKEY hKey, // handle to key to enumerate
DWORD dwIndex, // index of subkey to enumerate
LPTSTR lpName, // address of buffer for subkey name
LPDWORD lpcbName, // address for size of subkey buffer
LPDWORD lpReserved, // reserved
LPTSTR lpClass, // address of buffer for class string
LPDWORD lpcbClass, // address for size of class buffer
PFILETIME lpftLastWriteTime
// address for time key last written to
);
LONG RegEnumKeyEx(
HKEY hKey, // handle to key to enumerate
DWORD dwIndex, // index of subkey to enumerate
LPTSTR lpName, // address of buffer for subkey name
LPDWORD lpcbName, // address for size of subkey buffer
LPDWORD lpReserved, // reserved
LPTSTR lpClass, // address of buffer for class string
LPDWORD lpcbClass, // address for size of class buffer
PFILETIME lpftLastWriteTime
// address for time key last written to
);
参数说明:
- hKey:指定被枚举的键句柄。
- dwIndex:指定需要返回信息的子键索引编号。
- lpName:用户接收返回子键名称的缓冲区。
- lpcName:调用该函数前,该参数保存lpName指向缓冲区的长度;调用完成后,该参数保存缓冲区实际接收到的数据的长度。
- lpReserved:保存参数,必须为NULL。
- lpClass:一般为NULL。
- lpcbClass:一般为NULL。
- lpftLastWriteTime:指向一个FILETIME结构体,用于接收最后一次被写入的时间。
枚举键值
LONG RegEnumValue(
HKEY hKey, // handle to key to query
DWORD dwIndex, // index of value to query
LPTSTR lpValueName, // address of buffer for value string
LPDWORD lpcbValueName, // address for size of value buffer
LPDWORD lpReserved, // reserved
LPDWORD lpType, // address of buffer for type code
LPBYTE lpData, // address of buffer for value data
LPDWORD lpcbData // address for size of data buffer
);
LONG RegEnumValue(
HKEY hKey, // handle to key to query
DWORD dwIndex, // index of value to query
LPTSTR lpValueName, // address of buffer for value string
LPDWORD lpcbValueName, // address for size of value buffer
LPDWORD lpReserved, // reserved
LPDWORD lpType, // address of buffer for type code
LPBYTE lpData, // address of buffer for value data
LPDWORD lpcbData // address for size of data buffer
);
参数说明:
- hKey:指定被枚举的键句柄。
- dwIndex:指定需要返回信息的键值索引编号。
- lpValueName:用户接收返回键值名称的缓冲区。
- lpcbValueName:调用前,保存lpValueName指向缓冲区的长度;调用后,保存缓冲区实际接收到的数据的长度。
- lpReserved:保存参数,必须为NULL。
- lpType:指向一个用于返回键值数据类型的双字变量。
- lpData:用户接收返回键值数据的缓冲区。
- lpcbData:调用前,保存lpData指向缓冲区的长度;调用后,保存实际收到的数据的长度。
5. 示例程序
#include <Windows.h>
#include <iostream>
#include <iomanip>
int main()
{
char szValueName[MAXBYTE] = { 0 };
char szValueKey[MAXBYTE] = { 0 };
DWORD dwBufferSize = MAXBYTE;
DWORD dwKeySize = MAXBYTE;
DWORD dwType = 0;
HKEY hKey = NULL;
char subKeyName[] = "Software\\Microsoft\\Windows\\CurrentVersion\\";
LONG lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, subKeyName, 0, KEY_ALL_ACCESS, &hKey);
if (lRet != ERROR_SUCCESS)
{
std::cout << "ERROR:打开注册表失败,可能是因为没有提供管理员权限。";
return -1;
}
int i = 0;
while (TRUE)
{
lRet = RegEnumValue(hKey, i, szValueName, &dwBufferSize, NULL, &dwType, reinterpret_cast<LPBYTE>(szValueKey), &dwKeySize);
if (lRet == ERROR_NO_MORE_ITEMS)
{
break;
}
std::cout << i << " " << std::setw(30) <<szValueName << " " << std::setw(50) << szValueKey << std::endl;
ZeroMemory(szValueKey, MAXBYTE);
ZeroMemory(szValueName, MAXBYTE);
dwBufferSize = MAXBYTE;
dwKeySize = MAXBYTE;
i++;
}
RegCloseKey(hKey);
return 0;
}
#include <Windows.h>
#include <iostream>
#include <iomanip>
int main()
{
char szValueName[MAXBYTE] = { 0 };
char szValueKey[MAXBYTE] = { 0 };
DWORD dwBufferSize = MAXBYTE;
DWORD dwKeySize = MAXBYTE;
DWORD dwType = 0;
HKEY hKey = NULL;
char subKeyName[] = "Software\\Microsoft\\Windows\\CurrentVersion\\";
LONG lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, subKeyName, 0, KEY_ALL_ACCESS, &hKey);
if (lRet != ERROR_SUCCESS)
{
std::cout << "ERROR:打开注册表失败,可能是因为没有提供管理员权限。";
return -1;
}
int i = 0;
while (TRUE)
{
lRet = RegEnumValue(hKey, i, szValueName, &dwBufferSize, NULL, &dwType, reinterpret_cast<LPBYTE>(szValueKey), &dwKeySize);
if (lRet == ERROR_NO_MORE_ITEMS)
{
break;
}
std::cout << i << " " << std::setw(30) <<szValueName << " " << std::setw(50) << szValueKey << std::endl;
ZeroMemory(szValueKey, MAXBYTE);
ZeroMemory(szValueName, MAXBYTE);
dwBufferSize = MAXBYTE;
dwKeySize = MAXBYTE;
i++;
}
RegCloseKey(hKey);
return 0;
}
Output:
0 CommonFilesDir C:\Program Files (x86)\Common Files
1 CommonFilesDir (x86) C:\Program Files (x86)\Common Files
2 CommonW6432Dir C:\Program Files\Common Files
3 DevicePath %SystemRoot%\inf
4 MediaPathUnexpanded %SystemRoot%\Media
5 ProgramFilesDir C:\Program Files (x86)
6 ProgramFilesDir (x86) C:\Program Files (x86)
7 ProgramFilesPath %ProgramFiles%
8 ProgramW6432Dir C:\Program Files
9 SM_ConfigureProgramsName Set Program Access and Defaults
10 SM_GamesName Games
0 CommonFilesDir C:\Program Files (x86)\Common Files
1 CommonFilesDir (x86) C:\Program Files (x86)\Common Files
2 CommonW6432Dir C:\Program Files\Common Files
3 DevicePath %SystemRoot%\inf
4 MediaPathUnexpanded %SystemRoot%\Media
5 ProgramFilesDir C:\Program Files (x86)
6 ProgramFilesDir (x86) C:\Program Files (x86)
7 ProgramFilesPath %ProgramFiles%
8 ProgramW6432Dir C:\Program Files
9 SM_ConfigureProgramsName Set Program Access and Defaults
10 SM_GamesName Games