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_MACHINEHKEY_CURRENT_USER 等。
  • lpSubKey:指定要创建或打开的子项的名称,这是一个以 null 结尾的字符串。
  • Reserved:保留参数,通常为 0。
  • lpClass:指定子项的类名称,通常可以为 NULL,表示不指定类名称。
  • dwOptions:注册表项选项,通常使用 REG_OPTION_NON_VOLATILE,表示注册表项将在系统重启后保留。还可以使用其他选项,如 REG_OPTION_VOLATILE
  • samDesired:指定对子项的访问权限,例如 KEY_READKEY_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_MACHINEHKEY_CURRENT_USER 等。
  • lpSubKey:指定要打开的注册表子项的名称。这是一个以 null 结尾的字符串。
  • ulOptions:保留参数,通常为 0。
  • samDesired:指定对注册表项的访问权限,通常使用 KEY_READKEY_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_SZREG_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;
}

  

posted @   TechNomad  阅读(543)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示