跳转至

注册表操作API

概述

注册表是Windows存储配置信息的层次数据库。Windows API提供了完整的注册表操作函数。

打开和关闭注册表键

RegOpenKeyEx - 打开注册表键

C++
1
2
3
4
5
6
7
LSTATUS RegOpenKeyEx(
    HKEY    hKey,         // 根键句柄
    LPCSTR  lpSubKey,     // 子键路径
    DWORD   ulOptions,    // 保留,必须为0
    REGSAM  samDesired,   // 访问权限
    PHKEY   phkResult     // 接收键句柄
);

根键句柄: - HKEY_CLASSES_ROOT - HKEY_CURRENT_USER - HKEY_LOCAL_MACHINE - HKEY_USERS - HKEY_CURRENT_CONFIG

访问权限: - KEY_READ:读取权限 - KEY_WRITE:写入权限 - KEY_EXECUTE:执行权限 - KEY_ALL_ACCESS:所有权限 - KEY_QUERY_VALUE:查询值 - KEY_SET_VALUE:设置值 - KEY_CREATE_SUB_KEY:创建子键 - KEY_ENUMERATE_SUB_KEYS:枚举子键

示例

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

int main() {
    HKEY hKey;
    LSTATUS status = RegOpenKeyEx(
        HKEY_LOCAL_MACHINE,
        L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
        0,
        KEY_READ,
        &hKey
    );
    
    if (status == ERROR_SUCCESS) {
        printf("Key opened successfully\n");
        RegCloseKey(hKey);
    } else {
        printf("RegOpenKeyEx failed: %d\n", status);
    }
    
    return 0;
}

RegCloseKey - 关闭注册表键

C++
1
2
3
LSTATUS RegCloseKey(
    HKEY hKey
);

创建和删除键

RegCreateKeyEx - 创建注册表键

C++
LSTATUS RegCreateKeyEx(
    HKEY                  hKey,
    LPCSTR                lpSubKey,
    DWORD                 Reserved,
    LPSTR                 lpClass,
    DWORD                 dwOptions,
    REGSAM                samDesired,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    PHKEY                 phkResult,
    LPDWORD               lpdwDisposition
);

选项: - REG_OPTION_NON_VOLATILE:非易失(默认) - REG_OPTION_VOLATILE:易失(重启后消失) - REG_OPTION_CREATE_LINK:创建符号链接 - REG_OPTION_BACKUP_RESTORE:备份还原权限

返回状态: - REG_CREATED_NEW_KEY:创建了新键 - REG_OPENED_EXISTING_KEY:打开了现有键

示例

C++
HKEY hKey;
DWORD disposition;
LSTATUS status = RegCreateKeyEx(
    HKEY_CURRENT_USER,
    L"SOFTWARE\\MyApp",
    0, NULL,
    REG_OPTION_NON_VOLATILE,
    KEY_WRITE,
    NULL,
    &hKey,
    &disposition
);

if (status == ERROR_SUCCESS) {
    if (disposition == REG_CREATED_NEW_KEY) {
        printf("New key created\n");
    } else {
        printf("Existing key opened\n");
    }
    RegCloseKey(hKey);
}

RegDeleteKey - 删除注册表键

C++
1
2
3
4
LSTATUS RegDeleteKey(
    HKEY    hKey,
    LPCSTR  lpSubKey
);

示例

C++
RegDeleteKey(HKEY_CURRENT_USER, L"SOFTWARE\\MyApp");

RegDeleteKeyEx - 扩展删除键

C++
1
2
3
4
5
6
LSTATUS RegDeleteKeyEx(
    HKEY    hKey,
    LPCSTR  lpSubKey,
    REGSAM  samDesired,
    DWORD   Reserved
);

RegDeleteTree - 删除键树

C++
1
2
3
4
LSTATUS RegDeleteTree(
    HKEY    hKey,
    LPCSTR  lpSubKey
);

读取值

RegQueryValueEx - 查询注册表值

C++
1
2
3
4
5
6
7
8
LSTATUS RegQueryValueEx(
    HKEY    hKey,
    LPCSTR  lpValueName,
    LPDWORD lpReserved,
    LPDWORD lpType,
    LPBYTE  lpData,
    LPDWORD lpcbData
);

数据类型: - REG_SZ:字符串 - REG_EXPAND_SZ:可扩展字符串 - REG_MULTI_SZ:多字符串 - REG_DWORD:32位整数 - REG_QWORD:64位整数 - REG_BINARY:二进制数据 - REG_NONE:无类型

示例

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

