c++ 操作登錄檔111
阿新 • • 發佈:2018-12-16
c++ 操作登錄檔 1. 登錄檔簡介 登錄檔是為Windows NT和Windows95中所有32位硬體/驅動和32位應用程式設計的資料檔案,用於儲存系統和應用程式的設定資訊。16位驅動在Winnt (Windows New Technology)下無法工作,所以所有裝置都通過登錄檔來控制,一般這些是通過BIOS(基本輸入輸出系統)來控制的。在Win95下,16位驅動會繼續以真實模式方式裝置工作,它們使用system.ini來控制。16位應用程式會工作在NT或者Win95 下,它們的程式仍然會參考win.ini和system.ini檔案獲得資訊和控制。 2. 登錄檔結構 2.1. 簡介 登錄檔是是Microsoft Windows中的一個重要而又複雜的資訊資料庫,它是多層次式的。在不同系統上登錄檔的基本結構相同。其中的複雜資料會在不同方式上結合,從而產生出一個絕對唯一的登錄檔。從使用者的角度看,登錄檔系統由兩個部分組成:登錄檔資料庫和登錄檔編輯器。登錄檔資料庫包括兩個檔案:system.dat和user.dat。system.dat用來儲存微機的系統資訊,如安裝的硬體和調和驅動程式的有關資訊等。user.dat用來儲存每個使用者特有的資訊,如桌面設定、牆紙或視窗的顏色設定等。由於登錄檔是最重要的系統檔案之一,因此對於它的保護和備份就特別重要。系統在每次成功啟動之後都將此次啟動時的登錄檔作一個備份。system.dat的備份檔案為system.dao,user.dat的備份檔案為user.dao。如果由於某種原因登錄檔受到破壞,則可以用這兩個備份檔案來恢復登錄檔。Win 98/Win Me備份的登錄檔檔案儲存在C:/WINDOWS/SYSBCKUP資料夾(這是個隱藏資料夾)中,檔名稱是rb000.cab、rb002.cab、rb003.cab、rb004.cab、rb005.cab(通常為五個)。 2.2. 資料結構 登錄檔由鍵(或稱“項”)、子鍵(子項)和值項構成。一個鍵就是分支中的一個資料夾,而子鍵就是這個資料夾中的子資料夾,子鍵同樣是一個鍵。一個值項則是一個鍵的當前定義,由名稱、資料型別以及分配的值組成。一個鍵可以有一個或多個值,每個值的名稱各不相同,如果一個值的名稱為空,則該值為該鍵的預設值。 登錄檔的資料型別主要有以下四種: 顯示型別(在編輯器中) 資料型別 說明 REG_SZ 字串 文字字串 REG_MULTI_SZ 多字串 含有多個文字值的字串 REG_BINARY 二進位制數 二進位制值,以十六進位制顯示 REG_DWORD 雙字 一個32位的二進位制值,顯示為8位的十六進位制值 2.3. 幾個主鍵簡介 (1)HKEY_CLASSES_ROOT 在登錄檔中HKEY_CLASSES_ROOT是系統中控制所有資料檔案的項。HKEY_CLASSES_ROOT控制鍵包括了所有檔案擴充套件和所有和執行檔案相關的檔案。它同樣也決定了當一個檔案被雙擊時起反應的相關應用程式。 HKEY_CLASSES_ROOT被用作程式設計師在安裝軟體時方便的傳送資訊,在Win95和Winnt中,HKEY_CLASSES_ROOT和HKEY_LOCAL_MACHINE/Software/Classes是相同的。程式設計師在執行他們的啟動程式時不需要擔憂實際的位置,相反的,他們只需要在HKEY_CLASSES_ROOT中加入資料就可以了。 (2)HKEY_CURRENT_CONFIG win95一般只使用一個硬體配置檔案。如果有多個硬體配置檔案。HKEY_LOCAL_MACHINE/Config中就會新增一個鍵。HKEY_LOCAL_MACHINE/Config包含了HKEY_LOCAL_MACHINE中相同的資料。 在啟動時,你可以選擇你願意使用的配置檔案。如果有多個安裝,每次系統重新啟動時,你就必須選擇。HKEY_CURRENT_CONFIG是在啟動時控制目前硬體配置的鍵。在系統啟動以後,任何地方的變化都會自動影響到它。程式設計師經常使用HKEY_CURRENT_CONFIG方便的來存取配置資訊。HKEY_CURRENT_CONFIG包括了系統中現有的所有配置檔案的細節。你的選擇影響了哪一個硬體配置檔案成為現在的。舉例來說,如果配置0002被選擇了,所有0002的配置資訊會被對映到這些鍵上。HKEY_CURRENT_CONFIG允許軟體和裝置驅動程式設計師很方便的更新登錄檔,而不涉及到多個配置檔案資訊。 HKEY_LOCAL_MACHINE中同樣的資料和任何登錄檔的變化都會同時的變化。 (3)HKEY_USERS HKEY_USERS將預設使用者和目前登陸使用者的資訊輸入到登錄檔編輯器,在win95中,它僅被那些配置檔案啟用的登陸使用者使用,同樣在winnt下,它也是這樣。 win95從user.dat中取得他們的資訊,winnt從ntuser.dat中取得資訊。.dat檔案包含了所有基於使用者的登錄檔設定並且允許你取配置這些使用者的環境。如果你改變了預設使用者的設定,所有新使用者會繼承同樣的設定。而且,那些已經被建立的使用者變的失效。 (4)HKEY_LOCAL_MACHINE HKEY_LOCAL_MACHINE是一個顯示控制系統和軟體的處理鍵。HKLM鍵儲存著計算機的系統資訊。它包括網路和硬體上所有的軟體設定。(比如檔案的位置,註冊和未註冊的狀態,版本號等等)這些設定和使用者無關,因為這些設定是針對使用這個系統的所有使用者的。 (5)HKEY_CURRENT_USER HKEY_CURRENT_USER包含著在HKEY_USERS安全辨別裡列出的同樣資訊。任何在HKEY_CURRENT_USER裡的改動也都會立即HKEY_USERS改動。相反也是這樣。 HKEY_CURRENT_USER允許程式設計師和開發者易於存取目前登陸使用者的設定。通過建立這個鍵,微軟很容易在不涉及到使用者的SID下改變,新增和設定。也就是說,所有當前的操作改變只是針對當前使用者而改變,並不影響其他使用者。 3. C++操作登錄檔 3.1. CRegKey 類及主要使用和函式說明 所需要標頭檔案:atlbase.h 常用函式 (1) 開啟一個鍵的函式: 1RegOpenKeyEx 函式定義:LONG RegOpenKeyEx(HKEY hKey,//已經開啟的鍵的控制代碼,或者直接是上述幾個根鍵 LPCTSTR lpSubKey,//要開啟的子鍵名字的地址 DWORD ulOptions,//保留值,必須為0 REGSAM samDesired,//開啟方式,如讀還是寫 PHKEY phkResult//返回的開啟的子鍵的控制代碼 ); 2RegOpenKey 這個函式與Windows 3.1相容。基於Win32的應用程式應該使用RegOpenKeyEx函式。 LONG RegOpenKey(HKEY hKey, // 要開啟鍵的控制代碼 LPCTSTR lpSubKey, // 要開啟子鍵的名字的地址 PHKEY phkResult // 要開啟鍵的控制代碼的地址 ); 注意:RegOpenKey這個函式與Windows 3.1相容。基於Win32的應用程式應該使用RegOpenKeyEx函式。 (2)查詢某一個鍵值:RegQueryValueEx 函式定義:LONG RegQueryValueEx(HKEY hKey,//要查詢的鍵的控制代碼 LPCTSTR lpValueName,//要查詢的鍵值的名稱 LPDWORD lpReserved,//保留值 LPDWORD lpType,//要查詢的資料的型別 LPBYTE lpData,//要返回的查詢的資料 LPDWORD lpcbData//預置的資料的長度 ); (3)設定一個鍵值RegSetValueEx 函式定義:LONG RegSetValueEx(HKEY hKey,//要設定的鍵的控制代碼 LPCTSTR lpValueName,//要訪問的鍵值的名稱 LPDWORD lpReserved,//保留值 DWORD dwType,//要設定的資料的型別 const BYTE *lpData,//要設定的健值 DWORD cbData//資料的長度 ); (4)新建指定鍵RegCreateKey 函式定義:LONG RegCreateKey (HKEY hkey, // 要開啟鍵的控制代碼 LPCTSTR lpsubkey, // 要開啟子鍵的名字的地址 PHKEY phkresult // 已開啟控制代碼的快取區的地址 ); 注意:如果這個鍵在登錄檔中已經存在,這個函式開啟它。 (5)刪除 1刪除登錄檔指定鍵下的值 LONG RegDeleteValue(HKEY hKey, //子鍵的控制代碼 LPCTSTR lpValueName //刪除鍵值的名稱 ); 2刪除登錄檔項 (登錄檔資料夾)就用 LONG RegDeleteKey(HKEY hKey, //已開啟的鍵的控制代碼 LPCTSTR lpSubKey //要刪除的子鍵或路徑 ); RegDeleteKey 也可用來刪除一個鍵值。在 Win 95/98 平臺下,也可用來刪除整個子鍵和鍵值。但是在Windows NT/2000平臺下,只能用來刪除沒有子鍵的鍵。 3刪除一個帶有很多子鍵值的鍵 DWORD SHDeleteKey(HKEY hkey,// 登錄檔開啟的鍵值的控制代碼 LPCTSTR pszSubKey //被刪除的鍵值名稱 ); 當然你得包含標頭檔案shlwapi.h,並且新增shlwapi.lib。 注意:這個函式很危險,如在你的程式中使用SHDeleteKey(hkey,NULL),將刪除HKEY_CURRENT_USER//SOFTWARE//Microsoft//Windows//CurrentVersion//Run下的所有值;如果使用SHDeleteKey(HKEY_CURRENT_USER,”SOFTWARE//Microsoft//Windows//CurrentVersion//Run”),將刪除HKEY_CURRENT_USER//SOFTWARE//Microsoft//Windows//CurrentVersion//Run這個鍵以及下面的所有子鍵和值。 3.2. 例項 (1)讀取登錄檔 1檢視HKEY_CURRENT_USER主鍵下Software//武漢帷幄資訊科技有限公司//施工工藝決策系統//系統配置//BCGPGanttControls//GanttChartBCGPGantt-0子鍵中名稱為GridProgressColumnIndex的值,其型別為DWORD。 void OnBnClickedQuery() //響應按鈕IDC_QUERY { HKEY hKEY;//定義有關的hKEY,在查詢結束時要關閉 //開啟與路徑data_Set相關的hKEY LPCTSTR data_Set= _T("/Software//武漢帷幄資訊科技有限公司//施工工藝決策系統//系統配置//BCGPGanttControls//GanttChartBCGPGantt-0"); //訪問登錄檔,hKEY則儲存此函式所開啟的鍵的控制代碼 if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_CURRENT_USER,data_Set,0,KEY_READ,&hKEY)) { DWORD dwValue; DWORD dwSize = sizeof(DWORD); DWORD dwType = REG_DWORD; if (::RegQueryValueEx(hKEY,_T("GridProgressColumnIndex"), 0, &dwType, (LPBYTE)&dwValue, &dwSize) != ERROR_SUCCESS) { AfxMessageBox(_T("錯誤:無法查詢有關的登錄檔資訊")); } //程式結束,關閉開啟的hKEY ::RegCloseKey(hKEY); } UpdateData(false); // TODO: 在此新增控制元件通知處理程式程式碼 } 可以看到讀取的登錄檔GridProgressColumnIndex的值是正確的。 2檢視HKEY_LOCAL_MACHINE主鍵下SOFTWARE//Microsoft//Windows NT//CurrentVersion子鍵中名稱為"SoftwareType的值,其型別為REG_SZ。 void OnBnClickedQuery() { HKEY hKEY;//定義有關的hKEY,在查詢結束時要關閉 //開啟與路徑data_Set相關的hKEY LPCTSTR data_Set= _T("SOFTWARE//Microsoft//Windows NT//CurrentVersion"); //訪問登錄檔,hKEY則儲存此函式所開啟的鍵的控制代碼 if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_LOCAL_MACHINE,data_Set,0,KEY_READ,&hKEY)) { char dwValue[256]; DWORD dwSzType = REG_SZ; DWORD dwSize = sizeof(dwValue); if (::RegQueryValueEx(hKEY,_T("SoftwareType"), 0, &dwSzType, (LPBYTE)&dwValue, &dwSize) != ERROR_SUCCESS) { AfxMessageBox(_T("錯誤:無法查詢有關的登錄檔資訊")); } //程式結束,關閉開啟的hKEY ::RegCloseKey(hKEY); } UpdateData(false); // TODO: 在此新增控制元件通知處理程式程式碼 } (2)寫登錄檔 1在HKEY_CURRENT_USER主鍵下寫一個Software//武漢帷幄資訊科技有限公司//test111子鍵,設定其名稱為Name,型別為DWORD,值為6。 void OnBnClickedChange()//響應按鈕IDC_CHANGE { HKEY hKey;//定義有關的hKEY,在查詢結束時要關閉 HKEY hTempKey; DWORD dwValue = 6; DWORD dwSize = sizeof(DWORD); DWORD dwType = REG_DWORD; //開啟與路徑data_Set相關的hKEY LPCTSTR data_Set= _T("Software//武漢帷幄資訊科技有限公司"); if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_CURRENT_USER, data_Set,0,KEY_SET_VALUE, &hKey)) { // 使用hKey來操作data_Set這個KEY裡面的值。 if (ERROR_SUCCESS == ::RegCreateKey(hKey, _T("test111"), &hTempKey)) {//背景色 if (ERROR_SUCCESS != ::RegSetValueEx(hTempKey, _T("Name"), 0, REG_DWORD, (CONST BYTE*)&dwValue, sizeof(DWORD))) { AfxMessageBox(_T("錯誤")); ::RegCloseKey(hKey); return; } } } ::RegCloseKey(hKey); // TODO: 在此新增控制元件通知處理程式程式碼 } 2在HKEY_CURRENT_USER主鍵下寫一個Software//武漢帷幄資訊科技有限公司//test111子鍵,設定其名稱為Name,型別為REG_SZ,值為China。 void OnBnClickedChange() { HKEY hKey;//定義有關的hKEY,在查詢結束時要關閉 HKEY hTempKey; CString m_name = "China"; LPBYTE m_name_Set = CString_To_LPBYTE(m_name);//定義x軸名稱 DWORD length = m_name.GetLength() + 1;//定義資料長度 //開啟與路徑data_Set相關的hKEY LPCTSTR data_Set= _T("Software//武漢帷幄資訊科技有限公司"); if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_CURRENT_USER, data_Set,0,KEY_SET_VALUE, &hKey)) { // 使用hKey來操作data_Set這個KEY裡面的值。 if (ERROR_SUCCESS == ::RegCreateKey(hKey, _T("test111"), &hTempKey)) { if (ERROR_SUCCESS != ::RegSetValueEx(hTempKey, _T("Name"), 0, REG_SZ, m_name_Set, length)) { AfxMessageBox(_T("錯誤")); ::RegCloseKey(hKey); return; } } } ::RegCloseKey(hKey); UpdateData(false); // TODO: 在此新增控制元件通知處理程式程式碼 } 3在HKEY_CURRENT_USER主鍵下寫一個Software//武漢帷幄資訊科技有限公司//test111子鍵,設定其名稱為Name,型別為REG_ BINARY,值為ff ac 05 4e。 void OnBnClickedChange() { HKEY hKey;//定義有關的hKEY,在查詢結束時要關閉 HKEY hTempKey; BYTE m_name[10]; memset(m_name, 0, sizeof(m_name));//將陣列m_name清零 m_name[0] = 0xff; m_name[1] = 0xac; m_name[2] = 0x05; m_name[4] = 0x4e; //開啟與路徑data_Set相關的hKEY LPCTSTR data_Set= _T("Software//武漢帷幄資訊科技有限公司"); if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_CURRENT_USER, data_Set,0,KEY_SET_VALUE, &hKey)) { // 使用hKey來操作data_Set這個KEY裡面的值。 if (ERROR_SUCCESS == ::RegCreateKey(hKey, _T("test111"), &hTempKey)) { if (ERROR_SUCCESS != ::RegSetValueEx(hTempKey, _T("Name"), 0, REG_BINARY,(unsigned char *)m_name,5)) { AfxMessageBox(_T("錯誤")); ::RegCloseKey(hKey); return; } } } ::RegCloseKey(hKey); UpdateData(false); // TODO: 在此新增控制元件通知處理程式程式碼 } (3)刪除登錄檔 1刪除HKEY_CURRENT_USER//Software//武漢帷幄資訊科技有限公司//test111的鍵值Name void OnBnClickedDelete() { HKEY hKey;//定義有關的hKEY,在查詢結束時要關閉 //開啟與路徑data_Set相關的hKEY LPCTSTR data_Set= _T("Software//武漢帷幄資訊科技有限公司//test111"); if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_CURRENT_USER, data_Set,0,KEY_SET_VALUE, &hKey)) { // 使用hKey來操作data_Set這個KEY裡面的值。 if (ERROR_SUCCESS != ::RegDeleteValue(hKey, _T("Name"))) { AfxMessageBox(_T("錯誤")); ::RegCloseKey(hKey); return; } } ::RegCloseKey(hKey); UpdateData(FALSE); // TODO: 在此新增控制元件通知處理程式程式碼 } 2刪除HKEY_CURRENT_USER//Software//武漢帷幄資訊科技有限公司下的子鍵 test111。 void OnBnClickedDelete() { HKEY hKey;//定義有關的hKEY,在查詢結束時要關閉 //開啟與路徑data_Set相關的hKEY LPCTSTR data_Set= _T("Software//武漢帷幄資訊科技有限公司"); if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_CURRENT_USER, data_Set,0,KEY_SET_VALUE, &hKey)) { // 使用hKey來操作data_Set這個KEY裡面的值。 if (ERROR_SUCCESS != ::RegDeleteKey(hKey, "test111")) { AfxMessageBox(_T("錯誤")); ::RegCloseKey(hKey); return; } } ::RegCloseKey(hKey); UpdateData(FALSE); // TODO: 在此新增控制元件通知處理程式程式碼 }