C/C++ Windows API——注册表

// RegDemo.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include 
#include 

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,失败返回错误码,在中定义
    */
    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,失败返回错误码,在中定义
        */
        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,失败返回错误码,在中定义
    */
    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,失败返回错误码,在中定义
        */
        //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;
}

你可能感兴趣的:(——,Windows,API)