int main() {
    HKEY hKey;
    LSTATUS status = RegOpenKeyEx(
        HKEY_LOCAL_MACHINE,
        L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
        0, KEY_READ, &hKey
    );
    
    if (status == ERROR_SUCCESS) {
        // 读取字符串值
        WCHAR value[256];
        DWORD size = sizeof(value);
        DWORD type;
        
        status = RegQueryValueEx(hKey, L"ProductName", NULL, &type, (LPBYTE)value, &size);
        if (status == ERROR_SUCCESS && type == REG_SZ) {
            wprintf(L"ProductName: %s\n", value);
        }
        
        // 读取DWORD值
        DWORD dwordValue;
        size = sizeof(dwordValue);
        status = RegQueryValueEx(hKey, L"MajorVersionNumber", NULL, &type, (LPBYTE)&dwordValue, &size);
        if (status == ERROR_SUCCESS && type == REG_DWORD) {
            printf("Major Version: %d\n", dwordValue);
        }
        
        RegCloseKey(hKey);
    }
    
    return 0;
}

RegGetValue - 获取值(简化版)

C++
1
2
3
4
5
6
7
8
9
LSTATUS RegGetValue(
    HKEY    hkey,
    LPCSTR  lpSubKey,
    LPCSTR  lpValue,
    DWORD   dwFlags,
    LPDWORD pdwType,
    PVOID   pvData,
    LPDWORD pcbData
);

标志: - RRF_RT_REG_SZ:字符串 - RRF_RT_REG_DWORD:DWORD - RRF_RT_REG_BINARY:二进制 - RRF_NOEXPAND:不展开环境变量 - RRF_ZEROONFAILURE:失败时清零缓冲区

示例

C++
1
2
3
4
5
6
7
WCHAR value[256];
DWORD size = sizeof(value);
RegGetValue(HKEY_LOCAL_MACHINE, 
    L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
    L"ProductName",
    RRF_RT_REG_SZ, NULL, value, &size);
wprintf(L"Product: %s\n", value);

写入值

RegSetValueEx - 设置注册表值

C++
1
2
3
4
5
6
7
8
LSTATUS RegSetValueEx(
    HKEY         hKey,
    LPCSTR       lpValueName,
    DWORD        Reserved,
    DWORD        dwType,
    const BYTE   *lpData,
    DWORD        cbData
);

示例

C++
#include <windows.h>

int main() {
    HKEY hKey;
    LSTATUS status = RegCreateKeyEx(
        HKEY_CURRENT_USER,
        L"SOFTWARE\\MyApp",
        0, NULL, REG_OPTION_NON_VOLATILE,
        KEY_WRITE, NULL, &hKey, NULL
    );
    
    if (status == ERROR_SUCCESS) {
        // 设置字符串值
        WCHAR* strValue = L"1.0.0";
        RegSetValueEx(hKey, L"Version", 0, REG_SZ, (LPBYTE)strValue, (wcslen(strValue) + 1) * sizeof(WCHAR));
        
        // 设置DWORD值
        DWORD dwValue = 1;
        RegSetValueEx(hKey, L"Enabled", 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(dwValue));
        
        // 设置二进制值
        BYTE binData[] = {0x01, 0x02, 0x03, 0x04};
        RegSetValueEx(hKey, L"Data", 0, REG_BINARY, binData, sizeof(binData));
        
        // 设置可展开字符串
        WCHAR* expandValue = L"%SystemRoot%\\System32";
        RegSetValueEx(hKey, L"Path", 0, REG_EXPAND_SZ, (LPBYTE)expandValue, (wcslen(expandValue) + 1) * sizeof(WCHAR));
        
        RegCloseKey(hKey);
    }
    
    return 0;
}

RegDeleteValue - 删除注册表值

C++
1
2
3
4
LSTATUS RegDeleteValue(
    HKEY    hKey,
    LPCSTR  lpValueName
);

示例

C++
RegDeleteValue(hKey, L"Version");

枚举键和值

RegEnumKeyEx - 枚举子键

C++
LSTATUS RegEnumKeyEx(
    HKEY      hKey,
    DWORD     dwIndex,
    LPSTR     lpName,
    LPDWORD   lpcchName,
    LPDWORD   lpReserved,
    LPSTR     lpClass,
    LPDWORD   lpcchClass,
    PFILETIME lpftLastWriteTime
);

示例

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

void EnumSubKeys(HKEY hKey) {
    WCHAR name[256];
    DWORD nameSize;
    DWORD index = 0;
    
    while (true) {
        nameSize = sizeof(name) / sizeof(WCHAR);
        LSTATUS status = RegEnumKeyEx(hKey, index, name, &nameSize, NULL, NULL, NULL, NULL);
        
        if (status == ERROR_NO_MORE_ITEMS) {
            break;
        }
        
        if (status == ERROR_SUCCESS) {
            wprintf(L"SubKey: %s\n", name);
        }
        
        index++;
    }
}

