VC++使用WinReg系列API操作注册表

1.注册表用途
   windows注册表就像操作系统的数据库,系统运行的一些参数可以存放在注册表中,用户应用程序为了防止程序退出一些关键数据
丢失,也可以在其中保存软件运行的一些参数

2.32位程序访问64位系统注册表
    32位程序在64位系统上不能直接访问64位路径注册表,而是跳转访问WoW6432Node下,
    要想直接访问64位注册表路径,使用参数KEY_WOW64_64KEY,
    要想访问32位注册表路径,使用参数KEY_WOW64_32KEY
    注册表常用的四个顶级项:
        HKEY_CLASSES_ROOT
        HKEY_CURRENT_USER
        HKEY_LOCAL_MACHINE
        HKEY_USERS

3. 注册表常用访问权限
    注册表访问权限:
        KEY_READ:读
        KEY_WRITE:写
        KEY_ALL_ACCESS:所有权限
        ......

4. 操作注册表方法
    4.1 调用WinReg系列API
    4.2 调用Shlapi系列API

5. WinReg系列API中常用方法
    注意:该类方法操作注册表要首先打开注册表才能操作
    RegCreateKey:创建注册表项
    RegOpenKeyEx:打开注册表项
    RegSetValueEx:增加(写入)注册表项值
    RegQueryValueEx:读取注册表项值
    RegDeleteKeyEx:删除注册表项
    RegDeleteValue:删除注册表项值
    RegEnumValue:枚举注册表项值
    RegCloseKey:关闭注册表

代码举例如下:

// 创建注册表项
BOOL CreateRegItem(const wstring& strItemKey, HKEY hKey = HKEY_CURRENT_USER)
{
    LSTATUS lRet;
    HKEY hItemKey;
    //创建项,支持多层递归创建
    lRet = ::RegCreateKey(HKEY_CURRENT_USER, strItemKey.c_str(), &hItemKey);
    if (ERROR_SUCCESS == lRet)
        return FALSE;
    ::RegCloseKey(hItemKey);
    return TRUE;
}

// 注册表项打开,创建,写入值,读取值
BOOL DealRegItem(const wstring& strItemKey, 
    const wstring& strItemValueKey,
    const wstring& strItemValueKeyValue,
    HKEY hKey = HKEY_CURRENT_USER)
{
    LSTATUS lRet;
    HKEY hItemKey;
    lRet = ::RegOpenKeyEx(hKey,
        strItemKey.c_str(),
        0,
        KEY_READ | KEY_WRITE | KEY_WOW64_32KEY,
        &hItemKey);
    if (ERROR_SUCCESS != lRet)
    {
        lRet = ::RegCreateKey(HKEY_CURRENT_USER, strItemKey.c_str(), &hItemKey);
        if (ERROR_SUCCESS != lRet)
            return FALSE;
    }

    // 项中写入字符串值
    lRet = ::RegSetValueEx(hItemKey, strItemValueKey.c_str(), 0, REG_SZ, (LPBYTE)strItemValueKeyValue.c_str(), strItemValueKeyValue.size() * 2); 
    // 读取项值
    // 1.获取项值类型和项值字节数
    ULONG nCharLen = 0;
    DWORD dwType = 0;
    lRet = ::RegQueryValueEx(hItemKey,
        strItemValueKey.c_str(),
        NULL,
        &dwType,
        NULL,
        &nCharLen);

    if (lRet != ERROR_SUCCESS || nCharLen == 0) {
        ::RegCloseKey(hItemKey);
        return false;
    }

    // 2.根据1中字节数申请空间,然后读取数据
    wstring value;
    TCHAR *pTmp = new (std::nothrow) TCHAR[nCharLen + 1];
    wmemset(pTmp, 0x00, nCharLen + 1);
    lRet = ::RegQueryValueEx(hItemKey,
        strItemValueKey.c_str(),
        NULL,
        &dwType,
        (BYTE*)pTmp,
        &nCharLen);
    value = pTmp;
    if (pTmp)
    {
        delete[] pTmp;
        pTmp = NULL;
    }
    wcout << (REG_SZ == dwType) << L" " << value.c_str() << endl;


    // 项中写入整数
    wstring strDwordItemValueKey = L"masterprice";
    DWORD dwPrice = 895467;
    lRet = ::RegSetValueEx(hItemKey, strDwordItemValueKey.c_str(), 0, REG_DWORD, (LPBYTE)&dwPrice, sizeof(dwPrice));
    // 读取项值
    // 1.获取项值类型和项值字节数
    nCharLen = 0;
    dwType = 0;
    lRet = ::RegQueryValueEx(hItemKey,
        strDwordItemValueKey.c_str(),
        NULL,
        &dwType,
        NULL,
        &nCharLen);

    if (lRet != ERROR_SUCCESS || nCharLen == 0) {
        ::RegCloseKey(hItemKey);
        return false;
    }

    // 2.根据1中字节数申请空间,然后读取数据
    DWORD dwValue = 0;
    pTmp = new (std::nothrow) TCHAR[nCharLen + 1];
    wmemset(pTmp, 0x00, nCharLen + 1);
    lRet = ::RegQueryValueEx(hItemKey,
        strDwordItemValueKey.c_str(),
        NULL,
        &dwType,
        (BYTE*)pTmp,
        &nCharLen);
    dwValue = *((DWORD*)pTmp);
    if (pTmp)
    {
        delete[] pTmp;
        pTmp = NULL;
    }
    cout << (REG_DWORD == dwType) << " " << dwValue << endl;


    ::RegCloseKey(hItemKey);

    return TRUE;
}

