註冊表編程下,用不同的方法實現對其的讀取與寫入:
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 ;
}