注册表

  1. windows的注册表分三个部分

    1. 注册表根路径
    2. 注册表文件夹
    3. 主表标记录(key->value)
  2. windows api中对于注册表的描述更日常表述不同
  3. 在windows 的api中 key指的是某个 注册表文件夹
  4. 在windows 的api中 value指的是某个 记录的key

实例

#include "pch.h"
#include "windows.h"
#include <iostream>


/*
 * 根据错误码输出错误信息
 */
void showErrorText(DWORD error_num)
{
    char *msg = NULL;
    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        error_num,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // 使用默认语言
        (LPSTR)&msg,
        0,
        NULL
    );

    printf("Error code %d: ", error_num);
    if (msg == NULL)
        printf("%sn", "Unknown error");
    else
        printf("%sn", msg);
}


//创建 注册表文件夹
void create_red_dir() {
    HKEY hKey;
    HKEY subKey;
    DWORD result;

    char str_reg_pathp[] = "Software";//指定要访问的 注册表文件夹
    char str_red_dir[] = "reg_dir";//新加的注册表文件夹名称 
    char str_key[] = "key";        //增加的key
    char str_value[] = "value";    //key对应的value

    //1 打开注册表
    result = RegOpenKeyEx(
        HKEY_CURRENT_USER,str_reg_pathp, // 打开指定路径的 注册表文件夹
        0,              // 保留参数必须填 0
        KEY_WRITE,      // 打开权限,写入
        &hKey           // 打开之后的句柄
    );

    if (result != ERROR_SUCCESS)
    {
        showErrorText(result);
    }

    /*
    2
    新加的注册表文件夹

    */
    RegCreateKey(hKey, str_red_dir, &subKey);

    //3 关闭注册表:
    RegCloseKey(hKey);

}

//增加记录
void add_reg_key_value() {
    HKEY hKey;
    DWORD result;

    char str_reg_pathp[] = "Software\\reg_dir";//指定要访问的 注册表文件夹
    char str_key[] = "key";        //增加的key
    char str_value[] = "value";    //key对应的value

    //1 打开注册表
    result = RegOpenKeyEx(
        HKEY_CURRENT_USER, str_reg_pathp, // 打开指定路径的 注册表文件夹
        0,              // 保留参数必须填 0
        KEY_WRITE,      // 打开权限,写入
        &hKey           // 打开之后的句柄
    );

    if (result != ERROR_SUCCESS)
    {
        showErrorText(result);
    }


    /*
    2
    在某个 注册表文件夹下 设置一条记录

    */
    result = RegSetValueEx(
        hKey,     //注册表 文件夹 句柄
        str_key,    // key字段
        0,       // 保留参数必须填 0
        REG_SZ,  // 键值类型为字符串
        (const unsigned char *)str_value, // value字符串首地址
        sizeof(str_value)   // 字符串长度
    );

    if (result != ERROR_SUCCESS)
    {
        showErrorText(result);
    }

    //4 关闭注册表:
    RegCloseKey(hKey);



    if (result != ERROR_SUCCESS)
    {
        showErrorText(result);
    }
}

//删除 注册表文件夹
void del_reg_dir()
{
    HKEY hKey;
    DWORD result;

    char str_reg_pathp[] = "Software";//指定要访问的 注册表文件夹
    char str_red_dir[] = "reg_dir"; //要删除的注册表文件夹名称 

    //1 打开注册表
    result = RegOpenKeyEx(
        HKEY_CURRENT_USER, str_reg_pathp,
        0,              // 保留参数必须填 0
        KEY_WRITE,      // 打开权限,写入
        &hKey           // 打开之后的句柄
    );

    if (result != ERROR_SUCCESS)
    {
        showErrorText(result);
    }

    //2 删除 注册表文件夹
    result = RegDeleteKey(hKey, str_red_dir);

    if (result != ERROR_SUCCESS)
    {
        showErrorText(result);
    }

    //关闭注册表:
    RegCloseKey(hKey);

}

//匹配记录
void del_reg_from_key() {
    HKEY hKey;
    DWORD result;

    char str_key[] = "key"; // 要删除的value
    char str_reg_pathp[] = "SOFTWARE\\reg_dir";//指定要访问的 注册表文件夹

    //1 打开注册表
    result = RegOpenKeyEx(
        HKEY_CURRENT_USER, str_reg_pathp,
        0,              // 保留参数必须填 0
        KEY_WRITE,      // 打开权限,写入
        &hKey           // 打开之后的句柄
    );

    if (result != ERROR_SUCCESS)
    {
        showErrorText(result);
    }

    // 2 删除 匹配的记录 匹配key
    result = RegDeleteValue(hKey, str_key);

    if (result != ERROR_SUCCESS)
    {
        showErrorText(result);
    }

    //3 关闭注册表:
    RegCloseKey(hKey);

}


