前言
今天看了一本注册表方面的书,觉得还不错。特别还写了一章注册表编程。呵呵,我现在就我的理解把它贴上来给大家分享一下:)
什么是注册表我不用说了吧,反正大家都知道了。不知道?其实注册表就是...就是...就是那么回事了,具体我也说不清楚。有一点是可以肯定的,通过修改注册表可以产生很牛的效果,比如说自动运行啊,隐藏驱动器之类的,反正很多用拉,数不清的。又比如说现在有n多软件功能丰富,其实都是在把注册表改来改去。呵呵,说了这么多废话,不好意思,恩,现在开始吧。
操作注册表主要还是要靠API了,我数一下,1,2,3,...很多,就写一些比较常用的吧。不知道为什么,有这么多的注册表API,MS却没有把它们封装成一个类,很不爽。好了,先介绍一个操作注册表的一个重要变量类型:HKEY,一看这个类型以H开头,就知道它是一个句柄。什么是句柄我也不太懂,但是好象凡是win32编程都要用到句柄,按定义的话句柄是一个void *,可是又和平时说的指针不太一样。不管怎么说,HKEY就是一个Handle to a registry key,MSDN上是这样写的。翻译过来应该是一个注册表键的句柄,不知道对不对,唉,都怪我E文没学好,让大家笑了。在操作注册表的时候都要用到一个这样的句柄。好了,说了这么多先介绍几个API吧。
一。RegCreateKeyEx
恩,来看看RegCreateKeyEx吧,一看这个函数的字面意思就知道是创建一个键。如果这个键已经存在的话,就相当是把它打开了。对了,还有个概念没说,什么是键。其实我一句话也说不清就有点象一个文件夹那样的,还不懂的话...不说了。这个函数的声明是这样的:
LONG RegCreateKeyEx(
HKEY hKey,
LPCTSTR lpSubKey,
DWORD Reserved,
LPTSTR lpClass,
DWORD dwOptions,
REGSAM samDesired,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
PHKEY phkResult,
LPDWORD lpdwDisposition
);
我来数一数,1,2,3...我靠,一共九个参数,累死我了。这么多参数怎么用呢?看一下。
hKey:这是一个已经打开的键的句柄,看来是要在一个已经打开的键建立一个子键了。就好象在一个已经存在的目录下建立一个字目录一样。对了,如果你开始没有一个已经打开的键的句柄,怎么办呢?有办法的,hKey还可以是如下的值:
HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
HKEY_PERFORMANCE_DATA(WinNT&&Win2K)
HKEY_DYN_DATA(Win98&&Win95&&WinMe)
其实一般情况下hKey的值都是这几种。具体是什么意思嘛,打开注册表编辑器就看见了:)打个比方就象你的电脑有A,C,D..几个盘一样,注册表也有几个这样的东西就是了。
lpSubKey:一个字符串,不用说是什么意思了吧?就是说你要把你的注册表键放在哪个位置了。有两点注意了,首先lpSubKey不能为NULL,还有就是(/),要写成(//)。
Reserved:没什么用,必须是0。
lpClass:又是一个字符串,据说是指定你要建立的键的类型,我也不知道怎么用就设它为NULL算了。
dwOptions:对你建立的键的一些选项。可以是这些值:REG_OPTION_NON_VOLATILE,
REG_OPTION_VOLATILE,
REG_OPTION_BACKUP_RESTORE
第一个是默认的了。一般用第一个就可以了。
samDesired :好象是你对这个新建的键的访问权限了,笑话,我自己建的我我当然要设置为KEY_ALL_ACCESS,也就是想怎么样就怎么样的那种。
lpSecurityAttributes:很麻烦,懒得说了,反正也不是很重要,还是把它设为NULL。
phkResult:这可是个很重要的参数了,你建立一个键后,这个键的句柄就放在这里,以后操作就全靠它了。注意了,它是一个指向HKEY的指针。
lpdwDisposition:又是一个指针,调用完此函数后,可以通过它来检测是打开了一个已经存在的键(REG_OPENED_EXISTING_KEY),还是建立了一个键(REG_CREATED_NEW_KEY)。
还有一个问题,就是返回值的问题,如果返回ERROR_SUCCESS,也就是0了,恭喜恭喜,成功了。最后举个例吧:
#include<windows.h>
void main()
{
DWORD dwRes;
HKEY hk;
RegCreateKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE//Carrier Studio//Hello",
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hk,
&dwRes
);
if (dwRes == REG_CREATED_NEW_KEY)
{
printf("new key!!/n");
}
}
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
二。RegOpenKeyEx,以及RegCloseKey
先说一下RegOpenKeyEx,看字面的意思就知道是打开一个键,由于RegCreateKeyEx也可以打开一个键的,所以这个函数就有点那个了。不过这个函数比RegCreateKeyEx简单n倍,所以还是很有用的了。它是这样声明的:
LONG RegOpenKey(HKEY hKey,LPCTSTR lpSubKey,PHKEY phkResult);
一看,这些参数是不是很熟悉了啊?hKey,lpSubKey,phkResult的意思和RegCreateKeyEx函数中这些参数的意思没什么两样了。这里不多说了,到上一节去看看就知道了。返回值还是老样子,ERROR_SUCCESS就表示成功打开了。
再来看看RegCloseKey,很简单,只有一个参数:
LONG RegCloseKey(HKEY hKey) 就是关闭一个键了,关闭一个键以后,句柄就没用了。我不知道关闭一个键了和不关有什么不同,不过养成随时关闭的习惯总是有好处的。返回值?不用说,同上。
三。RegSetValueEx
RegSetValueEx,也就是已经知道一个键句柄了,对这个键的数据进行新建或改写。就好象已经知道一个文件夹,然后对其中的文件改动。一看就知道很有用了。对一些系统的数据改动的话,可以产生很牛的效果!!!啊,真是振奋人心啊!!!不过不要乱改啊,把系统该坏了别找我啊。少说废话了,看一下怎么用的:
LONG RegSetValueEx(
HKEY hKey,
LPCTSTR lpSubKey,
DWORD Reserved,
DWORD dwType,
LPCTSTR lpData,
DWORD cbData
);
hKey:不用说了吧?
lpSubKey:字符串,就是你要设置的数据项的名字了,就好象文件名那样。
Reserved:没用,必须是0。
dwType:数据的类型,有很多种,我只说两种常用的了。REG_SZ和REG_DWORD,就是字符串型和DWORD(unsigned long)型了。一般就是这两种的。
lpData:就是你要设置的数据了,如果是字符串的话,先要把首地址强制转化成无符号型的指针,再传过去。如果是整数的话,先取地址,再强制转化成无符号型的字符指针,再串过去。
DWORD cbData:你要设置的数据的长度,如果是字符串型的,则是strlen+1。如果是整数就是4了。返回值同上。
还是举个例吧:
#include<windows.h>
void main()
{
DWORD dwRes;
HKEY hk;
char szName[4]="我";
DWORD dwScore=100;
RegCreateKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE//Carrier Studio//Hello",
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hk,
&dwRes
);
RegSetValueEx(hk,"Name",0,REG_SZ,(LPBYTE)szName,3);
RegSetValueEx(hk,"Score",0,REG_DWORD,(LPBYTE)dwScore,4);
RegCloseKey(hk);
}
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
三。RegQueryValueEx和RegEnumValue
以上都是在说如何写注册表,不过很多情况下都要读注册表的。啊,来看一下有哪几个API,1,2,...怎么又这么多?算了,就说两个吧,应该够用了的。还是先说一下RegQueryValueEx吧,这回看不出什么意思了,Query是什么意思呢?别急,我先查一下字典,Query,Query,查到了,字典说是"怀疑"的意思,好象解释不通啊。唉,还是不要查了,早知道就装金山快译了。不说废话了,还是直说用法算了。这个函数就是说已知一个数据项的名字,然后去访问它的值,来看看声明:
LONG RegQueryValueEx(
HKEY hKey,
LPTSTR lpValueName,
LPDWORD lpReserved,
LPDWORD lpType,
LPBYTE lpData,
LPDWORD lpcbData
);
hKey和lpValueName不说了,和RegSetValueEx的前两个参数意思是一样的,不明白的话,看上一章可以了:)
lpReserved:真是受不了啊!又是一个没用的参数,必须是NULL.
lpType,lpData,lpcbData:和RegSetValueEx的后面3个参数意思差不多的,只不过lpType和lpcbData要取地址。不多说了。不懂直接问我算了。
返回值?不用说,还是同上。
好了好了,说到哪里了?哦,该说RegEnumValue了,这个意思我懂,Enum就是枚举的意思,那这个函数就是枚举一个键下的所有值了。好了,开门见山,我就直说它怎么用了。
LONG RegEnumValue(
HKEY hKey,
DWORD dwIndex,
LPTSTR lpValueName,
LPDWORD lpcbValueName,
LPDWORD lpReserved,
LPDWORD lpType,
LPBYTE lpData,
LPDWORD lpcbData
);
有没搞错,又是这么多参数,受不了MS了。唉,没办法,还是一个一个的看吧。
hKey:不说了,同上。
dwIndex:就是索引号了从0开始的,0,1,2....一直下去,就可以找出所有的值了。
lpValueName:找到一个值后,它的名字就保存在这里了。显然是一个字符串。
lpcbValueName:就是lpValueName的长度了,别忘了取地址。
lpReserved:又一个保留的,NULL。
lpType:和RegSetValueEx的dwType差不多,不过这个要取地址,它告诉你这个值是什么类型的。
lpData,lpcbData,返回值:累死我了,不说了,同上。
好象说得不太清楚,不要怪我,不懂可以问我了。恩,还是举个例吧,实例最能说明问题(记不得谁说的了):
for (int i = 0;dwRes==0;i++)
{
DWORD cbV=32,cbD=32;
BYTE szData[32];
char szValue[32];
dwRes = RegEnumValue(hk, i, szValue,&cbV, NULL, NULL,szData,&cbD);
......//自己写
}
这一章就写到这里吧。
四。RegDeleteValue和RegDeleteKey
太简单了,懒得说了,但为了对得起大家,还是说一下吧:
LONG RegDeleteKey(HKEY hKey,LPCTSTR lpSubKey);
LONG RegDeleteValue(HKEY hKey,LPCTSTR lpValueName);
就这么简单,一个删除键,一个删除值。不用我说了吧。
后记。
不知不觉写了这么多,看一下表,哎哟,11点了,赶快睡觉。水平有限,写错了大家不要笑啊。<^_^>
等一下,我看写了多少个API:1,2,3...8个,不是很多,不当之处,高手指点一下啊。