1. 注册表简介
注册表是 Windows 操作系统中的一个核心数据库 , 其中存放着各种参数 , 直接控制着 Windows 的启动 , 硬件驱动程序的装载以及一些 Windows 应用程序的运行 , 从而在整个系统中起着核心作用 ; 这些作用包括了软 , 硬件的相关配置和状态信息 , 比如注册表中保存有应用程序和资源管理器外壳的初始条件 , 首选项和卸载数据等 , 联网计算机的整个系统的设置和各种许可 , 文件扩展名与应用程序的关联 , 硬件部件的描述 , 状态和属性 , 性能记录和其他底层的系统状态信息 , 以及其他数据等 ;
2. 注册表的数据结构
注册表由 键 (也叫主键或称 “项” ) , 子键 (子项) 和 值 项构成 ; 一个键就是分支中的一个文件夹 , 而子键就是这个文件夹当中的子文件夹 , 子键同样它也是一个键 ; 一个值项则是一个键的当前定义 , 由名称 , 数据类型以及分配的值组成 ; 一个键可以有一个或多个值 , 每个值的名称各不相同 , 如果一个值的名称为空 , 则该值为该键的默认值 ;
注册表的数据类型主要有以下四种 :
REG_SZ
: 字符串 : 文本字符串REG_MULTI_SZ
: 多字符串值 : 含有多个文本值的字符串REG_BINARY
: 二进制数 : 二进制值 , 以十六进制显示REG_DWORD
: 双字值 : 一个 32 位的二进制值 , 显示为 8 位的十六进制值
3. 主键简介
HKEY_CLASSES_ROOT
在注册表中 HKEY_CLASSES_ROOT 是系统中控制所有数据文件的项 ; HKEY_CLASSES_ROOT 控制键包括了所有文件扩展和所有和执行文件相关的文件 ; 它同样也决定了当一个文件被双击时起反应的相关应用程序 ; HKEY_CLASSES_ROOT 被用作程序员在安装软件时方便的发送信息 , 在 Win95 和 Winnt 中 , HKEY_CLASSES_ROOT 和 HKEY_LOCAL_MACHINE/Software/Classes
是相同的 ; 程序员在运行他们的启动程序时不需要担忧实际的位置 , 相反的 , 他们只需要在 HKEY_CLASSES_ROOT 中加入数据就可以了 ;
HKEY_CURRENT_CONFIG
Win95 一般只使用一个硬件配置文件 ; 如果有多个硬件配置文件 ; HKEY_LOCAL_MACHINE/Config
中就会添加一个键 ;HKEY_LOCAL_MACHINE/Config
包含了HKEY_LOCAL_MACHINE中相同的数据 ;
在启动时 , 你可以选择你愿意使用的配置文件 ; 如果有多个安装 , 每次系统重新启动时 , 你就必须选择 ; HKEY_CURRENT_CONFIG 是在启动时控制目前硬件配置的键 ; 在系统启动以后 , 任何地方的变化都会自动影响到它 ; 程序员经常使用 HKEY_CURRENT_CONFIG 方便的来存取配置信息 ; HKEY_CURRENT_CONFIG 包括了系统中现有的所有配置文件的细节 ; 你的选择影响了哪一个硬件配置文件成为现在的 ; 举例来说 , 如果配置 0002 被选择了 , 所有 0002 的配置信息会被映射到这些键上 ; HKEY_CURRENT_CONFIG 允许软件和设备驱动程序员很方便的更新注册表 , 而不涉及到多个配置文件信息 ; HKEY_LOCAL_MACHINE 中同样的数据和任何注册表的变化都会同时的变化 ;
HKEY_USERS
HKEY_USERS 将缺省用户和目前登陆用户的信息输入到注册表编辑器 , 在 Win95 中 , 它仅被那些配置文件激活的登陆用户使用 , 同样在 Winnt 下 , 它也是这样 ; Win95 从 user.dat 中取得他们的信息 , Winnt 从 ntuser.dat 中取得信息 ; dat文件包含了所有基于用户的注册表设置并且允许你取配置这些用户的环境 ; 如果你改变了缺省用户的设置 , 所有新用户会继承同样的设置 ; 而且 , 那些已经被建立的用户变的失效 ;
HKEY_LOCAL_MACHINE
HKEY_LOCAL_MACHINE是一个显示控制系统和软件的处理键 ; HKLM 键保存着计算机的系统信息 ; 它包括网络和硬件上所有的软件设置 ; (比如文件的位置 , 注册和未注册的状态 , 版本号等等) 这些设置和用户无关 , 因为这些设置是针对使用这个系统的所有用户的 ;
HKEY_CURRENT_USER
HKEY_CURRENT_USER 包含着在 HKEY_USERS 安全辨别里列出的同样信息 ; 任何在 HKEY_CURRENT_USER 里的改动也都会立即HKEY_USERS 改动 , 相反也是这样 ; HKEY_CURRENT_USER 允许程序员和开发者易于存取目前登陆用户的设置 ; 通过建立这个键 , 微软很容易在不涉及到用户的 SID 下改变 , 添加和设置 ; 也就是说 , 所有当前的操作改变只是针对当前用户而改变 , 并不影响其他用户 ;
4. C++ 函数支持
-
打开一个指定的注册表键
LONG RegOpenKeyEx( HKEY hKey, // 需要打开的主键的名称 LPCTSTR lpSubKey, // 需要打开的子键的名称 DWORD ulOptions, // 保留 , 设为 0 REGSAM samDesired, // 安全访问标记 , 也就是权限 PHKEY phkResult // 得到的将要打开键的句柄 )
-
检索一个已打开的注册表句柄中 , 指定的注册表键的类型和设置值
LONG WINAPI RegQueryValueEx( HKEY hKey, LPCTSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData );
-
创建或打开注册表项 , 默认为创建 , 当注册表中有此项时 , 为打开
LONG WINAPI RegCreateKey( _In_ HKEY hKey, _In_opt_ LPCTSTR lpSubKey, _Out_ PHKEY phkResult );
-
设置注册表键的值
LONG RegSetValueEx( HKEY hKey, LPCTSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData );
-
删除一个注册表的键
LONG WINAPI RegDeleteKey( __in HKEY hKey, __in LPCTSTR lpSubKey );
-
删除一个注册表键的值
LONGWINAPIRegDeleteValue( _In_HKEYhKey, _In_opt_LPCTSTRlpValueName );
5. 代码实例
// 查询一个键的值
void CRegeditDemoDlg::OnBnClickedButtonQuery()
{
HKEY hKEY; // 定义有关的 hKEY , 在查询结束时要关闭
// 打开与路径 data_Set 相关的 hKEY
LPCTSTR strPath= _T("Wow6432Node\\CLSID\\{00024500-0000-0000-C000-000000000046}\\LocalServer");
//访问注册表,hKEY则保存此函数所打开的键的句柄
if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_CLASSES_ROOT,strPath,0,KEY_READ,&hKEY))
{
char szValue[256] = {0};
DWORD dwSize = sizeof(szValue);
DWORD dwType = REG_SZ;
// 取键的默认值
if (::RegQueryValueEx(hKEY,_T("ENSK"), 0, &dwType, (LPBYTE)&szValue, &dwSize) != ERROR_SUCCESS)
{
AfxMessageBox(_T("错误:无法查询有关的注册表信息"));
}
//程序结束,关闭打开的 hKEY
::RegCloseKey(hKEY);
}
}
// 创建一个键并写值
void CRegeditDemoDlg::OnBnClickedButtonCreateAndAlter()
{
HKEY hKey; // 定义有关的 hKEY , 在查询结束时要关闭
HKEY hTempKey;
CString strName = _T("China");
DWORD nLength = (strName.GetLength() + 1) * sizeof(TCHAR); // 定义数据长度
LPBYTE lpbName = new BYTE[(strName.GetLength() + 1) * sizeof(TCHAR)]; // 有可能是 Ansi 或 Unicode
memcpy(lpbName, (void*)(LPCTSTR)strName, (strName.GetLength() + 1) * sizeof(TCHAR));
LPCTSTR strPath= _T("Wow6432Node\\CLSID\\{00024500-0000-0000-C000-000000000046}\\LocalServer");
// 打开与路径 strPath 相关的 hKEY
if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_CLASSES_ROOT, strPath, 0, KEY_SET_VALUE, &hKey))
{
// 在当前键下创建一个子键 "TOJOHN"
if (ERROR_SUCCESS == ::RegCreateKey(hKey, _T("TOJOHN"), &hTempKey))
{
// 设置子健的值
if (ERROR_SUCCESS == ::RegSetValueEx(hTempKey, _T("Name"), 0, REG_SZ, lpbName, nLength))
{
AfxMessageBox(_T("更新注册表成功"));
}
else
{
AfxMessageBox(_T("更新注册表失败"));
}
}
::RegCloseKey(hTempKey);
}
::RegCloseKey(hKey);
}
// 删除一个键
void CRegeditDemoDlg::OnBnClickedButtonDeleteKey()
{
HKEY hKey; // 定义有关的 hKEY , 在查询结束时要关闭
LPCTSTR strPath= _T("Wow6432Node\\CLSID\\{00024500-0000-0000-C000-000000000046}\\LocalServer");
// 打开与路径 strPath 相关的 hKEY
if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_CLASSES_ROOT, strPath,0,KEY_SET_VALUE, &hKey))
{
// 使用 hKey 来操作 strPath 这个 KEY 里面的值
if (ERROR_SUCCESS == ::RegDeleteKey(hKey, _T("TOJOHN")))
{
AfxMessageBox(_T("删除注册表键成功"));
}
else
{
AfxMessageBox(_T("删除注册表键失败"));
}
}
::RegCloseKey(hKey);
}
// 删除一个键的值
void CRegeditDemoDlg::OnBnClickedButtonDeleteValue()
{
HKEY hKey; // 定义有关的 hKEY , 在查询结束时要关闭
LPCTSTR strPath= _T("Wow6432Node\\CLSID\\{00024500-0000-0000-C000-000000000046}\\LocalServer\\TOJOHN");
// 打开与路径 strPath 相关的 hKEY
if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_CLASSES_ROOT, strPath, 0, KEY_SET_VALUE, &hKey))
{
// 使用 hKey 来操作 strPath 这个 KEY 里面的值
if (ERROR_SUCCESS == ::RegDeleteValue(hKey, _T("Name")))
{
AfxMessageBox(_T("删除注册表值成功"));
}
else
{
AfxMessageBox(_T("删除注册表值失败"));
}
}
::RegCloseKey(hKey);
}
// 写入 DWORD 类型的值
void CRegeditDemoDlg::OnBnClickedButtonWriteDword()
{
HKEY hKey; // 定义有关的 hKEY , 在查询结束时要关闭
HKEY hTempKey;
DWORD dwValue = 6;
DWORD dwSize = sizeof(DWORD);
DWORD dwType = REG_DWORD;
LPCTSTR strPath= _T("Wow6432Node\\CLSID\\{00024500-0000-0000-C000-000000000046}\\LocalServer");
//打开与路径 strPath 相关的 hKEY
if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_CLASSES_ROOT, strPath, 0, KEY_SET_VALUE, &hKey))
{
// 使用 hKey 来操作 strPath 这个 KEY 里面的值
if (ERROR_SUCCESS == ::RegCreateKey(hKey, _T("TOJOHN"), &hTempKey))
{
if (ERROR_SUCCESS == ::RegSetValueEx(hTempKey, _T("Name"), 0, REG_DWORD, (CONST BYTE*)&dwValue, sizeof(DWORD)))
{
AfxMessageBox(_T("更新注册表成功"));
}
else
{
AfxMessageBox(_T("更新注册表失败"));
}
}
::RegCloseKey(hTempKey);
}
::RegCloseKey(hKey);
}
// 写入二进制类型的值
void CRegeditDemoDlg::OnBnClickedButtonWriteBinary()
{
HKEY hKey; // 定义有关的 hKEY , 在查询结束时要关闭
HKEY hTempKey;
BYTE byteName[10];
memset(byteName, 0, sizeof(byteName)); // 将数组 byteName 清零
byteName[0] = 0xff;
byteName[1] = 0xac;
byteName[2] = 0x05;
byteName[4] = 0x4e;
LPCTSTR strPath= _T("Wow6432Node\\CLSID\\{00024500-0000-0000-C000-000000000046}\\LocalServer");
//打开与路径 strPath 相关的 hKEY
if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_CLASSES_ROOT, strPath, 0, KEY_SET_VALUE, &hKey))
{
// 使用 hKey 来操作 strPath 这个 KEY 里面的值
if (ERROR_SUCCESS == ::RegCreateKey(hKey, _T("TOJOHN"), &hTempKey))
{
if (ERROR_SUCCESS == ::RegSetValueEx(hTempKey, _T("Name"), 0, REG_BINARY, (unsigned char *)byteName, 5))
{
AfxMessageBox(_T("更新注册表成功"));
}
else
{
AfxMessageBox(_T("更新注册表失败"));
}
}
::RegCloseKey(hTempKey);
}
::RegCloseKey(hKey);
}
作者 Github : tojohnonly , 博客 : EnskDeCode