Windows注册表
1 注册表的作用
注册表在windows中非常重要,它是一个庞大的数据库,里面保存了大量的系统信息,例如保存软件硬件的配置信息,计算机系统的设置,性能记录。
如果注册表遭到破坏,就可能对整个系统造成影响,甚至系统瘫痪。
2 注册表的结构
注册表是树状的层次结构:主键-->子键-->子键-->子键-->……-->键值。其中每一个键都有键值,键值由3部分构成:值名,值类型,值本身值。有点像int x =0的节奏哈。 每个键都有一个默认的值,所以的默认值就是说这个值没有名字。当然可以为这个键再增加其他值,前提是这些值得有名字。
3 注册表的主键
<1>HkEY_USERS
<2>HKEY_CURRENT_USER
<3>HKEY_CURRENT_CONFIG
<4>HKEY_CLASSES_ROOT
<5>HKEY_LOCAL_MACHINE
<6>HKEY_DYN_DATA
这个键保存了系统在运行时候的动态数据,因为每次显示的时候都是变化的,所以此根键下的信息没有放在注册表中。
4访问注册表的权限
有时候程序执行时候会出现如下的错误,例如下面的代码:
LONG x1 =RegCreateKey(HKEY_LOCAL_MACHINE,TEXT("software\\VC++MFC\\adminss"),&hKey);
运行之后 x1 = 5,对应的错误信息就是“拒绝访问”。当然这句程序执行后不会在注册表中创建键,原因就是前面的说的没有权限,具体就是当前登陆的用户没有权限访问注册表。
解决方法:
注册表-->编辑-->权限-->添加(组和用户名)-->输入对象名称来选择-->检查名称-->确定
然后就会在组和用户列表中出现了你所添加的账户名。单击它,查看它具有的操作注册表的权限。
5 访问注册表的常用函数
我们可以像访问文件一样,对注册表进行键值创建,键值打开,键值读取,键值写的操作。常用的函数如下所示:
<1>RegCreateKey
LONG WINAPI RegCreateKey( _In_ HKEY hKey, _In_opt_ LPCTSTR lpSubKey, _Out_ PHKEY phkResult );
返回值:表示注册表访问失败的错误ID,只有返回值是ERROR_SUCCRSS(0)表示成功访问,其他都表示各种各样的错误。
hKey:指向当前打开表项的句柄,或者预定义的保留句柄之一,HKEY_CLASSES_ROOT,HKEY_USERS,HKEY_CURRENT_USER,HKEY_CURRENT_CONFIG,HKEY_LOCAL_MACHINE.
lpSubKey:一个空’\0’结束的字符串,表示要创建或者打开的键的名称
phkResult:返回值,指向要创建或者打开的键的句柄。不再使用时用RegCloseKey函数关闭。
示例:
RegCreateKey(HKEY_LOCAL_MACHINE,TEXT("software\\VC++MFC\\adminss"),&hKey);
结果:
运行程序我们可以在注册表中看到新创建的键
<2>RegOpenKey
LONG WINAPI RegOpenKey( _In_ HKEY hKey, _In_opt_ LPCTSTR lpSubKey, _Out_ PHKEY phkResult );
hKey,lpSubKey同RegCreateKey中的同名参数,phkResult表示当前打开的键值的句柄
<3>RegSetValue
LONG WINAPI RegSetValue( _In_ HKEY hKey, _In_opt_ LPCTSTR lpSubKey, _In_ DWORD dwType, _In_ LPCTSTR lpData, _In_ DWORD cbData );
hKey,lpSubKey同上面函数。另外一个键的值有三个属性,值名字,值类型,值本身值。这个函数设置的键是默认值(没有名字),dwType表示值类型,lpData表示设置的值,cbData表示当前设置值的长度。
注意:当lpSubKey = NULL的时候,此时设置的值是句柄hKey表示的键的值。
<4>RegSetValueEx
当要设置键的有名字的知道时候,就需要使用这个函数了
LONG WINAPI RegSetValueEx( _In_ HKEY hKey, _In_opt_ LPCTSTR lpValueName, _Reserved_ DWORD Reserved, _In_ DWORD dwType, _In_ const BYTE *lpData, _In_ DWORD cbData );
lpValueName:表示键的名字
Reserved:保留值,必须设为0
dwType:值类型。可以为REG_SZ,REG_DWORD,等等
lpData:值的值,指向一个缓冲区,代表值的值
cbData:lpData参数指向数据的大小,单位是字节
示例如下:
RegSetValueA(hKey,NULL,REG_SZ,TEXT("fun for Test"),strlen(TEXT("fun for Test")) ); RegSetValueA(hKey,TEXT("Test"),REG_SZ,TEXT("fun for fun"),strlen(TEXT("fun for fun")) ); RegSetValueExA(hKey,TEXT("Test1"),0,REG_SZ,(const BYTE*)TEXT("funforname"),strlen(TEXT("fun forname"))); HKEY keyTest; //LONG x= RegOpenKey(HKEY_LOCAL_MACHINE,TEXT("Test"),&keyTest); RegOpenKey(HKEY_LOCAL_MACHINE,TEXT("software\\vc++mfc\\adminss\\Test"),&keyTest); RegSetValueEx(keyTest,TEXT("Test2"),0,REG_SZ,(const BYTE*)TEXT("Test'sname value"),strlen(TEXT("Test'sname value")));
结果:
同时也说明了在设置键值的时候,如果不存在键值就会创建键值。
<5>RegQueryValue
LONG WINAPI RegQueryValue( _In_ HKEY hKey, _In_opt_ LPCTSTR lpSubKey, _Out_opt_ LPTSTR lpValue, _Inout_opt_ PLONG lpcbValue );
hKey:指定的键句柄,或者预留的5大主键句柄
lpSubKey:子键的名字,当为NULL的时候表示的查询hKey代表的键默认值
lpValue:返回值
lpcbValue:指定lpValue代表的缓冲区的大小。仅仅是存放值的大小
<6> RegQueryValueEx
用这个可以查询键值有名字的时候的值
LONG WINAPI RegQueryValueEx( _In_ HKEY hKey, _In_opt_ LPCTSTR lpValueName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPDWORD lpType, _Out_opt_ LPBYTE lpData, _Inout_opt_ LPDWORD lpcbData );
lpValue:值的名字
lpReserved:保留值,必须为NULL
lpType:返回值,表示值的类型
lpData:返回值,表示值的自身内容
lpcbData:确定值自身内容的大学,不能设置为NULL
6 完整的函数代码:
void CmfcFileView::OnRegWrite() { // TODO: 在此添加命令处理程序代码 HKEY hKey; LPSTR buf; LONG x1 =RegCreateKey(HKEY_LOCAL_MACHINE,TEXT("software\\VC++MFC\\adminss"),&hKey); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER| FORMAT_MESSAGE_FROM_SYSTEM,NULL ,x1, MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),(LPTSTR)&buf,0,NULL); LocalFree(buf); RegSetValueA(hKey,NULL,REG_SZ,TEXT("fun for Test"),strlen(TEXT("fun for Test")) ); RegSetValueA(hKey,TEXT("Test"),REG_SZ,TEXT("fun for fun"),strlen(TEXT("fun for fun")) ); RegSetValueExA(hKey,TEXT("Test1"),0,REG_SZ,(const BYTE*)TEXT("funfor name"),strlen(TEXT("fun forname"))); HKEY keyTest; //LONG x =RegOpenKey(HKEY_LOCAL_MACHINE,TEXT("Test"),&keyTest); RegOpenKey(HKEY_LOCAL_MACHINE,TEXT("software\\vc++mfc\\adminss\\Test"),&keyTest); RegSetValueEx(keyTest,TEXT("Test2"),0,REG_SZ,(const BYTE*)TEXT("Test'sname value"),strlen(TEXT("Test'sname value"))); RegCloseKey(hKey); RegCloseKey(keyTest); } void CmfcFileView::OnRegRead() { // TODO: 在此添加命令处理程序代码 //get thedefault value of the key LONG sz; RegQueryValue(HKEY_LOCAL_MACHINE,TEXT("software\\vc++mfc\\adminss\\test"),NULL,&sz); TCHAR* pv = newTCHAR[sz]; RegQueryValue(HKEY_LOCAL_MACHINE,TEXT("software\\vc++mfc\\adminss\\test"),pv,&sz); deletepv; pv = NULL; //get thename value of the key DWORD sb,dwType; TCHAR v[20]; HKEY hKey; RegOpenKey(HKEY_LOCAL_MACHINE,TEXT("software\\vc++mfc\\adminss\\test"),&hKey); //RegQueryValueEx(hKey,TEXT("test2"),NULL,&dwType,(LPBYTE)v,&sb);//ok RegQueryValueEx(hKey,TEXT("test2"),NULL,&dwType,NULL,&sb); TCHAR* ps = newTCHAR[sb](); RegQueryValueEx(hKey,TEXT("test2"),NULL,&dwType,(LPBYTE)ps,&sb);//cann't pass NULL to the last parameter deleteps; ps = NULL; RegCloseKey(hKey); }
windows注册表编程