0%

注册表介绍

下面内容摘自网络:http://www.sohu.com/a/232058468_99914465

注册表的结构包括六大分支(有的是五大分支,如果是五大分支,就没有hkey-dyn-data这一结构),注册表编辑器与资源管理器的界面相似。

注册表编辑器左窗格显示六大分支,右窗格是相应的键值项。我们编辑注册表,就是修改和增加相应的键值项。

注册表的六大分支结构如下:

hkey-classes-root该主关键字包含了有关的OLE信息,以便在系统工作过程中实现对各种文件和文档信息的访问。具体的内容有已经注册的文件扩展名、文件类型、文件图标等。

hkey-current-user是一个指向HKEY_USERS结构中某个分支的指针,它包含当前用户的登录信息。实际上它就是HKEY_USERS\Default下面的一部分内容,如果在HKEY_USERS\Default下面没有用户登录的其它内容,那么这两个主关键字包含的内容是完全相同的。

hkey-local-machine该关键字包含了本地计算机(相对网络环境而言)的硬件和软件的全部信息。当系统的配置和设置发生变化时,本关键字下面的登录项也将随之改变。

hkey-users 所有登录用户的信息。

hkey-current-config这个关键字实际上也是指向HKEY_LOCAL _MACHINE\Config结构中的某个分支的指针。HKEY_CURRENT_CONFIG下面的子关键字及内容与HKEY_LOCAL _MACHINE\Config\0001分支下面的子关键字及内容是完全相同的。本关键字包含的主要内容是计算机的当前配置情况,如显示器、打印机等可选外部设备及其设置信息等,而且这个配置信息均将根据当前连接的网络类型、硬件配置以及应用软件的安装不同而有所变化。

hkey-dyn-data 即插即用和系统性能的动态信息。

对于 Windows98 来说包含了六个主键,而在 Windows 2003/2000/XP 中没有 HKEY_DYN_DATA 主键,所以对于 Windows 2003/2000/XP 来说只有五个主键。

注册表中的键值项数据可分为如下三种类型:

1.字符串值(S)

在Windows98的注册表中,表示文件的描述、硬件的标识等等信息一般都用字符串值。字符串值由字母和数字组成,它的最大长度不能超过255个字符。通过键、键值就组成了一种键值项数据,这就相当于Win.ini、Ssytem.ini文件中每个小节下面的设置行一样的道理。

2.二进制值(B)

在Windows的注册表中,二进制值是没有长度限制的,可以是任意个字节长。在注册表编辑器中,二进制以十六进制的方式显示出来。

3.DWORD值(D)

在Windwos98的注册表中,DWORD值是一个32位(双字节长)长度的数值。在注册表编辑器中,系统以十六进制的方式显示DWORD值。

主要是我不想敲键盘了哈哈哈。
那么我们看一下微软给我们编写他的一些操作函数吧。

打开关闭子键RegCreateKeyExRegCloseKey

关闭打开是操作注册表最基本的一些操作了,首先是RegCreateKeyEx这个函数参数有点多,但是还是很好理解的。

