Win32编程之注册表的相关操作(十四)
一、设置注册表项的值
RegCreateKeyEx函数
RegCreateKeyEx
函数是 Windows API 中的一个函数,用于创建或打开注册表中的一个指定键的子键(子项)。通过该函数,您可以创建新的注册表子项,或者打开现有的子项以进一步操作。
函数原型:
1 2 3 4 5 6 7 8 9 10 11 | LONG RegCreateKeyEx( HKEY hKey, // 指定一个基本注册表项的句柄 LPCTSTR lpSubKey, // 指定要创建或打开的子项的名称 DWORD Reserved, // 保留参数,通常为 0 LPTSTR lpClass, // 指定子项的类名称,可以为 NULL DWORD dwOptions, // 注册表项选项,通常为 REG_OPTION_NON_VOLATILE REGSAM samDesired, // 指定对子项的访问权限 const LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 安全性属性,通常为 NULL PHKEY phkResult, // 接收创建或打开的子项的句柄 LPDWORD lpdwDisposition // 接收操作结果信息,如 REG_CREATED_NEW_KEY 或 REG_OPENED_EXISTING_KEY ); |
参数解释:
hKey
:指定一个基本注册表项的句柄,它是一个HKEY
类型的句柄,用于指定在哪个根注册表项下创建或打开子项。常用的根注册表项包括HKEY_LOCAL_MACHINE
、HKEY_CURRENT_USER
等。lpSubKey
:指定要创建或打开的子项的名称,这是一个以 null 结尾的字符串。Reserved
:保留参数,通常为 0。lpClass
:指定子项的类名称,通常可以为NULL
,表示不指定类名称。dwOptions
:注册表项选项,通常使用REG_OPTION_NON_VOLATILE
,表示注册表项将在系统重启后保留。还可以使用其他选项,如REG_OPTION_VOLATILE
。samDesired
:指定对子项的访问权限,例如KEY_READ
或KEY_WRITE
,以控制对子项的读写权限。lpSecurityAttributes
:安全性属性,通常可以为NULL
,表示不设置安全性属性。phkResult
:指向HKEY
类型的指针,用于接收创建或打开的子项的句柄。lpdwDisposition
:指向DWORD
类型的变量的指针,用于接收操作结果信息,如REG_CREATED_NEW_KEY
表示创建了新的子项,或REG_OPENED_EXISTING_KEY
表示打开了现有的子项。
返回值:
- 如果函数调用成功,返回
ERROR_SUCCESS
(0)。 - 如果函数调用失败,返回一个非零的错误代码,可以使用
FormatMessage
函数来获取错误信息。
函数功能:
RegCreateKeyEx
函数用于创建或打开注册表中的一个指定键下的子项。通过指定键的句柄、子项名称和其他参数,您可以创建新的子项或打开已存在的子项。如果子项已存在,则可以使用 lpdwDisposition
参数来了解是创建了新的子项还是打开了已存在的子项。
RegSetValueEx函数
RegSetValueEx
函数用于设置或创建注册表中指定键的值。通过该函数,您可以将不同类型的数据(如字符串、二进制数据、整数值等)写入到注册表中。
函数原型:
1 2 3 4 5 6 7 8 | LONG RegSetValueEx( HKEY hKey, // 指定一个打开的注册表项的句柄 LPCTSTR lpValueName, // 指定要设置的值的名称 DWORD Reserved, // 保留参数,通常为 0 DWORD dwType, // 指定值的类型,如 REG_SZ、REG_DWORD 等 const BYTE *lpData, // 指向数据的指针 DWORD cbData // 指定数据的大小(字节数) ); |
参数解释:
hKey
:指定一个打开的注册表项的句柄,您可以使用RegOpenKeyEx
函数来打开注册表项。lpValueName
:指定要设置的值的名称,它是一个以 null 结尾的字符串。Reserved
:保留参数,通常为 0。dwType
:指定要设置的值的类型,例如REG_SZ
表示字符串类型、REG_DWORD
表示双字(DWORD)类型等。不同的类型需要使用不同的数据类型和数据格式。lpData
:指向要写入注册表的数据的指针,数据的格式和类型必须与dwType
参数匹配。cbData
:指定数据的大小(字节数),即lpData
缓冲区中要写入的数据的字节数。
返回值:
- 如果函数调用成功,返回
ERROR_SUCCESS
(0)。 - 如果函数调用失败,返回一个非零的错误代码,可以使用
FormatMessage
函数来获取错误信息。
函数功能:
RegSetValueEx
函数用于设置或创建注册表中的一个特定键的值。它允许您将不同类型的数据写入到注册表中,并指定值的类型(dwType
)以及数据(lpData
)的格式。如果指定的键和值名称不存在,它还可以创建它们。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #include <Windows.h> #include <stdio.h> int main() { HKEY hKey; DWORD disposition; // 用于接收操作结果信息 // 打开或创建注册表项 HKEY_CURRENT_USER\Software\MyApp LONG result = RegCreateKeyEx( HKEY_CURRENT_USER, TEXT( "Software\\MyApp" ), 0, NULL, REG_OPTION_NON_VOLATILE, // 表示注册表项将在系统重启后保留 KEY_WRITE, NULL, &hKey, &disposition ); if (result == ERROR_SUCCESS) { if (disposition == REG_CREATED_NEW_KEY) { printf ( "Registry key created.\n" ); const WCHAR * valueName = TEXT( "MyValue" ); const char * valueData = "Hello, Registry!" ; // 设置字符串值 result = RegSetValueEx( hKey, valueName, 0, REG_SZ, ( BYTE *)valueData, strlen (valueData) + 1 // 包括 null 终止符的大小 ); if (result == ERROR_SUCCESS) { printf ( "Registry value set successfully.\n" ); } else { printf ( "Failed to set registry value.\n" ); } } else if (disposition == REG_OPENED_EXISTING_KEY) { printf ( "Registry key opened.\n" ); } // 关闭注册表项句柄 RegCloseKey(hKey); } else { printf ( "Failed to open or create registry key.\n" ); } return 0; } |
二、读取注册表项的值
RegOpenKeyEx函数
RegOpenKeyEx
函数是 Windows API 中的一个函数,用于打开注册表中的一个指定注册表项的句柄。通过该句柄,您可以读取或修改该注册表项中的值和子项。
函数原型:
1 2 3 4 5 6 7 | LONG RegOpenKeyEx( HKEY hKey, // 指定基本注册表项的句柄 LPCTSTR lpSubKey, // 指定要打开的注册表子项的名称 DWORD ulOptions, // 保留参数,通常为 0 REGSAM samDesired, // 指定对注册表项的访问权限 PHKEY phkResult // 接收打开的注册表项的句柄 ); |
参数解释:
hKey
:指定一个基本注册表项的句柄,它是一个HKEY
类型的句柄,用于指定在哪个根注册表项下打开子项。常用的根注册表项包括HKEY_LOCAL_MACHINE
、HKEY_CURRENT_USER
等。lpSubKey
:指定要打开的注册表子项的名称。这是一个以 null 结尾的字符串。ulOptions
:保留参数,通常为 0。samDesired
:指定对注册表项的访问权限,通常使用KEY_READ
或KEY_WRITE
。您可以使用不同的访问权限标志来控制读取、写入和修改注册表的权限。phkResult
:指向HKEY
类型的指针,用于接收打开的注册表项的句柄。
返回值:
- 如果函数调用成功,返回
ERROR_SUCCESS
(0),并且phkResult
包含打开的注册表项的句柄。 - 如果函数调用失败,返回一个非零的错误代码,可以使用
FormatMessage
函数来获取错误信息。
函数功能:
RegOpenKeyEx
函数用于打开指定注册表项的句柄,以便对其进行读取或修改操作。通过该句柄,您可以执行以下操作:
- 使用
RegQueryValueEx
函数来读取注册表项的值。 - 使用
RegSetValueEx
函数来设置注册表项的值。 - 使用
RegDeleteValue
函数来删除注册表项的值。 - 使用
RegEnumKeyEx
函数来列举子项。
RegQueryValueEx函数
RegQueryValueEx
函数用于读取注册表中指定键的值。通过该函数,您可以检索注册表项中的字符串、二进制数据、整数值等不同类型的数据
函数原型:
1 2 3 4 5 6 7 8 | LONG RegQueryValueEx( HKEY hKey, // 指定一个打开的注册表项的句柄 LPCTSTR lpValueName, // 指定要检索的值的名称 LPDWORD lpReserved, // 保留参数,通常为 NULL LPDWORD lpType, // 用于接收值的类型 LPBYTE lpData, // 用于接收值数据的缓冲区 LPDWORD lpcbData // 指定缓冲区大小,接收数据的字节数 ); |
参数解释:
hKey
:指定一个打开的注册表项的句柄,您可以使用RegOpenKeyEx
函数来打开注册表项。lpValueName
:指定要检索的值的名称,它是一个以 null 结尾的字符串。lpReserved
:保留参数,通常为NULL
。lpType
:一个指向DWORD
类型的变量的指针,用于接收值的类型,例如REG_SZ
、REG_DWORD
等。lpData
:一个指向缓冲区的指针,用于接收检索到的值的数据。lpcbData
:一个指向DWORD
类型的变量的指针,用于指定lpData
缓冲区的大小,以接收检索到的数据的字节数。
返回值:
- 如果函数调用成功,返回
ERROR_SUCCESS
(0),并且lpData
缓冲区中包含检索到的数据。 - 如果函数调用失败,返回一个非零的错误代码,可以使用
FormatMessage
函数来获取错误信息。
函数功能:
RegQueryValueEx
函数用于从指定的注册表项中读取一个特定值的数据。它根据提供的注册表键和值的名称,将相应的数据检索到 lpData
缓冲区中,并通过 lpType
指针返回数据的类型。此函数可以用于读取字符串、二进制数据、整数等不同类型的值。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | #include <Windows.h> #include <stdio.h> int main() { HKEY hKey; DWORD dwType; DWORD dwSize = MAX_PATH; char value[MAX_PATH]; // 打开注册表项 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion LONG result = RegOpenKeyEx( HKEY_CURRENT_USER, TEXT( "Software\\MyApp" ), 0, KEY_READ, &hKey ); if (result == ERROR_SUCCESS) { // 读取注册表项的 "MyValue" 值 result = RegQueryValueEx( hKey, TEXT( "MyValue" ), NULL, &dwType, ( LPBYTE )value, &dwSize ); if (result == ERROR_SUCCESS && dwType == REG_SZ) { printf ( "Program Files Directory: %s\n" , value); } else { printf ( "Failed to read registry value.\n" ); } // 关闭注册表项句柄 RegCloseKey(hKey); } else { printf ( "Failed to open registry key.\n" ); } return 0; } |
三、删除注册表项的值
RegDeleteValue函数
RegDeleteValue
函数用于删除注册表中指定键的特定值。通过该函数,您可以删除注册表中的一个值,以清除不再需要的注册表数据
函数原型:
1 2 3 4 | LONG RegDeleteValue( HKEY hKey, // 指定一个打开的注册表项的句柄 LPCTSTR lpValueName // 指定要删除的值的名称 ); |
参数解释:
hKey
:指定一个打开的注册表项的句柄,您可以使用RegOpenKeyEx
函数来打开注册表项。lpValueName
:指定要删除的值的名称,它是一个以 null 结尾的字符串。
返回值:
- 如果函数调用成功,返回
ERROR_SUCCESS
(0)。 - 如果函数调用失败,返回一个非零的错误代码,可以使用
FormatMessage
函数来获取错误信息。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #include <Windows.h> #include <stdio.h> int main() { HKEY hKey; // 打开注册表项 HKEY_CURRENT_USER\Software\MyApp LONG result = RegOpenKeyEx( HKEY_CURRENT_USER, TEXT( "Software\\MyApp" ), 0, KEY_WRITE, &hKey ); if (result == ERROR_SUCCESS) { const TCHAR * valueName = TEXT( "MyValue" ); // 删除指定值 result = RegDeleteValue(hKey, valueName); if (result == ERROR_SUCCESS) { printf ( "Registry value deleted successfully.\n" ); } else if (result == ERROR_FILE_NOT_FOUND) { printf ( "Registry value not found.\n" ); } else { printf ( "Failed to delete registry value.\n" ); } // 关闭注册表项句柄 RegCloseKey(hKey); } else { printf ( "Failed to open registry key.\n" ); } return 0; } |
四、列举指定注册表键下的子键(子项)的名称
RegEnumKeyEx函数
RegEnumKeyEx
函数是用于列举指定注册表键下的子键(子项)的名称。通过该函数,您可以获取注册表项的子项列表,以便进一步处理或检查
函数原型:
1 2 3 4 5 6 7 8 9 10 | LONG RegEnumKeyEx( HKEY hKey, // 指定一个打开的注册表项的句柄 DWORD dwIndex, // 指定要检索的子项的索引 LPTSTR lpName, // 用于接收子项名称的缓冲区 LPDWORD lpcName, // 接收子项名称的缓冲区大小(字符数) LPDWORD lpReserved, // 保留参数,通常为 NULL LPTSTR lpClass, // 用于接收子项的类名称的缓冲区 LPDWORD lpcClass, // 接收类名称的缓冲区大小(字符数) PFILETIME lpftLastWriteTime // 接收子项的最后写入时间 ); |
参数解释:
hKey
:指定一个打开的注册表项的句柄,您可以使用RegOpenKeyEx
函数来打开注册表项。dwIndex
:指定要检索的子项的索引,从 0 开始计数。lpName
:指向接收子项名称的缓冲区的指针。lpcName
:指向一个DWORD
类型的变量的指针,用于指定lpName
缓冲区的大小(字符数)。lpReserved
:保留参数,通常为NULL
。lpClass
:指向接收子项的类名称的缓冲区的指针。可以为NULL
。lpcClass
:指向一个DWORD
类型的变量的指针,用于指定lpClass
缓冲区的大小(字符数)。lpftLastWriteTime
:指向FILETIME
结构的指针,用于接收子项的最后写入时间。可以为NULL
。
返回值:
- 如果函数调用成功,返回
ERROR_SUCCESS
(0)。 - 如果函数调用失败,返回一个非零的错误代码,可以使用
FormatMessage
函数来获取错误信息。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #include <Windows.h> #include <stdio.h> int main() { HKEY hKey; DWORD index = 0; TCHAR subkeyName[MAX_PATH]; DWORD subkeyNameSize = MAX_PATH; // 打开注册表项 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion LONG result = RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT( "SOFTWARE\\Microsoft\\Windows\\CurrentVersion" ), 0, KEY_READ, &hKey ); if (result == ERROR_SUCCESS) { printf ( "Subkeys under HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion:\n" ); // 枚举子项名称 while ( true ) { result = RegEnumKeyEx( hKey, index, subkeyName, &subkeyNameSize, NULL, NULL, NULL, NULL ); if (result == ERROR_SUCCESS) { //printf("%s\n", subkeyName); wprintf(L "%s\n" , subkeyName); index++; subkeyNameSize = MAX_PATH; } else if (result == ERROR_NO_MORE_ITEMS) { // 所有子项都已枚举完毕 break ; } else { printf ( "Failed to enumerate subkey.\n" ); break ; } } // 关闭注册表项句柄 RegCloseKey(hKey); } else { printf ( "Failed to open registry key.\n" ); } return 0; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?