vc 註冊表編程

註冊表編程下,用不同的方法實現對其的讀取與寫入: 

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 ;
}
發佈了11 篇原創文章 · 獲贊 13 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章