1
2
3
4
5
6
7
8
9
10
11
12
LONG RegCreateKeyEx(
HKEY hKey, // handle to an open key
LPCTSTR lpSubKey, // address of subkey name
DWORD Reserved, // reserved
LPTSTR lpClass, // address of class string
DWORD dwOptions, // special options flag
REGSAM samDesired, // desired security access
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
// address of key security structure
PHKEY phkResult, // address of buffer for opened handle
LPDWORD lpdwDisposition // address of disposition value buffer
);
  1. hKey:这个值其实是一个之前已经打开的键或者说是那六个根键
  • HKEY_CLASSES_ROOT
  • HKEY_CURRENT_CONFIG
  • HKEY_CURRENT_USER
  • HKEY_LOCAL_MACHINE
  • HKEY_USERS
  • Windows NT: HKEY_PERFORMANCE_DATA
  • Windows 95 and Windows 98: HKEY_DYN_DATA
  1. lpSubKey:指向以null结尾的字符串的指针,该字符串指定此函数打开或创建的子键的名称。指定的子键必须是由hKey参数标识的键的子键。此子键不能以反斜杠字符(‘')开头。此参数不能为空。
  2. dwOptions:指定键的特殊选项。此参数可以是以下值之一。
  • REG_OPTION_NON_VOLATILE 重启不丢失
  • REG_OPTION_VOLATILE 重启丢失
  • REG_OPTION_BACKUP_RESTORE
  1. samDesired:可以是下面这几个值:
  • KEY_ALL_ACCESS Combination of KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, KEY_CREATE_SUB_KEY, KEY_CREATE_LINK, and KEY_SET_VALUE access.
  • KEY_CREATE_LINK Permission to create a symbolic link.
  • KEY_CREATE_SUB_KEY Permission to create subkeys.
  • KEY_ENUMERATE_SUB_KEYS Permission to enumerate subkeys.
  • KEY_EXECUTE Permission for read access.
  • KEY_NOTIFY Permission for change notification.
  • KEY_QUERY_VALUE Permission to query subkey data.
  • KEY_READ Combination of KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY access.
  • KEY_SET_VALUE Permission to set subkey data.
  • KEY_WRITE Combination of KEY_SET_VALUE and KEY_CREATE_SUB_KEY access.
  1. phkResult这个返回我们打开的一个句柄。
  2. lpdwDisposition:下面这几个值:
  • REG_CREATED_NEW_KEY The key did not exist and was created.
  • REG_OPENED_EXISTING_KEY The key existed and was simply opened without being changed.

还是比较好理解的,英语看不懂的稍微百度一下就好了,一般看名字就知道什么意思了。

1
2
3
LONG RegCloseKey(
HKEY hKey // handle to key to close
);

这个及时用来关闭的,就一个参数。

删除子键RegDeleteKey

删除一个子键用函数:RegDeleteKey
参数很是简单:

1
2
3
4
LONG RegDeleteKey(
HKEY hKey, // handle to open key
LPCTSTR lpSubKey // address of name of subkey to delete
);

但是在这里需要注意的是,只有所有有关这个子键的句柄都被关闭了之后才会删除完毕,而且好像在老板的电脑里面我们的这个函数是不支持递归删除的,现在好像已经支持了,再说了,在往前几年,都不用注册表,用个什么C盘里面的ini配置文件我记得,当时32位操作系统还没有很普及,这个应该是16位操作系统时候的了,具体的我也忘记了,反正是很老了。

键值操作

首先是设置一个键值,我们用到的函数是:RegSetValueEx,函数的原型:

1
2
3
4
5
6
7
8
LONG RegSetValueEx(
HKEY hKey, // handle to key to set value for
LPCTSTR lpValueName, // name of the value to set
DWORD Reserved, // reserved
DWORD dwType, // flag for value type
CONST BYTE *lpData, // address of value data
DWORD cbData // size of value data
);
  1. dwType这个参数是用来设置一些flag的,具体的可以是下面几个值(比较常用的我复制的是):
  • REG_BINARY
  • REG_DWORD
  • REG_EXPAND_SZ
  • REG_MULTI_SZ
  • REG_SZ

其他参数都是比较好理解的。

读取键值:RegQueryValueEx,函数原型:

1
2
3
4
5
6
7
8
LONG RegQueryValueEx(
HKEY hKey, // handle to key to query
LPTSTR lpValueName, // address of name of value to query
LPDWORD lpReserved, // reserved
LPDWORD lpType, // address of buffer for value type
LPBYTE lpData, // address of data buffer
LPDWORD lpcbData // address of data buffer size
);

这个函数基本上没啥太大的难度,但是这种函数又是比较典型的二次函数(我自己起的名字),意思就是说这种函数我们在调用的过程中我们需要调用两次。
主要的特别之处在于我们的最后一个参数的长度是不确定的,所以我们在第一次调用这个函数的时候可以读取数据类型,如果类型符合我们就读取实际数据。
主要的特点:

  1. lpData这个参数设置为NULL的时候我们的lpcbData这个参数返回我们的真是数据长度
  2. 上述两个参数如果都是NULL的话呢,我们的类型将会返回给我们

删除键值:RegDeleteValue,函数原型:

1
2
3
4
LONG RegDeleteValue(
HKEY hKey, // handle to key
LPCTSTR lpValueName // address of value name
);

这个函数也是比较的简单,参数也是很明显的。

注册表实例-开机自动启动

其实这类的东西做时间长了发现其实就是一个思路,就是写写注册表,基本上靠平常日无聊时候看看网站收集到的。
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run这个注册表里面的东西就是开机自动启动项目,但是前提你的这个值类型为:REG_SZ。
示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <windows.h>
using namespace std;

int main()
{
HKEY hRoot = HKEY_LOCAL_MACHINE;
char *szSubKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";//不要忘记转义了哦
HKEY hKey;
//打开指定的子键
DWORD dwDis = REG_OPENED_EXISTING_KEY;//没有的话呢也不创建
if(RegCreateKeyEx(hRoot,szSubKey,0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hKey,&dwDis) != ERROR_SUCCESS)//重启不丢失,然后多要点权限 ,不成功就返回
return -1;
char szModleFile[MAX_PATH];
GetModuleFileName(NULL,szModleFile,MAX_PATH);//获取一下当前的文件名称
if(RegSetValueEx(hKey,"Ceshi",0,REG_SZ,(BYTE*)szModleFile,strlen(szModleFile)) == ERROR_SUCCESS)
{
cout<<"success!"<<endl;
}else
{
cout<<"fail!"<<endl;
}
RegCloseKey(hKey);
return 0;
}

有一点需要注意的是,我们在Win8或Win10之类的高版本平台上运行,我们需要给他管理员哦,否则也是不行的!