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: 在此添加控件通知處理程序代碼
}