1. 程式人生 > >C/C++ Windows API——登錄檔

C/C++ Windows API——登錄檔

// RegDemo.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"
#include <locale.h>
#include <Windows.h>

int main()
{
    setlocale(LC_ALL, "chs");

    LSTATUS errorCode;
    HKEY rootHKey = HKEY_CURRENT_USER;
    /*
    注意:由於Vistual Studio使用Unicode編碼,所以這裡要用WCHAR,用char的話會返回2無法開啟(使用TCHAR可以相容二者)
    Key指的是左邊樹檢視中的任一節點
    */
    TCHAR *subKey = _T("Environment\\TestKey"
); //ValueName指的是右邊列表項的名字 LPCTSTR lpValueName = _T("TestValue"); DWORD reserved = 0; LPDWORD lpReserved = 0; DWORD dwType = REG_SZ; HKEY hkResult; /* //建立指定的註冊鍵。如果這個鍵已經存在,這個函式會開啟它。注意:鍵的名字大小寫不敏感。 WINADVAPI LSTATUS APIENTRY RegCreateKeyExW( _In_ HKEY hKey, //一個開啟項的控制代碼,或者一個標準項名
_In_ LPCWSTR lpSubKey, //建立的新子項的名字 _Reserved_ DWORD Reserved, //保留 _In_opt_ LPWSTR lpClass, //項的類名,定義了該鍵的型別,可以為NULL _In_ DWORD dwOptions, //一般是0。如果是REG_OPTION_VOLATILE,那麼該項不正式儲存下來,系統重新啟動後會消失 _In_ REGSAM samDesired, //帶有字首KEY_??的一個或多個常數。它們組合起來描述了允許對這個項進行哪些操作
_In_opt_ CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, //對這個項的安全特性進行描述的一個結構,一般是空指標 _Out_ PHKEY phkResult, //用於裝載新子項控制代碼的一個變數 _Out_opt_ LPDWORD lpdwDisposition //指示該操作是建立新子項還是開啟已有子項 ); dwOptions可以是下列值 #define REG_OPTION_RESERVED (0x00000000L) // Parameter is reserved #define REG_OPTION_NON_VOLATILE (0x00000000L) // Key is preserved // when system is rebooted #define REG_OPTION_VOLATILE (0x00000001L) // Key is not preserved // when system is rebooted #define REG_OPTION_CREATE_LINK (0x00000002L) // Created key is a // symbolic link #define REG_OPTION_BACKUP_RESTORE (0x00000004L) // open for backup or restore // special access rules // privilege required #define REG_OPTION_OPEN_LINK (0x00000008L) // Open symbolic link #define REG_LEGAL_OPTION \ (REG_OPTION_RESERVED |\ REG_OPTION_NON_VOLATILE |\ REG_OPTION_VOLATILE |\ REG_OPTION_CREATE_LINK |\ REG_OPTION_BACKUP_RESTORE |\ REG_OPTION_OPEN_LINK) #define REG_OPEN_LEGAL_OPTION \ (REG_OPTION_RESERVED |\ REG_OPTION_BACKUP_RESTORE |\ REG_OPTION_OPEN_LINK) samDesired可以是下列值 #define KEY_QUERY_VALUE (0x0001) #define KEY_SET_VALUE (0x0002) #define KEY_CREATE_SUB_KEY (0x0004) #define KEY_ENUMERATE_SUB_KEYS (0x0008) #define KEY_NOTIFY (0x0010) #define KEY_CREATE_LINK (0x0020) #define KEY_WOW64_32KEY (0x0200) Indicates that an application on 64-bit Windows should operate on the 32-bit registry view. This flag is ignored by 32-bit Windows. For more information, see Accessing an Alternate Registry View. This flag must be combined using the OR operator with the other flags in this table that either query or access registry values. #define KEY_WOW64_64KEY (0x0100) Indicates that an application on 64-bit Windows should operate on the 64-bit registry view. This flag is ignored by 32-bit Windows. For more information, see Accessing an Alternate Registry View. This flag must be combined using the OR operator with the other flags in this table that either query or access registry values. Either KEY_WOW64_32KEY or KEY_WOW64_64KEY can be specified. If both flags are specified, the function fails with ERROR_INVALID_PARAMETER. #define KEY_WOW64_RES (0x0300) #define KEY_READ ((STANDARD_RIGHTS_READ |\ KEY_QUERY_VALUE |\ KEY_ENUMERATE_SUB_KEYS |\ KEY_NOTIFY) \ & \ (~SYNCHRONIZE)) #define KEY_WRITE ((STANDARD_RIGHTS_WRITE |\ KEY_SET_VALUE |\ KEY_CREATE_SUB_KEY) \ & \ (~SYNCHRONIZE)) #define KEY_EXECUTE ((KEY_READ) \ & \ (~SYNCHRONIZE)) #define KEY_ALL_ACCESS ((STANDARD_RIGHTS_ALL |\ KEY_QUERY_VALUE |\ KEY_SET_VALUE |\ KEY_CREATE_SUB_KEY |\ KEY_ENUMERATE_SUB_KEYS |\ KEY_NOTIFY |\ KEY_CREATE_LINK) \ & \ (~SYNCHRONIZE)) lpdwDisposition可以是下列值 #define REG_CREATED_NEW_KEY (0x00000001L) // New Registry Key created #define REG_OPENED_EXISTING_KEY (0x00000002L) // Existing Key opened return 成功返回ERROR_SUCCESS,失敗返回錯誤碼,在<winerror.h>中定義 */ LPWSTR lpClass = NULL; LPSECURITY_ATTRIBUTES lpSecurityAttributes = 0; DWORD dwDisposition; errorCode = RegCreateKeyEx(rootHKey, subKey, reserved, lpClass, REG_OPTION_VOLATILE, KEY_READ | KEY_WRITE, lpSecurityAttributes, &hkResult, &dwDisposition); if (errorCode == ERROR_SUCCESS) { printf("RegCreateKeyEx -> hkResult=0x%x, dwDisposition=%ld\n", hkResult, dwDisposition); /* WINADVAPI LSTATUS APIENTRY RegSetValueEx( _In_ HKEY hKey, // 一個已開啟表項的控制代碼,或者指定一個標準項名(即登錄檔中的幾個根登錄檔項) _In_opt_ LPCTSTR lpValueName, // 指示這個函式將開啟或建立的表項的名稱。這個表項必須是由hkey引數所標識的子項。如果此值是NULL,或指向空字串,則此函式為該項的預設值或未命名值設定型別和資料。 _Reserved_ DWORD Reserved, // 保留值,必須強制為0 _In_ DWORD dwType, // 指定將被儲存的資料型別 _In_reads_bytes_opt_(cbData) CONST BYTE * lpData, // 指向一個緩衝區,該緩衝區包含了欲為指定值名稱儲存的資料。 _In_ DWORD cbData // 指定由lpData引數所指向的資料的大小,單位是位元組。 ); dwType可以是下列值 REG_BINARY 任何形式的二進位制資料 REG_DWORD 一個32位的數字 REG_DWORD_LITTLE_ENDIAN 一個“低位元組在前”格式的32位數字 REG_DWORD_BIG_ENDIAN 一個“高位元組在前”格式的32位數字 REG_EXPAND_SZ 一個以0結尾的字串,該字串包含對環境變數(如“%PAHT”)的未擴充套件引用 REG_LINK 一個Unicode格式的帶符號連結 REG_MULTI_SZ 一個以0結尾的字串陣列,該陣列以連線兩個0為終止符 REG_NONE 未定義值型別 REG_RESOURCE_LIST 一個裝置驅動器資源列表 REG_SZ 一個以0結尾的字串 return 成功返回ERROR_SUCCESS,失敗返回錯誤碼,在<winerror.h>中定義 */ LPCTSTR setData = _T("可惜不是你 - 梁靜茹"); errorCode = RegSetValueEx(hkResult, lpValueName, reserved, dwType, (BYTE*)setData, lstrlen(setData)*sizeof(TCHAR)); if (errorCode == ERROR_SUCCESS) { printf("RegSetValueEx -> succ\n"); } else { printf("RegSetValueEx fail(%ld)\n", errorCode); } //有些作業系統會將對登錄檔的修改延遲寫入磁碟,以便保持系統的高效能。這個函式的作用就是確定將資料實際寫入磁碟。但通常,應儘量避免使用這個函式,因為它可能嚴重影響一個應用程式的效能 errorCode = RegFlushKey(hkResult); if (errorCode == ERROR_SUCCESS) { printf("RegFlushKey succ\n"); } else { printf("RegFlushKey fail(%ld)\n", errorCode); } //釋放指定註冊鍵的控制代碼 errorCode = RegCloseKey(hkResult); if (errorCode == ERROR_SUCCESS) { printf("RegCloseKey succ\n"); } else { printf("RegCloseKey fail(%ld)\n", errorCode); } } else { printf("RegCreateKeyEx fail(%ld)\n", errorCode); } /* LONG RegOpenKeyEx( HKEY hKey, // 需要開啟的主鍵的名稱 LPCTSTR lpSubKey, // 需要開啟的子鍵的名稱 DWORD ulOptions, // 保留,設為0 REGSAM samDesired, // 安全訪問標記,也就是許可權 PHKEY phkResult // 得到的將要開啟鍵的控制代碼 ); HKEY可以是下列值 #define HKEY_CLASSES_ROOT (( HKEY ) (ULONG_PTR)((LONG)0x80000000) ) #define HKEY_CURRENT_USER (( HKEY ) (ULONG_PTR)((LONG)0x80000001) ) #define HKEY_LOCAL_MACHINE (( HKEY ) (ULONG_PTR)((LONG)0x80000002) ) #define HKEY_USERS (( HKEY ) (ULONG_PTR)((LONG)0x80000003) ) #define HKEY_PERFORMANCE_DATA (( HKEY ) (ULONG_PTR)((LONG)0x80000004) ) #define HKEY_PERFORMANCE_TEXT (( HKEY ) (ULONG_PTR)((LONG)0x80000050) ) #define HKEY_PERFORMANCE_NLSTEXT (( HKEY ) (ULONG_PTR)((LONG)0x80000060) ) #if (WINVER >= 0x0400) #define HKEY_CURRENT_CONFIG (( HKEY ) (ULONG_PTR)((LONG)0x80000005) ) #define HKEY_DYN_DATA (( HKEY ) (ULONG_PTR)((LONG)0x80000006) ) #define HKEY_CURRENT_USER_LOCAL_SETTINGS (( HKEY ) (ULONG_PTR)((LONG)0x80000007) ) samDesired可以是下列值 #define KEY_QUERY_VALUE (0x0001) #define KEY_SET_VALUE (0x0002) #define KEY_CREATE_SUB_KEY (0x0004) #define KEY_ENUMERATE_SUB_KEYS (0x0008) #define KEY_NOTIFY (0x0010) #define KEY_CREATE_LINK (0x0020) #define KEY_WOW64_32KEY (0x0200) #define KEY_WOW64_64KEY (0x0100) #define KEY_WOW64_RES (0x0300) #define KEY_READ ((STANDARD_RIGHTS_READ |\ KEY_QUERY_VALUE |\ KEY_ENUMERATE_SUB_KEYS |\ KEY_NOTIFY) \ & \ (~SYNCHRONIZE)) #define KEY_WRITE ((STANDARD_RIGHTS_WRITE |\ KEY_SET_VALUE |\ KEY_CREATE_SUB_KEY) \ & \ (~SYNCHRONIZE)) #define KEY_EXECUTE ((KEY_READ) \ & \ (~SYNCHRONIZE)) #define KEY_ALL_ACCESS ((STANDARD_RIGHTS_ALL |\ KEY_QUERY_VALUE |\ KEY_SET_VALUE |\ KEY_CREATE_SUB_KEY |\ KEY_ENUMERATE_SUB_KEYS |\ KEY_NOTIFY |\ KEY_CREATE_LINK) \ & \ (~SYNCHRONIZE)) return 成功返回ERROR_SUCCESS,失敗返回錯誤碼,在<winerror.h>中定義 */ DWORD ulOptions = 0; REGSAM samDesired = KEY_QUERY_VALUE | KEY_SET_VALUE; errorCode = RegOpenKeyEx(rootHKey, (LPCTSTR)subKey, ulOptions, samDesired, &hkResult); if (errorCode == ERROR_SUCCESS) { printf("RegOpenKeyEx -> hkey=0x%x\n", hkResult); /* LONG WINAPI RegQueryValueEx(    HKEY hkey, // 一個已開啟表項的控制代碼,或者指定一個標準項名(即登錄檔中的幾個根登錄檔項)    LPCTSTR lpValueName, // 指示這個函式將開啟或建立的表項的名稱。這個表項必須是由hkey引數所標識的子項。    LPDWORD lpReserved, // reserved LPDWORD lpType, // 緩衝區的型別 LPBYTE lpData, // 一個返回值,指向一個快取區,用來獲得與指定子項預設值相關的一個字串。    LPDWORD lpcbData // 指定一個變數,用於裝載lpValue緩衝區的長度。一旦返回,它會設為實際載入緩衝區的位元組數量。該大小包含了資料長度還加上了終止符的空字串。    ); lpType可以是下列的值 #define REG_NONE ( 0 ) // No value type #define REG_SZ ( 1 ) // Unicode nul terminated string #define REG_EXPAND_SZ ( 2 ) // Unicode nul terminated string // (with environment variable references) #define REG_BINARY ( 3 ) // Free form binary #define REG_DWORD ( 4 ) // 32-bit number #define REG_DWORD_LITTLE_ENDIAN ( 4 ) // 32-bit number (same as REG_DWORD) #define REG_DWORD_BIG_ENDIAN ( 5 ) // 32-bit number #define REG_LINK ( 6 ) // Symbolic Link (unicode) #define REG_MULTI_SZ ( 7 ) // Multiple Unicode strings #define REG_RESOURCE_LIST ( 8 ) // Resource list in the resource map #define REG_FULL_RESOURCE_DESCRIPTOR ( 9 ) // Resource list in the hardware description #define REG_RESOURCE_REQUIREMENTS_LIST ( 10 ) #define REG_QWORD ( 11 ) // 64-bit number #define REG_QWORD_LITTLE_ENDIAN ( 11 ) // 64-bit number (same as REG_QWORD) return 成功返回ERROR_SUCCESS,失敗返回錯誤碼,在<winerror.h>中定義 */ //Windows 95/98/Me: 登錄檔子鍵或值名稱不能超過255字元。 DWORD len; BYTE lpData[255]; errorCode = RegQueryValueEx(hkResult, lpValueName, lpReserved, &dwType, lpData, &len); if (errorCode == ERROR_SUCCESS) { printf("RegQueryValue -> lpType=%d, value=%ls, len=%ld\n", dwType, (LPTSTR)lpData, len); } else { printf("RegQueryValue fail(%ld)\n", errorCode); } /* //刪除值(即刪除右側列表中的某一項) WINADVAPI LSTATUS APIENTRY RegDeleteValueW( _In_ HKEY hKey, //A handle to an open registry key. The key must have been opened with the KEY_SET_VALUE access right. _In_opt_ LPCWSTR lpValueName //鍵名 ); */ errorCode = RegDeleteValue(hkResult, lpValueName); if (errorCode == ERROR_SUCCESS) { printf("RegDeleteValue succ\n"); } else { printf("RegDeleteValue fail(%ld)\n", errorCode); } //釋放指定註冊鍵的控制代碼 errorCode = RegCloseKey(hkResult); if (errorCode == ERROR_SUCCESS) { printf("RegCloseKey succ\n"); } else { printf("RegCloseKey fail(%ld)\n", errorCode); } } else { printf("RegOpenKeyEx fail(%ld)\n", errorCode); } /* //刪除鍵(即刪除左側樹檢視中的某一節點) WINADVAPI LSTATUS APIENTRY RegDeleteKeyExW( _In_ HKEY hKey, //A handle to an open registry key. The access rights of this key do not affect the delete operation. _In_ LPCWSTR lpSubKey, _In_ REGSAM samDesired, _Reserved_ DWORD Reserved ); */ errorCode = RegDeleteKeyEx(rootHKey, subKey, KEY_WOW64_64KEY, reserved); if (errorCode == ERROR_SUCCESS) { printf("RegDeleteKeyEx succ\n"); } else { printf("RegDeleteKeyEx fail(%ld)\n", errorCode); } system("pause"); return 0; }