// 删除注册表项, 不支持递归删除,如果项下还有子项,删除会失败
BOOL DeleteRegItem(const wstring& strItemKey,
                    const wstring& strItemSubKey,
                    HKEY hKey = HKEY_CURRENT_USER)
{
    LSTATUS lRet;
    HKEY hItemKey;

    lRet = ::RegOpenKeyEx(hKey,
        strItemKey.c_str(),
        0,
        KEY_READ | KEY_WRITE | KEY_WOW64_32KEY,
        &hItemKey);
    if (lRet != ERROR_SUCCESS)
        return FALSE;

    // 如果Key(项)下还有项,删除会返回5错误,有值没影响,会删除,即不支持递归
    lRet = ::RegDeleteKeyEx(hItemKey, strItemSubKey.c_str(), KEY_WOW64_32KEY, 0);
    if (ERROR_SUCCESS != lRet)
    {
        cout << "error::" << lRet << endl;
        ::RegCloseKey(hItemKey);
        return FALSE;
    }
        
    ::RegCloseKey(hItemKey);
    return TRUE;
}

// 删除注册表项中的值
BOOL DealRegItemValue(const wstring& strItemKey,
    const wstring& strItemValueKey,
    HKEY hKey = HKEY_CURRENT_USER)
{
    LSTATUS lRet;
    HKEY hItemKey;

    lRet = ::RegOpenKeyEx(hKey,
        strItemKey.c_str(),
        0,
        KEY_READ | KEY_WRITE | KEY_WOW64_32KEY,
        &hItemKey);
    if (lRet != ERROR_SUCCESS)
        return FALSE;

    // 删除项下的值
    lRet = RegDeleteValue(hItemKey, strItemValueKey.c_str());
    if (ERROR_SUCCESS != lRet)
    {
        cout << "error::" << lRet << endl;
        ::RegCloseKey(hItemKey);
        return FALSE;
    }

    ::RegCloseKey(hItemKey);
    return TRUE;
}

// 枚举注册表
BOOL EnumerateRegItemValue(const wstring& strItemKey,
    map<wstring, wstring> &mapValues,
    HKEY hKey = HKEY_CURRENT_USER)
{
    HKEY hSubKey = NULL;

    BOOL retCode = RegOpenKeyEx(hKey, strItemKey.c_str(), NULL, KEY_READ | KEY_WOW64_64KEY, &hSubKey);
    if (retCode != ERROR_SUCCESS)
        return FALSE;

    LSTATUS lStatus = ERROR_SUCCESS;
    TCHAR szValueName[MAX_PATH] = { 0 };
    DWORD dwNameLen = MAX_PATH - 2;
    TCHAR szValue[MAX_PATH] = { 0 };
    DWORD dwLen = MAX_PATH - 2;


    for (int i = 0; ; i++)
    {
        lStatus = ::RegEnumValue(hSubKey, i, szValueName, &dwNameLen, NULL, NULL, (LPBYTE)szValue, &dwLen);
        if (ERROR_SUCCESS != lStatus)
            break;
        mapValues.insert(std::make_pair(szValueName, szValue));
        memset(szValueName, 0, sizeof(szValueName));
        memset(szValue, 0, sizeof(szValue));
        dwNameLen = MAX_PATH - 2;
        dwLen = MAX_PATH - 2;
    }
    
    RegCloseKey(hKey);
    return TRUE;
}

int main()
{
    //输出中文
    locale::global(locale("chs"));
    wcout.imbue(locale("chs"));
    
    /*
    CreateRegItem(L"SOFTWARE\\China\\Beijing\\Haidian");
    */


    DealRegItem(L"SOFTWARE\\China\\Shanxi\\Xian",
        L"changan",
        L"wankecheng");
    
    /*
    DeleteRegItem(L"SOFTWARE\\China\\Beijing",
        L"Haidian");
    */

    /*
    DealRegItemValue(L"SOFTWARE\\China\\Shanxi\\Xian", L"删除");
    */

    /*
    map<wstring, wstring> mapValues;
    EnumerateRegItemValue(L"SOFTWARE\\China\\Shanxi\\Xian", mapValues);
    */
   
    getchar();
    return 0;
}

测试运行效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值