//遍历某个 注册表文件夹下的所有记录
void loop_kv_from_reg_dir() {

#define MAX_KEY_LENGTH 255
#define MAX_VALUE_NAME 16383

    TCHAR    achKey[MAX_KEY_LENGTH];   // buffer for subkey name
    DWORD    cbName;                   // size of name string
    TCHAR    achClass[MAX_PATH] = TEXT("");  // buffer for class name
    DWORD    cchClassName = MAX_PATH;  // size of class string
    DWORD    cSubKeys = 0;             // number of subkeys
    DWORD    cbMaxSubKey;              // longest subkey size
    DWORD    cchMaxClass;              // longest class string
    DWORD    cValues;              // number of values for key
    DWORD    cchMaxValue;          // longest value name
    DWORD    cbMaxValueData;       // longest value data
    DWORD    cbSecurityDescriptor; // size of security descriptor
    FILETIME ftLastWriteTime;      // last write time

    DWORD i, retCode;

    //接受 记录的value
    TCHAR  achValue[MAX_VALUE_NAME];
    DWORD cchValue = MAX_VALUE_NAME;

    //接受 记录的data
    TCHAR  achData[MAX_VALUE_NAME];
    DWORD cchData = MAX_VALUE_NAME;

    HKEY hKey;
    char str_reg_pathp[] = "SOFTWARE\\WinRAR\\ArcHistory";//指定要访问的 注册表文件夹
    //char str_reg_pathp[] = "SOFTWARE\\WinRAR";//指定要访问的 注册表文件夹

    DWORD result = 0;

    //1 打开注册表
    result=RegOpenKeyEx(
        HKEY_CURRENT_USER, str_reg_pathp, // 打开指定路径的 注册表文件夹
        0,              // 保留参数必须填 0
        KEY_READ,      // 打开权限,读取
        &hKey           // 打开之后的句柄
    );

    if (result != ERROR_SUCCESS)
    {
        showErrorText(result);
    }

    // 2 获取注册表文件夹的信息
    retCode = RegQueryInfoKey(
        hKey,                    // key handle
        achClass,                // buffer for class name
        &cchClassName,           // size of class string
        NULL,                    // reserved
        &cSubKeys,               // number of subkeys
        &cbMaxSubKey,            // longest subkey size
        &cchMaxClass,            // longest class string
        &cValues,                // number of values for this key
        &cchMaxValue,            // longest value name
        &cbMaxValueData,         // longest value data
        &cbSecurityDescriptor,   // security descriptor
        &ftLastWriteTime);       // last write time

    //如果有下一级 的注册表文件夹,就迭代出来
    if (cSubKeys) 
    {
        printf("nNumber of subkeys: %d\r\n", cSubKeys);

        for (i = 0; i < cSubKeys; i++)
        {
            cbName = MAX_KEY_LENGTH;
            retCode = RegEnumKeyEx(hKey, i,
                achKey,
                &cbName,
                NULL,
                NULL,
                NULL,
                &ftLastWriteTime);
            if (retCode == ERROR_SUCCESS)
            {
                printf(TEXT("(%d) %s\r\n"), i + 1, achKey);
            }
        }
    }

    //如果有记录,就迭代出来
    if (cValues) 
    {
        printf("nNumber of values: %d\r\n", cValues);

        for (i = 0, retCode = ERROR_SUCCESS; i < cValues; i++)
        {
            cchValue = MAX_VALUE_NAME;
            cchData = MAX_VALUE_NAME;
            achValue[0] = '\0';
            achData[0] = '\0';
            retCode = RegEnumValue(hKey, i,
                achValue,
                &cchValue,
                NULL,
                NULL,
                (LPBYTE)achData,
                &cchData);

            if (retCode == ERROR_SUCCESS)
            {
                printf(TEXT("(%d) %s %s \r\n"), i + 1, achValue, achData);
            }
            else {
            
                printf("错误代码:%0x\r\n", retCode);
            }
        }
    }

}

int main()
{
    //create_red_dir();
    //del_reg_dir();

    //add_reg_key_value();
    //del_reg_from_key();
    loop_kv_from_reg_dir();
    system("pause");

}
Last modification:October 26, 2018
如果觉得我的文章对你有用,请随意赞赏