注册表编程下,用不同的方法实现对其的读取与写入: API:创建步骤:创建键RegCreateKey()或RegCreateKeyEx(),打开键RegOpenKey()或RegOpenKeyEx(),写入注册表RegSetvalue()或是RegSetvalue(),关闭RegCloseKey () 读取步骤 打开键RegOpenKey()或RegOpenKeyEx(),读取数据RegQueryValue() 或RegQueryValueEx(),关闭RegCloseKey () 注册表存储在二进制文件中,Win32 API提供了大量的函数以便应用程序访问注册表。 1、 创建键: 1.1 RegCreateKey(HKEY hKey, // 已经打开的父键句柄 LPCTSTR lpSubKey,// 要新建的子键的名称 PHKEY phkResult }// 新建的子键的句柄 1.2 RegCreateKeyEx(HKEY hKey, // 已经打开的父键句柄 LPCTSTR lpSubKey,// 要新建的子键的名称 DWORD ulOptions, // 保留 (一般都是0) LPCTSTR lpClass,// 指向键的类别的字符串。如果键已经存在了,则该参数被忽略 REGSAM samDesired, // 安全访问掩码 LPSECURITY_ATTRIBUTES lpSecurityAttributes;该参数决定返回的键句柄是否能被子进程继承 PHKEY phkResult ,// 新建的子键的句柄 LPDWORD lpdwDisposition; // 如果是REG_CREATED_NEW_KEY:如果键不存在则创建;如果是 REG_OPENED_EXISTING_KEY:如果键已存在则打开该建; ) 2、 打开键: 2.1 RegOpenKey(HKEY hKey, // 已经打开的父键句柄 LPCTSTR lpSubKey, // 待打开的子键的名称 PHKEY phkResult ) // 打开的子键的句柄 2.2 LONG RegOpenKeyEx(HKEY hKey, // 已经打开的父键句柄 LPCTSTR lpSubKey, // 待打开的子键的名称 DWORD ulOptions, // 保留 (一般都是0) REGSAM samDesired, // 安全访问掩码 PHKEY phkResult // 打开的子键的句柄); 3、 写入注册表:RegSetValue(默认REG_SZ类型),RegSetValueEx(其他类型) 3.1RegSetValue(HKEY hKey, // 已经打开的父键句柄 LPCTSTR lpSubKey,// 待写入的键值名 DWORD dwType, //要设置的键值类型 LPBYTE lpData, //键值数据 DWORD cbData)//键值数据长度 3.2 RegSetValueEx(HKEY hKey, LPCTSTR lpValueName, DWORD Reserved,//默认为0 DWORD dwType, LPBYTE lpData, DWORD cbData) 4、 由注册表中读数据:RegQueryValue(默认REG_SZ类型),RegQueryValue Ex(其他类型) 4.1RegQueryValue( HKEY hKey, PCTSTR lpSubKey, LPTSTR lpValue, PLONG lpcbValue} 4.2LONG RegQueryValueEx( HKEY hKey, // 已经打开的父键句柄 LPCTSTR lpValueName, // 待读出的键值名 LPDWORD lpReserved, LPDWORD lpType,//读出的键值类型 LPBYTE lpData,//读出的键值数据 LPDWORD lpcbData)//读出的键值数据长度 5 关闭注册表 RegCloseKey(HKEY hKey ); 6. 删除子键 ReDeleteKey(HKEY hKey, LPCTSTR lpValueName); 7. 删除子键值 ReDeleteValue(HKEY hKey, LPCTSTR lpValueName); 8. 设置 子键的安全性 RegSetKeySecurity(hKey, OWNER_SECURITY_INFORMATION, &Security); 其中,Security是SECURITY_DESCRIPTOR结构的一个对象。除上面使用的WRITE_OWNER之外,对注册表键的访问权限还 有DELETE、READ_CONTROL、WRITE_DAC等标准访问权限以及注册表所专有的访问权限KEY_CREATE_LINK、 KEY_CREATE_SUB_KEY、KEY_EXECUTE、KEY_ENUMERATE_SUB_KEYS、KEY_NOTIFY、KEY_QUERY_VALUE、 KEY_SETVALUE、KEY_ALL_ACCESS、KEY_READ和KEY_WRITE等。 9. 保存子键信息到一个文件中 RegSaveKey(HKEY hKey, LPCTSTR lpFileName, LPSECURITY_ATTRIBUTES lpSecurityAttributes); lpFileName注意这个文件必须是不存在的,而且也不能有扩展名(否则RegRestoreKey()函无法读取)。 在使用这个函数时需要有SE_BACKUP_NAME权限,而这个权限是不可以在RegOpenKey()或是RegCreateKeyEx()中指定的。要做到这一点就必须提升程序的权限,其具体实现如下代码如示: #include <windows.h> #include <stdio.h> #include <stdlib.h> void main() { char strKey[]="Software\Microsoft\Internet Explorer"; LPTSTR szSaveFileName; HKEY key; // 申请备份权限 HANDLE hToken; TOKEN_PRIVILEGES tkp; if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken)) return; LookupPrivilegeValue(NULL,SE_BACKUP_NAME,&tkp.Privileges[0].Luid);//申请SE_BACKUP_NAME权限 tkp.PrivilegeCount=1; tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken,FALSE,&tkp,0,(PTOKEN_PRIVILEGES)NULL,0); //开始备份工作 szSaveFileName=LPTSTR("D:\KeyDate"); //注意文件不可存在否则无法成功 RegOpenKeyEx( HKEY_CURRENT_USER, (LPCTSTR)strKey, 0, KEY_ALL_ACCESS, &key); RegSaveKey(key,szSaveFileName, NULL); RegCloseKey(key); } 10.从一个文件中恢复子键信息到注册表 RegRestoreKey(HKEY hKey, LPCTSTR lpFileName, DWORD dwFlage); 此函数的前两个参数可以与RegSaveKey相同,而参数dwFlage为TRUE<REG_WHOLE_HIVE_VOLATILE>的话,是暂时恢复注册表,如果为FALSE<REG_WHOLE_NO_VOLATILE>则是永久修改注册表值。同样需要注意的是使用这个函数需要有SE_RESTORE_NAME权限。 11. 枚举键值信息 枚举键值信息的方法与枚举子键信息极为相似,可以用RegEnumValue函数实现,其函数原型如下: RegEnumValue( hkey, //被枚举的键句柄 dwIndex, //子键索引编号 lpValueName, //键值名称 lpcbValueName, //键值名称长度 lpReserved, //系统保留,指定为0 lpType, //键值数据类型 lpDate, //键值数据 lpcbDate //键值数据长度 ); 其实现代码如下: for(dwIndex=0;dwIndex<NameCnt;dwIndex++) //枚举键值 ...{ DateSize=MaxDateLen+1; NameSize=NameMaxLen+1; szValueName=(char *)malloc(NameSize); szValueDate=(LPBYTE)malloc(DateSize); /**//*参数定义请参照获取子键/键值信息部分...*/ RegEnumValue(hKey,dwIndex,szValueName,&NameSize,NULL,&Type,szValueDate,&DateSize);//读取键值 if(Type==REG_SZ) ...{ /**//*判断键值项类型并做其它操作......*/ } if(Type==REG_DWORD) ...{ } } 与枚举子键相似,在每次循环中应该重新设置 数据长度DateSize=MaxDateLen+1,键值名称长度NameSize=NameMaxLen+1。 11.枚举子键信息 枚举子键可以用API函数 RegEnumKeyEx来实现,调用RegEnumKeyEx时将返回子键的名称、长度和一些相关数据。如果想得到一个键下的全部子键的话应该循环调用,直到返回ERROR_NO_MORE_ITEMS为至,就说明已经枚举完了所有数据。 其函数原型如下: RegEnumKeyEx( hkey, //被枚举的键句柄 dwIndex, //子键索引编号 lpName, //子键名称 lpcbName, //子键名称长度 lpReserved, //系统保留,指定为0 lpClass, //子键类名 lpcbClass, //子键类名长度 lpftLastWriteTime//最后写入时间 ); 因为在之前我们已经通过RegQueryInfoKey函数获取了键的有关数据,所以在这里不再跟据ERROR_NO_MORE_ITEMS来实现了。 其实现代码如下: for(dwIndex=0;dwIndex<KeyCnt;dwIndex++) //枚举子键 ...{ KeySize=KeyMaxLen+1; //因为RegQueryInfoKey得到的长度不包括0结束字符,所以应加1 szKeyName=(char*)malloc(KeySize); /**//*参数定义请参照获取子键/键值信息部分...*/ RegEnumKeyEx(hKey,dwIndex,szKeyName,&KeySize,NULL,NULL,NULL,NULL);//枚举子键 printf(szKeyName); } 最后需要注意的是在每次调用RegEnumKeyEx前必须重新将KeySize的值设为KeyMaxLen缓冲区的大小,因为每次函数返回时KeySize的值会变成返回的键值的名称长度,随着循环次数这个值会变小,而可能出现无法枚举所有键值项的情况。 01 void CFileView::OnRegWrite() 02 { 03 HKEY hKey; 04 RegCreateKey(HKEY_LOCAL_MACHINE,"SoftWare\\www.colsir.com\\admin",&hKey); 05 RegSetValue(hKey,"1111",REG_SZ,"pan",strlen("pan")); 06 RegCloseKey(hKey); 07 } 08 void CFileView::OnRegRead() 09 { 10 LONG lValue; 11 RegQueryValue(HKEY_LOCAL_MACHINE,"SoftWare\\www.colsir.com\\admin",NULL,&lValue);//如果数据是不需要的这个参数可以为空 12 char *pBuf=new char[lValue]; 13 RegQueryValue(HKEY_LOCAL_MACHINE,"SoftWare\\www.colsir.com\\admin",pBuf,&lValue); 14 MessageBox(pBuf); 15 } BOOL GetLocalThenCopySet() { BOOL bLocalThenToDest = FALSE; DWORD dwDisposition,dwType,dwDest,dwSize = sizeof (DWORD); HKEY hKey; if(RegCreateKeyEx(HKEY_LOCAL_MACHINE,_T("SOFTWARE\\sony\\Compile\\"),0L,NULL,REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,NULL,&hKey,&dwDisposition) == ERROR_SUCCESS) { if(RegQueryValueEx(hKey,_T("LocalThenCopy"),NULL, &dwType,(BYTE *)&dwDest,&dwSize) == ERROR_SUCCESS) { bLocalThenToDest = dwDest; } else { RegSetValueEx(hKey,_T("LocalThenCopy"), 0L, REG_DWORD, (CONST BYTE*) &bLocalThenToDest, sizeof(DWORD)); } } RegCloseKey(hKey); return bLocalThenToDest ; }
|
|