RegEnumValue - 枚举值

C++
LSTATUS RegEnumValue(
    HKEY    hKey,
    DWORD   dwIndex,
    LPSTR   lpValueName,
    LPDWORD lpcchValueName,
    LPDWORD lpReserved,
    LPDWORD lpType,
    LPBYTE  lpData,
    LPDWORD lpcbData
);

示例

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

void EnumValues(HKEY hKey) {
    WCHAR name[256];
    DWORD nameSize;
    BYTE data[1024];
    DWORD dataSize;
    DWORD type;
    DWORD index = 0;
    
    while (true) {
        nameSize = sizeof(name) / sizeof(WCHAR);
        dataSize = sizeof(data);
        
        LSTATUS status = RegEnumValue(hKey, index, name, &nameSize, NULL, &type, data, &dataSize);
        
        if (status == ERROR_NO_MORE_ITEMS) {
            break;
        }
        
        if (status == ERROR_SUCCESS) {
            wprintf(L"Value: %s, Type: %d\n", name, type);
        }
        
        index++;
    }
}

注册表信息

RegQueryInfoKey - 查询键信息

C++
LSTATUS RegQueryInfoKey(
    HKEY      hKey,
    LPSTR     lpClass,
    LPDWORD   lpcchClass,
    LPDWORD   lpcSubKeys,
    LPDWORD   lpcbMaxSubKeyLen,
    LPDWORD   lpcbMaxClassLen,
    LPDWORD   lpcValues,
    LPDWORD   lpcbMaxValueNameLen,
    LPDWORD   lpcbMaxValueLen,
    LPDWORD   lpcbSecurityDescriptor,
    PFILETIME lpftLastWriteTime
);

示例

C++
1
2
3
4
DWORD subKeyCount, valueCount;
RegQueryInfoKey(hKey, NULL, NULL, &subKeyCount, NULL, NULL, 
                &valueCount, NULL, NULL, NULL, NULL);
printf("SubKeys: %d, Values: %d\n", subKeyCount, valueCount);

导出和导入

RegSaveKey - 保存注册表键

C++
1
2
3
4
5
LSTATUS RegSaveKey(
    HKEY                hKey,
    LPCSTR              lpFile,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes
);

RegRestoreKey - 还原注册表键

C++
1
2
3
4
5
LSTATUS RegRestoreKey(
    HKEY   hKey,
    LPCSTR lpFile,
    DWORD  dwFlags
);

RegLoadKey - 加载注册表配置单元

C++
1
2
3
4
5
LSTATUS RegLoadKey(
    HKEY    hKey,
    LPCSTR  lpSubKey,
    LPCSTR  lpFile
);

RegUnLoadKey - 卸载注册表配置单元

C++
1
2
3
4
LSTATUS RegUnLoadKey(
    HKEY   hKey,
    LPCSTR lpSubKey
);

实用示例

读取注册表完整示例

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

void PrintValue(HKEY hKey, LPCWSTR valueName) {
    DWORD type;
    BYTE data[1024];
    DWORD dataSize = sizeof(data);
    
    LSTATUS status = RegQueryValueEx(hKey, valueName, NULL, &type, data, &dataSize);
    
    if (status != ERROR_SUCCESS) {
        wprintf(L"Failed to read %s\n", valueName);
        return;
    }
    
    switch (type) {
        case REG_SZ:
        case REG_EXPAND_SZ:
            wprintf(L"%s = %s\n", valueName, (LPCWSTR)data);
            break;
        case REG_DWORD:
            wprintf(L"%s = %d\n", valueName, *(DWORD*)data);
            break;
        case REG_QWORD:
            wprintf(L"%s = %lld\n", valueName, *(DWORD64*)data);
            break;
        case REG_BINARY:
            wprintf(L"%s = (binary, %d bytes)\n", valueName, dataSize);
            break;
        default:
            wprintf(L"%s = (type %d)\n", valueName, type);
            break;
    }
}

int main() {
    HKEY hKey;
    LSTATUS status = RegOpenKeyEx(
        HKEY_LOCAL_MACHINE,
        L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
        0, KEY_READ, &hKey
    );
    
    if (status == ERROR_SUCCESS) {
        PrintValue(hKey, L"ProductName");
        PrintValue(hKey, L"CurrentVersion");
        PrintValue(hKey, L"ProgramFilesPath");
        
        RegCloseKey(hKey);
    }
    
    return 0;
}

参考资料