• 注册表操作总结


    参考及摘抄自文章:http://www.cnblogs.com/lartely/archive/2011/04/10/2011770.html

                  http://blog.csdn.net/sunboy_2050/article/details/7753662

    基础知识:


    注册表的组织方式跟文件目录比较相似,主要分为根键、子键和键值项三部分,与文件目录对应的话就是根目录、子目录和文件。分别介绍一下这三部分:
    1.根键:共有5个,分别为HKEY_CLASSES_ROOT,HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE,HKEY_USERS和HKEY_CURRENT_CONFIG,把它们理解成磁盘的五个分区可以了。
    2.子键:可以有多个子键和键值项,就像一个目录中可以有多个子目录和多个文件一样。
    3.键值项:可以理解为文件,它由三部分组成,分别为:名称、类型、数据。
    类型又分为多种主要包括如下:
    REG_BINARY 二进制数据
    REG_DWORD 32位双字节数据
    REG_SZ 以0结尾的字符串
    REG_DWORD_BIG_ENDIAN 高位排在底位的双字
    REG_EXPAND_SZ 扩展字符串,可以加入变量如%PATH%
    REG_LINK UNICODE 符号链接
    REG_RESOURCE_LIST 设备驱动程序资源列表
    REG_MULTI_SZ 多字符串
    注册表数据项的数据类型有8种,但最常用的主要是前3种。

    常用API:


    1.打开/关闭注册表键

    LONG WINAPI RegOpenKeyEx(
      _In_        HKEY hKey,         // 父键句柄
      _In_opt_    LPCTSTR lpSubKey,  // 子键的名称
      _Reserved_  DWORD ulOptions,   // 保留项,传0即可
      _In_        REGSAM samDesired, // 访问权限
      _Out_       PHKEY phkResult    // 返回子键的句柄
    );

    HKEY hKey------

        父键的句柄,可为RegCreateKeyEx或RegOpenKeyEx返回的注册表键句柄

        或为预定义的根键HKEY_CLASSES_ROOT,HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE,HKEY_USERS或HKEY_CURRENT_CONFIG

    REGSAM samDesired------

        访问权限,想方便的话可以指定为KEY_ALL_ACCESS,这样什么权限都有了。其他常用的权限还有KEY_READ,KEY_WRITE等。

    成功开启子键则返回ERROR_SUCCESS

    LONG WINAPI RegCloseKey(
      _In_  HKEY hKey
    );

    这两个函数需配对使用

    [cpp] view plaincopy
     
    1. // 打开注册表键------  
    2. HKEY hKey;  
    3. LPCTSTR lpszSubKey = TEXT("SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");  
    4. int ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpszSubKey, 0, KEY_ALL_ACCESS, &hKey);  
    5. if (ret != ERROR_SUCCESS)  
    6. {  
    7.     // 打开失败  
    8.     ......  
    9. }  
    10.   
    11. ......  
    12.           
    13. // 关闭注册表键------  
    14. RegCloseKey(hKey);  

    2.获取注册表键的子键及键值的信息

    每个注册表键下面都包含子键及键值项,RegQueryInfoKey函数用于获取子键的数量,键值项的数量等信息。

    LONG WINAPI RegQueryInfoKey(
      _In_        HKEY hKey,               // 要获取信息的注册表键句柄
      _Out_opt_   LPTSTR lpClass,          // 一般传NULL
      _Inout_opt_ LPDWORD lpcClass,        // 一般传NULL
      _Reserved_  LPDWORD lpReserved,      // NULL
      _Out_opt_   LPDWORD lpcSubKeys,      // hKey下的子键数量
      _Out_opt_   LPDWORD lpcMaxSubKeyLen, // hKey下的子键名称的最大长度(不包含结尾的null字符)
      _Out_opt_   LPDWORD lpcMaxClassLen,  // 一般传NULL
      _Out_opt_   LPDWORD lpcValues,       // hKey下的键值的数量
      _Out_opt_   LPDWORD lpcMaxValueNameLen, // hKey下键值Name的最大长度(不包含结尾的null字符)
      _Out_opt_   LPDWORD lpcMaxValueLen,     // hKey下的键值Data的最大长度(in bytes)
      _Out_opt_   LPDWORD lpcbSecurityDescriptor, // 安全描述符长度,一般传NULL
      _Out_opt_   PFILETIME lpftLastWriteTime     // 最后修改时间,一般传NULL
    );

    通过RegQueryInfoKey获取了子键及键值项的信息后,这才知道子键的数量,键值项的数量等信息,后面就可以通过RegEnumKeyEx枚举子键信息,通过RegEnumValue枚举键值项信息。

    [cpp] view plaincopy
     
    1. DWORD dwSubKeyCnt;          // 子键的数量  
    2. DWORD dwSubKeyNameMaxLen;   // 子键名称的最大长度(不包含结尾的null字符)  
    3. DWORD dwKeyValueCnt;        // 键值项的数量  
    4. DWORD dwKeyValueNameMaxLen; // 键值项名称的最大长度(不包含结尾的null字符)  
    5. DWORD dwKeyValueDataMaxLen; // 键值项数据的最大长度(in bytes)  
    6. int ret = RegQueryInfoKey(  
    7.     hKey,  
    8.     NULL,  
    9.     NULL,  
    10.     NULL,  
    11.     &dwSubKeyCnt,  
    12.     &dwSubKeyNameMaxLen,  
    13.     NULL,  
    14.     &dwKeyValueCnt,  
    15.     &dwKeyValueNameMaxLen,  
    16.     &dwKeyValueDataMaxLen,  
    17.     NULL,  
    18.     NULL);  
    19. if (ret != ERROR_SUCCESS) // Error  
    20. {  
    21.     ......  
    22. }  

    3.枚举子键信息

    LONG WINAPI RegEnumKeyEx(
      _In_         HKEY hKey,
      _In_         DWORD dwIndex,      // 索引,从0开始
      _Out_        LPTSTR lpName,      // 接收子键的名称
      _Inout_      LPDWORD lpcName,    // lpName的大小(in characters,包含null)
      _Reserved_   LPDWORD lpReserved, // NULL
      _Inout_      LPTSTR lpClass,     // 一般传NULL
      _Inout_opt_  LPDWORD lpcClass,   // 一般传NULL
      _Out_opt_    PFILETIME lpftLastWriteTime  // 一般传NULL
    );

    前面通过RegQueryInfoKey获取了hKey下子键的数量以及子键名称的最大长度,那么接下来通过RegEnumKeyEx就可以获取每个子键的名称了。为什么要获取子键的名称,因为获取了这个名称之后,就可以通过RegOpenKeyEx开启子键获得其句柄。

    整个流程差不多是这样子的:RegQueryInfoKey-->获得某注册表键下的子键的数量及子键名称的最大长度-->RegEnumKeyEx-->枚举获取每个子键的名称-->RegOpenKeyEx-->开启子键句柄-->做你想要的操作。

    lpName------

        前面通过RegQueryInfoKey获取了子键名称的最大长度(没有包含结尾的null字符),所有可以通过定义一个[最大长度+1]大小的Buffer来接收

    lpcName------

        RegQueryInfoKey获取的子键名称的最大长度 + 1

    [cpp] view plaincopy
     
    1. //  
    2. // 以下代码中的变量dwSubKeyNameMaxLen&dwSubKeyCnt由  
    3. // RegQueryInfoKey获取  
    4. //  
    5. LPTSTR lpszSubKeyName = new TCHAR[dwSubKeyNameMaxLen+1];  
    6. for (int index = 0; index < dwSubKeyCnt; ++index)  
    7. {  
    8.     memset(lpszSubKeyName, 0, sizeof(TCHAR)*(dwSubKeyNameMaxLen+1));  
    9.     DWORD dwNameCnt = dwSubKeyNameMaxLen + 1;  
    10.     int ret = RegEnumKeyEx(  
    11.         hKey,  
    12.         index,  
    13.         lpszSubKeyName,  
    14.         &dwNameCnt,  
    15.         NULL,  
    16.         NULL,  
    17.         NULL,  
    18.         NULL);  
    19.     if (ret != ERROR_SUCCESS)  
    20.     {  
    21.         ......  
    22.     }  
    23. }  
    24. delete[] lpszSubKeyName;  

    4.枚举键值项信息

    LONG WINAPI RegEnumValue(
      _In_         HKEY hKey,
      _In_         DWORD dwIndex,         // 索引,从0开始
      _Out_        LPTSTR lpValueName,    // 接收键值项的名称
      _Inout_      LPDWORD lpcchValueName,// lpValueName的大小,包含null character
      _Reserved_   LPDWORD lpReserved,    // NULL
      _Out_opt_    LPDWORD lpType,        // 接收键值项的类型
      _Out_opt_    LPBYTE lpData,         // 接收键值项的数据
      _Inout_opt_  LPDWORD lpcbData       // lpData的Buffer大小(in bytes)
    );

    前面通过RegQueryInfoKey获取了hKey下键值项的数量以及键值项名称的最大长度,键值项数据的最大长度,那么接下来通过RegEnumValue就可以获取每个键值项的名称、类型、数据。

    [cpp] view plaincopy
     
    1. //  
    2. // 以下代码中变量:dwKeyValueCnt & dwKeyValueNameMaxLen &  
    3. //                dwKeyValueDataMaxLen  
    4. // 均为通过RegQueryInfoKey获取的  
    5. //  
    6. for (unsigned int index = 0; index < dwKeyValueCnt; ++index)  
    7. {  
    8.     LPTSTR lpszKeyValueName = new TCHAR[dwKeyValueNameMaxLen + 1];  
    9.     memset(lpszKeyValueName, 0, sizeof(TCHAR)*(dwKeyValueNameMaxLen + 1));  
    10.     DWORD  dwNameCnt = dwKeyValueNameMaxLen + 1;  
    11.     DWORD  dwKeyValueType;  
    12.     LPBYTE lpbKeyValueData = new BYTE[dwKeyValueDataMaxLen];  
    13.     DWORD  dwKeyValueDataLen;  
    14.       
    15.     int ret = RegEnumValue(  
    16.         hKey,   
    17.         index,   
    18.         lpszKeyValueName,  
    19.         &dwNameCnt,   
    20.         NULL,   
    21.         &dwKeyValueType,    
    22.         lpbKeyValueData,  
    23.         &dwKeyValueDataLen);  
    24.     if (ret != ERROR_SUCCESS)  
    25.     {  
    26.         ......  
    27.     }  
    28.     delete[] lpszKeyValueName;  
    29.     delete[] lpbKeyValueData;  
    30. }  

    5.由键值项名称获取键值项的类型及键值项数据

    LONG WINAPI RegQueryValueEx(
      _In_         HKEY hKey,
      _In_opt_     LPCTSTR lpValueName, // 键值项名称
      _Reserved_   LPDWORD lpReserved,  // NULL
      _Out_opt_    LPDWORD lpType,      // 接收键值项类型
      _Out_opt_    LPBYTE lpData,       // 接收键值项数据
      _Inout_opt_  LPDWORD lpcbData     // lpData的Buffer大小(in bytes)
    );

    有时候,我们知道某注册表键下的键值项的名称,而想获取键值项的类型及键值项数据,就可以通过该函数获取。

    比如:我们知道HKEY_CURRENT_USEREnvironment注册表键下存在名为"Path"的键值项,通过该函数就可以获取其值。

    通常情况下,虽然我们知道键值项的名称,却不知道键值项数据的大小,也即lpData该如何定义?可以分两步实现:一、调用RegQueryValueEx,但传lpData为NULL,函数执行成功后,lpcbData会返回键值项数据的大小。二、根据上一步获取的键值项数据的大小,new一个对应大小的Buffer,然后再调用RegQueryValueEx,传递lpData为新开辟的Buffer,这样就可以了。

    [cpp] view plaincopy
     
    1. // 获取键值项Data的大小  
    2. LPCTSTR lpszKeyValueName = TEXT("???");  
    3. DWORD dwKeyValueType;  
    4. DWORD dwKeyValueDataSize;  
    5. int ret = RegQueryValueEx(hKey, lpszKeyValueName, NULL, &dwKeyValueType, NULL, &dwKeyValueDataSize);  
    6. if (ret != ERROR_SUCCESS)  
    7. {  
    8.     ......  
    9. }  
    10.   
    11. // 获取键值项Data  
    12. LPBYTE lpbKeyValueData = new BYTE[dwKeyValueDataSize];  
    13. ret = RegQueryValueEx(hKey, lpszKeyValueName, NULL, &dwKeyValueType, lpbKeyValueData, &dwKeyValueDataSize);  
    14. if (ret != ERROR_SUCCESS)  
    15. {  
    16.     ......  
    17. }  
    18.   
    19. delete[] lpbKeyValueData;  

    6.设置键值项的值/新建键值项

    LONG RegSetValueEx(
      HKEY hKey,
      LPCWSTR lpValueName,
      DWORD Reserved,
      DWORD dwType,
      const BYTE* lpData,
      DWORD cbData
    );

    该函数也可以新建键值项,当lpValueName指定名称的键值项不存在时,会新建键值项。

    7.删除键值项

    LONG RegDeleteValue( 
      HKEY hKey, 
      LPCWSTR lpValueName 
    ); 

    8.创建、删除子键

    LONG RegCreateKeyEx( 
      HKEY hKey, 
      LPCWSTR lpSubKey, 
      DWORD Reserved, 
      LPWSTR lpClass, 
      DWORD dwOptions, 
      REGSAM samDesired, 
      LPSECURITY_ATTRIBUTES lpSecurityAttributes, 
      PHKEY phkResult, 
      LPDWORD lpdwDisposition 
    ); 
    LONG WINAPI RegDeleteKey(
      _In_  HKEY hKey,
      _In_  LPCTSTR lpSubKey
    );

    示例程序一:读取注册表获取计算机上已安装程序的信息


    Windows 系统中,安装程序都可以在注册表 HKEY_LOCAL_MACHINESoftWareMicrosoftWindowsCurrentVersionUninstall 获取,并且xp、vista、win7、win8都一样

    以下示例程序中:

    结构体ApplicationInfoA用于记录每个安装程序的具体信息,至于为何在名称后面加A,主要是为了表明其下的信息全是用string记录的。

    函数GetAllInstalledAppInfoA用于获取计算机上已安装程序的全部信息,它接受vector<ApplicationInfoA>引用类型的参数,并将获取的全部信息存放在该vector中。该程序执行成功返回0,执行失败则返回-1。

    main()函数中演示了怎么使用:

    vector<ApplicationInfoA> vAppInfo;     

    GetAllInstalledAppInfoA(vAppInfo);

    在获取了安装程序的信息后,输出到D盘下的InstalledAppInfo.txt文件中。

    [cpp] view plaincopy
     
    1. #include <windows.h>  
    2. #include <iostream>  
    3. #include <TCHAR.H>  
    4. #include <vector>  
    5.   
    6. using namespace std;  
    7.   
    8. //  
    9. // 用于记录安装软件信息的结构体  
    10. //  
    11. struct ApplicationInfoA  
    12. {  
    13.     string strName;            // 软件名  
    14.     string strDisplayName;     // 显示的软件名  
    15.     string strPublisher;       // 发布者  
    16.     string strVersion;         // 版本  
    17.     string strDisplayVersion;  // 显示的版本  
    18.     string strInstallLocation; // 安装的位置  
    19. };  
    20.   
    21. //  
    22. // 获取具体的程序的键值Data  
    23. // hKey [in]  
    24. //     --- 指向HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionUninstall的子键句柄  
    25. // lpszKeyValueName [in]  
    26. //     --- hKey下面的子键名称  
    27. // lpszKeyValueName [in]  
    28. //     --- 正如其名,键值的名称  
    29. // strKeyValue [out]  
    30. //     --- 键值的Data  
    31. //  
    32. int _GetAppInfoA_(HKEY hKey, LPCSTR lpszAppName, LPCSTR lpszKeyValueName, string& strKeyValue)  
    33. {  
    34.     int ret;  
    35.   
    36.     // 打开已安装软件的注册表键------------------------------------------------  
    37.     HKEY hInstallAppKey;  
    38.     ret = RegOpenKeyEx(hKey, lpszAppName, 0, KEY_ALL_ACCESS, &hInstallAppKey);  
    39.     if (ret != ERROR_SUCCESS)  
    40.     {  
    41.         return -1;  
    42.     }  
    43.   
    44.     // 获取已安装软件的注册表键的键值------------------------------------------  
    45.     // 1.获取字符串大小(默认为字符串即REG_SZ)  
    46.     DWORD dwKeyValueType = REG_SZ;  
    47.     DWORD dwKeyValueDataSize = 0;  
    48.     ret = RegQueryValueExA(  
    49.         hInstallAppKey,  
    50.         lpszKeyValueName,  
    51.         NULL,  
    52.         &dwKeyValueType,  
    53.         NULL,  
    54.         &dwKeyValueDataSize);  
    55.     if (ret == ERROR_FILE_NOT_FOUND)  
    56.     {  
    57.         RegCloseKey(hInstallAppKey);  
    58.         return 0;  
    59.     }  
    60.     else if (ret != ERROR_SUCCESS)  
    61.     {  
    62.         RegCloseKey(hInstallAppKey);  
    63.         return -1;  
    64.     }  
    65.   
    66.     // 2.获取字符串值  
    67.     if (dwKeyValueType != REG_SZ)   // 如果不是字符串类型则返回,有的安装程序此项不为字符串而为其他类型,忽略  
    68.     {  
    69.         RegCloseKey(hInstallAppKey);  
    70.         return 0;  
    71.     }  
    72.     LPSTR lpszKeyValueData = new char[dwKeyValueDataSize + 1];  
    73.     memset(lpszKeyValueData, 0, dwKeyValueDataSize + 1);  
    74.     ret = RegQueryValueExA(  
    75.         hInstallAppKey,  
    76.         lpszKeyValueName,  
    77.         NULL,  
    78.         &dwKeyValueType,  
    79.         (LPBYTE)lpszKeyValueData,  
    80.         &dwKeyValueDataSize);  
    81.     if (ret != ERROR_SUCCESS)  
    82.     {  
    83.         delete[] lpszKeyValueData;  
    84.         RegCloseKey(hInstallAppKey);  
    85.         return -1;  
    86.     }  
    87.     strKeyValue = lpszKeyValueData;  
    88.     delete[] lpszKeyValueData;  
    89.   
    90.     // 关闭注册表键------------------------------------------------------------  
    91.     RegCloseKey(hInstallAppKey);  
    92.   
    93.     return 0;  
    94. }  
    95.   
    96.   
    97. //  
    98. // 获取系统安装的程序信息并存储于参数vector中  
    99. // 成功执行返回0  
    100. // 执行失败则返回-1  
    101. //  
    102. int GetAllInstalledAppInfoA(vector<ApplicationInfoA>& vAppInfo)  
    103. {  
    104.     int ret;  
    105.   
    106.     // 打开注册表键------------------------------------------------------------  
    107.     HKEY hKey;  
    108.     LPCSTR lpszSubKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";  
    109.     ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, lpszSubKey, 0, KEY_ALL_ACCESS, &hKey);  
    110.     if (ret != ERROR_SUCCESS)  
    111.     {  
    112.         return -1;  
    113.     }  
    114.   
    115.     // 获取子键&键值信息-------------------------------------------------------  
    116.     DWORD dwSubKeysCnt;           // 子键数量  
    117.     DWORD dwMaxSubKeyNameLen;     // 子键名字的最大长度(not including the terminating null character)  
    118.     DWORD dwKeyValueCnt;          // 键值的数量  
    119.     DWORD dwMaxKeyValueNameLen;   // 键值名字的最大长度(not including the terminating null character)  
    120.     DWORD dwMaxKeyValueDataLen;   // 键值数据的最大长度(in Bytes)  
    121.   
    122.     ret = RegQueryInfoKey(  
    123.         hKey,  
    124.         NULL,  
    125.         NULL,  
    126.         NULL,  
    127.         &dwSubKeysCnt,  
    128.         &dwMaxSubKeyNameLen,  
    129.         NULL,  
    130.         &dwKeyValueCnt,  
    131.         &dwMaxKeyValueNameLen,  
    132.         &dwMaxKeyValueDataLen,  
    133.         NULL,  
    134.         NULL);  
    135.     if (ret != ERROR_SUCCESS)  
    136.     {  
    137.         RegCloseKey(hKey);  
    138.         return -1;  
    139.     }  
    140.   
    141.     // 枚举子键信息------------------------------------------------------------  
    142.     DWORD dwIndex;  
    143.     LPSTR lpszSubKeyName = new char[dwMaxSubKeyNameLen + 1];  
    144.     DWORD dwNameLen = dwMaxSubKeyNameLen + 1;  
    145.   
    146.     for (dwIndex = 0; dwIndex < dwSubKeysCnt; ++dwIndex)  
    147.     {  
    148.         dwNameLen = dwMaxSubKeyNameLen + 1;  
    149.         memset(lpszSubKeyName, 0, dwMaxSubKeyNameLen + 1);  
    150.   
    151.         ret = RegEnumKeyEx(  
    152.             hKey,  
    153.             dwIndex,  
    154.             lpszSubKeyName,  
    155.             &dwNameLen,  
    156.             NULL,  
    157.             NULL,  
    158.             NULL,  
    159.             NULL);  
    160.         if (ret != ERROR_SUCCESS)  
    161.         {  
    162.             RegCloseKey(hKey);  
    163.             delete[] lpszSubKeyName;  
    164.             return -1;  
    165.         }  
    166.   
    167.         //************获取具体的程序的安装信息BEG*************  
    168.         ApplicationInfoA appInfo;  
    169.         appInfo.strName = lpszSubKeyName;  
    170.         _GetAppInfoA_(hKey, lpszSubKeyName, "DisplayName", appInfo.strDisplayName);  
    171.         _GetAppInfoA_(hKey, lpszSubKeyName, "Publisher", appInfo.strPublisher);  
    172.         _GetAppInfoA_(hKey, lpszSubKeyName, "Version", appInfo.strVersion);  
    173.         _GetAppInfoA_(hKey, lpszSubKeyName, "DisplayVersion", appInfo.strDisplayVersion);  
    174.         _GetAppInfoA_(hKey, lpszSubKeyName, "InstallLocation", appInfo.strInstallLocation);  
    175.         vAppInfo.push_back(appInfo);  
    176.         //************获取具体的程序的安装信息END*************  
    177.     }  
    178.   
    179.     delete[] lpszSubKeyName;  
    180.   
    181.     // 关闭注册表键------------------------------------------------------------  
    182.     RegCloseKey(hKey);  
    183.     return 0;  
    184. }  
    185.   
    186. int main()  
    187. {  
    188.     cout << "Reg Demo Test" << endl;  
    189.   
    190.     vector<ApplicationInfoA> vAppInfo;  
    191.     cout << GetAllInstalledAppInfoA(vAppInfo) << endl;  
    192.   
    193.     //输出到文件  
    194.     vector<ApplicationInfoA>::iterator iter = vAppInfo.begin();  
    195.     FILE *fp = fopen("D:\InstalledAppInfo.txt", "a");  
    196.     while (iter != vAppInfo.end())  
    197.     {  
    198.         fprintf(fp, "---------------- ");  
    199.         fprintf(fp, "Name: %s  DisplayName: %s  Publisher: %s  Version: %s  DisplayVersion: %s  InstallLocation: %s ",   
    200.             iter->strName.c_str(), iter->strDisplayName.c_str(),  
    201.             iter->strPublisher.c_str(), iter->strVersion.c_str(),   
    202.             iter->strDisplayVersion.c_str(), iter->strInstallLocation.c_str());  
    203.         fprintf(fp, "---------------- ");  
    204.         ++iter;  
    205.     }  
    206.     fclose(fp);  
    207.   
    208.     return 0;  
    209. }  

    示例程序二:增加Path环境变量


    我们常常需要手工添加环境变量,如下图所示:

    那么怎样用程序实现呢?环境变量的配置存储在注册表当中,可以通过读写注册表来实现读写环境变量。

    系统变量存储在注册表的如下位置:HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession ManagerEnvironment

    而用户变量则存储在注册表的如下位置:HKEY_CURRENT_USEREnvironment

    下面示例程序用于向系统变量中的Path环境变量中增加内容。

    main函数中调用AddPathEnvValue(";HelloKitty")就用于向Path环境变量后面添加;HelloKitty。当然程序中有防呆机制,如果系统变量下刚开始没有Path环境变量则先新增Path环境变量。程序执行成功返回0,执行失败返回-1。

    代码如下:

    [cpp] view plaincopy
     
      1. #include <windows.h>  
      2. #include <iostream>  
      3.   
      4. using namespace std;  
      5.   
      6. //  
      7. // 为系统变量下的Path环境变量增加内容lpszPathValue  
      8. // 成功则返回0  
      9. // 失败则返回-1  
      10. // 若刚开始Path环境变量为"D:\123"  
      11. // 则调用AddPathEnvValue(";HelloKitty")后为"D:\123;HelloKitty"  
      12. //  
      13. int AddPathEnvValue(LPCSTR lpszPathValue)  
      14. {  
      15.     int ret;  
      16.   
      17.     // 打开注册表键----------------------------------------  
      18.     HKEY hKey;  
      19.     LPCSTR lpszSubKey = "SYSTEM\CurrentControlSet\Control\Session Manager\Environment";  
      20.     ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, lpszSubKey, 0, KEY_ALL_ACCESS, &hKey);  
      21.     if (ERROR_SUCCESS != ret)  
      22.     {  
      23.         cout << "RegOpenKeyExA():Error" << endl;  
      24.         return -1;  
      25.     }  
      26.       
      27.     // 读取注册表键的键值"Path"----------------------------  
      28.     // 1.获取KeyValueData即字符串的大小  
      29.     LPCSTR lpszKeyValueName = "Path";  
      30.     DWORD  dwKeyValueType = REG_EXPAND_SZ;  
      31.     DWORD  dwKeyValueDataSize = 0;     
      32.     ret = RegQueryValueExA(hKey, lpszKeyValueName, NULL, &dwKeyValueType, NULL, &dwKeyValueDataSize);  
      33.     if (ret == ERROR_FILE_NOT_FOUND)  
      34.     {  
      35.         //不存在Path环境变量则新增一个Path环境变量  
      36.         ret = RegSetValueExA(hKey, lpszKeyValueName, 0, REG_EXPAND_SZ, (const BYTE*)"", 1);  
      37.         if (ret != ERROR_SUCCESS)  
      38.         {  
      39.             cout << "RegSetValueExA():Error" << endl;  
      40.             RegCloseKey(hKey);  
      41.             return -1;  
      42.         }  
      43.     }  
      44.     else if (ret != ERROR_SUCCESS)  
      45.     {  
      46.         cout << "RegQueryValueExA():Error" << endl;  
      47.         RegCloseKey(hKey);  
      48.         return -1;  
      49.     }  
      50.     else if (dwKeyValueType != REG_EXPAND_SZ)  
      51.     {  
      52.         cout << "It is impossible" << endl;  
      53.         cout << dwKeyValueType << endl;  
      54.         RegCloseKey(hKey);  
      55.         return -1;  
      56.     }  
      57.   
      58.     // 2.获取KeyValueData即字符串的值  
      59.     CHAR *lpszKeyValueData = new CHAR[dwKeyValueDataSize + 1];  
      60.     memset(lpszKeyValueData, 0, dwKeyValueDataSize + 1);  
      61.     ret = RegQueryValueExA(hKey, lpszKeyValueName, NULL, &dwKeyValueType, (LPBYTE)lpszKeyValueData, &dwKeyValueDataSize);  
      62.     if (ret != ERROR_SUCCESS)  
      63.     {  
      64.         cout << "RegQueryValueExA():Error" << endl;  
      65.         RegCloseKey(hKey);  
      66.         delete[] lpszKeyValueData;  
      67.         return -1;  
      68.     }  
      69.   
      70.     // 在原注册表键值的基础上添加新的值  
      71.     unsigned int nLen = strlen(lpszPathValue);  
      72.     nLen += strlen(lpszKeyValueData);  
      73.     CHAR *lpszKeyValueData_New = new CHAR[nLen + 1];  
      74.     memset(lpszKeyValueData_New, 0, nLen + 1);  
      75.     sprintf(lpszKeyValueData_New, "%s%s", lpszKeyValueData, lpszPathValue);  
      76.     ret = RegSetValueExA(hKey, lpszKeyValueName, 0, REG_EXPAND_SZ, (const BYTE*)lpszKeyValueData_New, strlen(lpszKeyValueData_New) + 1);  
      77.     if (ret != ERROR_SUCCESS)  
      78.     {  
      79.         cout << "RegSetValueExA:Error" << endl;  
      80.         RegCloseKey(hKey);  
      81.         delete[] lpszKeyValueData;  
      82.         delete[] lpszKeyValueData_New;  
      83.   
      84.         return -1;  
      85.     }  
      86.   
      87.   
      88.     delete[] lpszKeyValueData;  
      89.     delete[] lpszKeyValueData_New;  
      90.   
      91.     // 关闭注册表键----------------------------------------  
      92.     RegCloseKey(hKey);  
      93.   
      94.     return 0;  
      95. }  
      96.   
      97. int main()  
      98. {  
      99.     cout << AddPathEnvValue(";HelloKitty") << endl;  
      100.   
      101.     return 0;  
      102. }  
  • 相关阅读:
    读Windows核心编程2字符和字符串
    HTTP Error 404.3 while browse to WCF service
    读Windows核心编程3内核对象
    代码安全性的基本原则[转载]
    在HyperV中安装和配置Ubuntu网络
    使用Windows Azure Mobile Service开发Windows Phone 8 App
    Js 学习 使用js arguments 写一个 多态overload 的小程序。 js 闭包写一个10的阶乘的算法
    js 学习 函数
    jquery slider show carouFredSel
    vs 2010 创建windows phone 程序 出现System.ArgumentNullException Value cannot be null. Parameter name: parentContext
  • 原文地址:https://www.cnblogs.com/liaocheng/p/4266079.html
Copyright © 2020-2023  润新知