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;
}
测试运行效果: