C++注册表操作

1. 基础知识

注册表的组织方式跟文件目录比较相似,主要分为根键、子键和键值项三部分,
1.1 根键
    分为5个,分别为:
        HKEY_CLASSES_ROOT
        HKEY_CURRENT_USER
        HKEY_LOCAL_MACHINE
        HKEY_USERS
        HKEY_CURRENT_CONFIG

1.2 子键
    可以有多个子键和键值项,就像一个目录中可以有多个子目录和多个文件一样。
1.3 键值项
    可以理解为文件,由三部分组成,分别为:名称、类型、数据。
    类型分为:
        REG_BINARY    二进制数据
        REG_DWORD    32位双字节数据
        REG_SZ    以0节尾的字符串
        REG_DWORD_BIG_ENDIAN    高位排在低位的双字
        REG_EXPAND_SZ    扩展字符串,可以加入变量 如%PATH%
        REG_LINK    UNICODE符号链接
        REG_RESOURCE_LIST    设备驱动程序资源列表
        REG_MULTI_SZ    多字符串

2. 打开/关闭注册表句柄

对注册表操作前应该先打开指定的键,然后通过键的句柄进行操作。
需要注意的是打开键的句柄后需要关闭(RegCloseKey())。
打开键句柄  RegOpenKeyEx()
函数原型:

 RegOpenKeyEx(
        hKey,  // 父键句柄
        lpSubKey,  // 子键句柄
        dwOptions,  // 系统保留,指定为0
        samDesired,  // 打开权限
        phkResult   // 返回打开句柄
        );

打开权限有多种,可以指定为KEY_ALL_ACCESS(包含所有权限);函数执行成功返回ERROR_SUCCESS。
    KEY_CREATE_LINK        许可创建一个符号链接
    KEY_CREATE_SUB_KEY        创建子键
    KEY_ENUMERATE_SUB_KEYS        列举子键
    KEY_EXECUTE        访问
    KEY_NOTIFY        提供更改通知
    KEY_QUERY_VALUE        查询子键数据
    KEY_ALL_ACCESS        联合了KEY_QUERY_VALUE、KEY_SET_VALUE、KEY_ENUMERATE_SUB_KEYS、KEY_NOTIFY、KEY_CREATE_SUB_KEY、KEY_CREATE_LINK访问权限并且加上所有的标准访问权限,除了SYNCHRONIZE
    KEY_READ    联合了STANDARD_RIGHIS_READ、KEY_QUERY_VALUE、KEY_ENUMERATE_SUB_KEYS、KEY_NOTIFY访问权限
    KEY_WOW64_64KEY        Windows XP:使64位或者342位应用程序打开64位键
    KEY_WOW64_32KEY        Windows XP:使64位或者342位应用程序打开32位键
    KEY_WRITE        联合STANDARS_RIGHTS_WRITE、KEY_SET_VALUE、KEY_CREATE_SUB_KEY访问权限

3. 获取子键/键值信息

常用到的子键/键值的信息如:子键/键值的数量,长度,以及数据的最大长度等,可以通过函数RegQueryInfoKey()获取。
函数原型:

    RegQueryInfoKey(
        hKey,  // 要获取信息的句柄
        lpClass,  // 接收创建键时的Class字符串
        lpcbClass,  // lpClass的长度
        lpReserved,  // 系统保留,指定为0
        lpcSubkeys,  // 子键数量
        lpcbMaxSubKeyLen,  // 子键中最长名称的长度
        lpcbMaxClassLen,  // 子键中最长Class字符串长度
        lpValues,  // 键值数量
        lpcbMaxValueNameLen,  // 键值项中最长名称的长度
        lpcbMaxValueLen,  // 键值项数据最大长度
        lpcbSecurityDescriptor,  // 安全描述符长度
        lpftLastWriteTime  // FILETIME结构,最后修改时间
    );

实际使用时只需要填写自己需要的即可;返回的长度不包括结尾的0字符,在使用时应该用长度+1。

3.1 获取一个项的值
使用函数RegQueryValueEx()函数获取一个项的设置值,函数原型:

LONG RegQueryValueEx(
    HKEY hKey,  // 一个已经打开项的句柄,或者指定一个标准项名
    LPCTSTR lpValueName,  // 要获取值的名字
    LPDWORD lpReserved,  // 保留字,设置为0
    LPDWORD lpType,  // 用于装载取回数据类型的一个变量
    LPBYTE lpData,  // 用于装载指定值的一个缓冲区
    LPDWORD lpcbData  // 用于装载lpData缓冲区长度的一个变量。一旦返回,它会设为实际装载到缓冲区的字节数
);

