windows登錄檔程式設計
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"
執行之後 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);
}