对系统注册表的访问
初始化文件在早期Windows编程中使用非常普遍,各种系统初始化文件如Win.ini、System.ini等甚至还担负了对系统软、硬件配置以及用户环境等进行控制的重任。在目前的Windows编程中,虽然初始化文件还以其方便简洁的编程方法而继续使用,但其使用范围已大不如前,尤其是在为系统提供配置信息等方面的功能被大大削弱,几乎不起什么重要作用。取而代之的是一种被称为“系统注册表”的二进制数据文件,为应用程序和系统的组成部分提供存储和检索相关的配置信息。该文件只能通过系统提供的注册表编辑器(Registry Editor)进行编辑,或是在程序中通过专门用于注册表访问的API函数对其进行编辑。
系统注册表是一个多层次的结构树,在树的根部共有六个预定义键:HKEY_CLASSES_ROOT、HKEY_CURRENT_USER、HKEY_LOCAL_MACHINE、KEYI_USERS、HKEY_CURRENT_CONFIG和HKEY_DYN_DATA(HKEY_DYN_DATA键只对于Windows 9x而言)。在每一个预定义键下面还包含有众多的树节点,每一个节点都是注册表的关键字,均代表了一个特定的配置项目。在节点展开后又包含有子关键字,直至最后的节点。其中HKEY_CLASSES_ROOT键主要保存了文档类型和属性等信息以及同应用程序相关的分类信息等。HKEY_CURRENT_USER键主要对用户的当前系统配置进行记录。HKEY_LOCAL_MACHINE键对计算机的状态信息进行记录。KEYI_USERS键对当前系统的所有用户信息进行组织。HKEY_CURRENT_CONFIG和HKEY_DYN_DATA键则分别对硬件配置信息和同动态注册相关的数据信息进行记录。
Windows提供了近30个API函数用于访问系统注册表,这些API函数提供了对注册表进行键的创建、打开、关闭、删除和对键值的设置、删除等功能。通常对注册表比较常用的操作不外乎对键或键值的添加、删除与修改等,而注册表中的各个键均有其特定的作用,通过对这些键的访问和对键值的适当修改可以获取到几乎所有的同系统有关的软、硬件信息并可对系统性能进行优化。例如,有关用户的信息位于系统注册表的HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\下(对于Windows 2000 Professional而言),键值名RegisteredOwner和RegisteredOrganization分别表示用户的姓名和公司名称。如需要在程序中获取该信息,只要访问此键值的内容即可。
读取注册表中某个键值的内容首先要通过RegOpenKey()或RegOpenKeyEx()函数打开相应的键,然后再调用RegQueryValue()或RegQueryValueEx()检索指定键值的内容,操作完成后调用RegClosefKey()将打开的键关闭,结束对注册表的访问。其中RegOpenKeyEx()和RegQueryValueEx()的功能比较强大,分别是对RegOpenKey()和RegQueryValue()在功能上的扩展,其函数原型为:
LONG RegOpenKeyEx(HKEY hKey, // 待打开的预定义键 LPCTSTR lpSubKey, // 待打开的子键的地址 DWORD ulOptions, // 保留 REGSAM samDesired, // 安全访问掩码 PHKEY phkResult // 打开的键的地址 ); LONG RegQueryValueEx(HKEY hKey, // 待检索的键 LPTSTR lpValueName, // 要检索的键值名称的地址 LPDWORD lpReserved, // 保留 LPDWORD lpType, // 键值类型的地址 LPBYTE lpData, // 存放检索结果的缓存的地址 LPDWORD lpcbData // 缓存长度的地址 ); |
最后,给出了通过访问注册表键值而得到用户注册信息的简单程序示例,该示例片段展示了对系统注册表指定键的打开、检索以及关闭等基本处理过程:
// 打开键 HKEY hKEY; LPCTSTR Rgspath = "Software\\Microsoft\\Windows NT\\CurrentVersion"; LONG ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, Rgspath, 0, KEY_READ, &hKEY); if(ret != ERROR_SUCCESS) { RegCloseKey(hKEY); return; } // 读取键值内容 DWORD dwInfoSize; DWORD type = REG_SZ; BYTE UserInfo[255]; ret = RegQueryValueEx(hKEY, "RegisteredOwner", NULL, &type, UserInfo, &dwInfoSize); if(ret!=ERROR_SUCCESS) { RegCloseKey(hKEY); return; } …… // 关闭键 RegCloseKey(hKEY); |