返回值:0=成功,其它表示失败
lpValueName指向要查询值的名字的字符串(以空字符结束),如果设置为NULL,那么这个函数找这个键的未命名或默认值的类型和数据。
lpReserved必须设置为NULL。

4. 枚举子键信息
枚举子键信息可以用函数RegEnumKeyEx()实现,调用该函数返回子键的名称、长度和一些相关数据。直到返回ERROR_NO_MORE_ITEMS说明已经枚举完所有的数据。函数原型:

RegEnumKeyEx(
    hKey,  // 被枚举的键句柄
    dwIndex,  // 子键索引编号
    lpName,  // 子键名称
    lpcbName,  // 子键名称长度
    lpReserved,  // 系统保留,指定为0
    lpClass,  // 子键类名
    lpcbClass,  // 子键类名长度
    lpftLastWriteTime  // 最后写入时间
);

5. 枚举键值信息

使用RegEnumValue()函数枚举键值信息,函数原型

RegEnumValue(
    hKey,  // 被枚举的键句柄
    dwIndex,  // 子键索引编号
    lpValueName,  // 键值名称
    lpcbValueName,  // 键值名称长度
    lpReserved,  // 系统保留,指定为0
    lpType,  // 键值数据类型
    lpData,  // 键值数据
    lpcbData  // 键值数据长度
);

6. 创建/删除子键

6.1 创建子键
    创建子键与打开子键类似,可以使用RegCreateKeyEx()函数实现。函数原型:

    RegCreateEx(
        hKey,  // 父键句柄
        lpSubKey,  // 子键句柄
        Reserved,  // 系统保留,指定为0
        lpClass,  // 定义子键类名,通常为NULL
        dwOptions,  // 创建子键时的选项
        samDesired,  // 创建后操作权限
        lpSecurityAttributes,  // 指向SECURITY_ATTRIBUTES结构,指定键句柄的继承性
        phkResult,  // 返回创建句柄
        lpdwDisposition,  // 通常设为NULL
    );

也可以用16位下的函数RegCreateKey()实现
    
6.2 删除一个子键
删除一个键使用函数RegDeleteKey(),函数原型:
RegDeleteKey(
    hKey,  // 主键句柄
    lpSubKey  // 子键名称字符串
);

7. 创建/删除键值项

7.1 创建键值可以用RegSetValueEx()函数实现,函数原型:

RegSetValueEx(
    hKey,  // 键句柄,键值项将保存在此键下
    lpValueName,  // 键值项名称
    Reserved,  // 系统保留,指定为0
    dwType,  // 键值项类型
    lpData,  // 键值项数据
    cbData,  // 键值项长度
);

使用时需要注意,参数lpData和cbData的值要根据dwType的值来设定。按照常用的设置分三种情况:
1. dwType为REG_SZ时,lpData为要设置的数据,cbData为数据的长度。
2. dwType为REG_DWORD时,cbData必须设置为4。
3. dwType为REG_BINARY时,cbData也必须设置为4。
调用时,如果键值项名称已经存在,会覆盖原有键值项,如果没有,就新建一个。

7.2 删除键值项
删除键值项可以用RegDeleteValue()函数,函数原型:

RegDeleteValue(
    hKey,  // 父键句柄
    lpValueName,  // 要删除的键值项名称
);

8. 备份/恢复注册表
8.1 备份注册表
备份注册表可以用RegSaveKey()函数实现,函数原型:

RegSaveKey(
    hKey,  // 要备份的键句柄
    lpFile,  // 保存信息的文件名称
    lpSecurityAttributes  // 文件安全属性
);

函数参数:
hKey:要备份的键句柄,可以是系统预定义的,也可以是RegOpenKey()打开或RegCreateKeyEx()创建的;
lpFile:保存信息的文件名称,这个文件必须是不存在的,这个文件也不能有扩展名;
lpSecurityAttributes:在NT系统中用来设置新文件的安全属性,通常设置为NULL。
使用该函数时需要有SE_BACKUP_NAME权限,这个权限不能在RegOpenKey()或RegCreateKeyEx()指定,需要提升程序的权限。

7.2 恢复注册表可以用RegRestoreKey()函数实现
函数原型:

RegStoreKey(
    hKey,  // 要恢复的键句柄
    lpFile,  // 保存信息的文件名称
    dwFlag  // 标志是否易失  为TRUE,暂时恢复注册表,为FALSE永久修改注册表值
);

同样需要注意的是使用该函数需要有SE_RESTORE_NAME权限。

参考链接:C++ 注册表编程 - 程序员大叔 - 博客园

你可能感兴趣的:(C++,注册表操作,c++,p2p,开发语言)