注册表编程

注册表编程

1. 注册表基础

1.1注册表历史背景

什么是注册表?我们可以把注册表理解成一种数据库,里面保存着各种数据,如:系统的配置信息,桌面环境,系统软件,IE浏览器等等软件的信息。在微软以前发布的操作系统中(如windows 3.X),把这些信息保存在System.iniWin.ini等文件中,随着数据量越来越大,越来越复杂,这样ini文件难以胜任,从windows 95开始引入注册表来保存这些复杂的,海量的数据,总之我们权且把它当着一个数据库吧。

1.2注册表作用

注册表最直接的用处,就是用来保存一些配置信息,如开发的桌面软件,一定会有些配置数据需要保存,那么我们可以像Windows早期版本那个,保存在ini文件中,不过ini文件容易被人修改。如果保存在注册表中,稍稍保密些,一般使用者也不懂得怎么改。注册表另外一个常用功能是,修改其他软件的配置信息,如浏览器的个性设置,电脑桌面的主题设置,光标配置等,不过这些对开发人员来讲,好像意义不是很大,修改别人的软件配置干什么,是吧?

注册表还保存着硬件的一些驱动相关信息,如COM口的数据,串口通信编程时,你是不是会为判断PC机是否有串口驱动而烦恼呀,不知道PC机上的串口逻辑号是多少很烦心呢?其实这些数据在注册表里都有,到注册表里一查就清楚了,关于如何判断PC机串口是否正常,PC现在有串口逻辑号是多少的相关技术,在博文《串口通信编程--多线程异步方式》里有详细介绍,还有代码参考。

用注册表保存配置信息,那么我们得先大体认识一下注册表的组成与架构,然后再介绍一下如何创建,查询,修改注册表。

1.3注册表结构

打开注册表:可能通过控制面板打开,也有很多其他途径能打开,常用方法是在【开始】菜单中选择【运行】命令,然后在框中输入命令regedit,如图:

https://img-my.csdn.net/uploads/201211/27/1353981172_8532.jpg

然后点【确定】按钮,将会打开注册表,如图:

https://img-my.csdn.net/uploads/201211/27/1353981177_6275.jpg

从图中可看出,注册表是层叠式构架的,左边的树形列表,第一级有5个根键,点开第一级接着有第二级,第三级等等,这叫项,也就是说,根键下面的是项,而项下面如果还有子级那叫子项,直到最后一级如图中路径“HKEY_CURRENT_CONFIG\SOFTWARE\FONTS”,其中FontsSoftware的子项,Fonts是最后一级,它没有子项了,再Fonts下面就是值项了,在右边一栏,值项由名称,类型,数据组成,值项就是最终保存具体数据的地方。

所以说,注册表由:键--------子项----值项构成,而值项由:名称,类型,数据组成,其中名称就不用说了,数据也不用说了,说说类型吧,类型是指数据的类型,数据的类型有很多种,从其他资料中切个图吧,更直观:

https://img-my.csdn.net/uploads/201211/27/1353981182_7629.jpg

看到没,乱糟糟的一堆,总之对一般程序员来说,别管那么多,把它们分成两在类:数值型与字符型,数值型分整型与二进制型,其中整形有4字节8字节等,还分高位在前还是低位在前。字符串更不多说了。

总结一下,注册表与根键、项(子项)、值项组成,根键与项是用来区别层次关系的,不具体存储数据,项下面有子项的同时还可以有值项。值项是具体存储数据的,形式是:名称、类型、值。先把这种关系捋顺了,下面看起来就容易了。

1.4各根键主要存储的信息

Ø HKEY_CLASSES_ROOT

定义了系统中所有文件类型标志和基本操作标志。

Ø HKEY_CURRENT_USER

当前用户的配置信息,包括环境变量、桌面设置、网络连接,软件运行信息等。

Ø HKEY_LOCAL_MACHINE

本机相关的系统信息,包括硬件信息,驱动信息,内存数据,总线数据等等。

Ø HKEY_USER

所有用户的信息。

Ø KKEY_CURRENT_CONFIG

本地计算机启动时配置的相关信息,如环境信息,桌面主题,背景色之类。

1.5手动操作注册表

打开注册表编辑器:【开始】菜单选择运行命令,输入regedit,【确定】,打开注册表编辑器,就可以在上面创建,修改,删除,还有查找等等操作。都是可视化操作,动手操作一下就懂,不赘述。

2. 注册表编程

本章介绍注册表的创建、修改、查询等知识。通过低层的API实现。

2.1相关函数分类

关于注册表的函数可大致分为:项管理类,值项管理类,枚举类,实用类,安全类。项管理与值项管理不言而喻是对项与值项的增删改查操作的。枚举是对项与值项数据进行分析查找。实用类是远程操作的,操作远程计算机的注册表。安全类主要是对注册表的安全信息操作。常用的是项管理,值项管理与枚举这三类。后面我们也介绍这三类。其他的不深究,如果想了解的,可以联系我,我有相关电子档书籍。

2.2项管理函数

很多书籍中分项,还有子项,弄得一头雾水,其实子项是相对而言的,有父项才有子项之说,所以说子项也是项,子项也可能是某项的父项,这个概念要搞清楚。

项管理函数是对项(子项)的创建、打开、关闭、删除的几个操作,分4个函数,下面一一介绍。

2.2.1项创建函数

RegCreateKeyExRegCreateKey,后者请不要再用,win32以后版本都用前者。此函数的功能是在指定项下建一子项。

LONG WINAPI RegCreateKeyEx(

 __in       HKEY hKey,

 __in       LPCTSTR lpSubKey,

 __reserved DWORD Reserved,

 __in_opt   LPTSTR lpClass,

 __in       DWORD dwOptions,

 __in       REGSAM samDesired,

 __in_opt   LPSECURITY_ATTRIBUTES lpSecurityAttributes,

 __out      PHKEY phkResult,

 __out_opt  LPDWORD lpdwDisposition

);

hKey父项:打开的句柄,表明在此项下建立子项,也可以是五个(大多数windows版本是五个,也有六个的)根键之一,就是以下常量:

HKEY_CLASSES_ROOT

HKEY_CURRENT_USER

HKEY_LOCAL_MACHINE

HKEY_USERS

HKEY_CURRENT_CONFIG

lpSubKey子项名称:你要创建的子项,接在父项下,如“REGTEST\\GPS设备网络通道\\”;

Reserved必须为0

lpClass建议为NULL

dwOptions:标志创建的注册表保存在文件中还是内存中;

一般取值REG_OPTION_NON_VOLATILE更多信息请查MSDN

samDesired访问权限,有读、写、查询等等,取KEY_ALL_ACCESS全部权限即可;

lpSecurityAttributes安全属性,不知道怎么设置,取NULL即可;

phkResult创建成功后,返回的新项的句柄;

lpdwDisposition返回状态描述,有两种状态,项原来存在|

项是新建的(REG_CREATED_NEW_KEYREG_OPENED_EXISTING_KEY)

返回值:成功返回ERROR_SUCCESS

伪代码:

HKEY hKey;

DWORD dw;

if(ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_CONFIG,

" REGTEST\\GPS设备网络通道\\", 0,

NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,

NULL, &hKey, &dw))

AfxMessageBox (_T(“创建成功”));

效果图:

https://img-my.csdn.net/uploads/201211/27/1353981185_9788.jpg

2.2.2项打开函数

RegOpenKeyEx打开一个注册表项,语法定义如下:

LONG WINAPI RegOpenKeyEx(

 __in       HKEY hKey,   //可以是根键,也可以是打开的项

 __in_opt   LPCTSTR lpSubKey,//需要打开的子项名称

 __reserved DWORD ulOptions,//同上

 __in       REGSAM samDesired,//访问权限,同上

 __out      PHKEY phkResult//打开成功后,返回项的句柄

);

伪代码:

HKEY hKey;

if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

        " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey))

        AfxMessageBox(_T("打开成功"));

2.2.3项关闭函数

RegCloseKey这个就太简单了,只有一个参数,就是关闭打开的项:

LONG WINAPI RegCloseKey(

 __in HKEY hKey//传入一个打开的项的句柄

);

伪代码:

HKEY hKey;

if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

        " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)){

        if (ERROR_SUCCESS == RegCloseKey(hKey))

                  AfxMessageBox(_T("关闭成功"));

}

2.2.4项删除函数

RegDeleteKey这个函数也简单,形参只须传入根健与子项路径即可:

LONG WINAPI RegDeleteKey(

 __in HKEY hKey,

 __in LPCTSTR lpSubKey

);

伪代码:

HKEY hKey;

if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

        " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)){

        if (ERROR_SUCCESS == RegCloseKey(hKey))

                  AfxMessageBox(_T("关闭成功"));

}

效果图:

https://img-my.csdn.net/uploads/201211/27/1353981189_4368.jpg

2.3值项管理函数

值项管理函数是对注册表中的值项进行设置(增加)、查询、删除操作,一共介绍三个函数,分别是设置值、查询值、删除值。

2.3.1值设置函数

以下为函数原型:

LONG WINAPI RegSetValueEx(

 __in    HKEY hKey, //已打开注册表项的句柄

 __in_opt  LPCTSTR lpValueName,//值项名称

 __reserved DWORD Reserved,//保留,为0

 __in    DWORD dwType,  //值项类型,前面介绍过,有整形,字符串等

 __in    const BYTE *lpData,//存放值项的值的指针,全部转换成PBYTE

 __in    DWORD cbData      //值项大小(字节)

);

以下是伪代码:

HKEY hKey;

if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

        " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)){

        DWORD nType = REG_SZ;

        char szName[] = {"我叫小王"};

        RegSetValueEx(hKey, "Name", 0, nType, (const PBYTE)szName, strlen(szName));

        nType = REG_DWORD;

        DWORD nYears = 60;

        RegSetValueEx(hKey, "Years", 0, nType, (const PBYTE)&nYears, 4);

}

效果图:

https://img-my.csdn.net/uploads/201211/27/1353981194_4218.jpg

从图中可看出,增加了两个值项,一个是字符串型,一个是整形。

2.3.2值查询函数

查询打开的项的值项,函数是RegQueryValueEx,以下为函数原型:

LONG WINAPI RegQueryValueEx(

 __in        HKEY hKey,//打开项的句柄

 __in_opt    LPCTSTR lpValueName,//值项名

 __reserved  LPDWORD lpReserved,//保留,为0

 __out_opt   LPDWORD lpType,  //返回值项的值类型,如果不关心值项类型,可谓NULL

 __out_opt   LPBYTE lpData,           //装值的BUFF

 __inout_opt LPDWORD lpcbData //BUFF的长度,同时返回取得数据的长度

);

以下为伪代码:

HKEY hKey;

if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

        " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)){

        DWORD nType = 0, nLen = 100;

        char szName[100];

        RegQueryValueEx(hKey, "Name", 0, &nType, (const PBYTE)szName, &nLen);

        nType = 0;

        DWORD nYears = 0; nLen = 4;

        RegQueryValueEx(hKey, "Years", 0, &nType, (const PBYTE)&nYears, &nLen);

        int i = 0;

}

2.3.3值项删除函数

删除打开的项的值项,首先得打开值项所属的项,然后删除值,函数原型如下:

LONG WINAPI RegDeleteValue(

 __in     HKEY hKey, //打开的项的句柄

 __in_opt LPCTSTR lpValueName//值项名字

);

以下为伪代码:

HKEY hKey;

if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

        " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)){

        RegDeleteValue(hKey, "Name");

        RegDeleteValue(hKey, "Years");

}

效果图:

https://img-my.csdn.net/uploads/201211/27/1353981201_3376.jpg

2.4注册表遍历

对注册表进行查找,项、子项、值项进行分析、提取数据等操作。一般有五个函数,下面一一介绍。

2.4.1枚举子项

该函数功能是枚举注册表中指定项的子项,提取子项信息,如子项名,修改时间,子项类型等,一次取一个,函数原型如下:

LONG WINAPI RegEnumKeyEx(

 __in HKEY hKey, //已打开的项句柄,必须有KEY_ENUMERATE_SUB_KEYS权限,

//同时也可以是几大根键值:

//HKEY_CLASSES_ROOT

//HKEY_CURRENT_CONFIG

//HKEY_CURRENT_USER

//HKEY_LOCAL_MACHINE

//HKEY_USERS

 __in DWORD dwIndex, //子项序号,第一次调用可为0,如果序号溢出将返回259号错误

 __out LPTSTR lpName, //返回子项名称的buff

 __inout      LPDWORD lpcName,//lpName的容量,函数返回后,返回lpname内容字节

 __reserved  LPDWORD lpReserved,//保留,为NULL

 __inout     LPTSTR lpClass,//返回子项类型,可以为NULL

 __inout_opt LPDWORD lpcClass,//lpClass容量,可以为NULL,同时返回装载的字节数

 __out_opt   PFILETIME lpftLastWriteTime//返回子项最后修改时间,可以为NULL

);

以下为伪代码:

char szKeyName[100]; memset(szKeyName, 0, 100);

char szClass[100]; memset(szClass, 0, 100);

HKEY hKey; long nErr = 0;

DWORD nNameLen = 100, nClassLen = 100;

FILETIME timeFile;

if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG, " REGTEST",

0, KEY_ALL_ACCESS/*KEY_ENUMERATE_SUB_KEYS*/, &hKey)) {

                  if (ERROR_SUCCESS == (nErr = RegEnumKeyEx(HKEY_CURRENT_CONFIG/*hKey*/,

0, szKeyName, &nNameLen, NULL, szClass, &nClassLen, &timeFile)))

                           AfxMessageBox(szKeyName);

}

2.4.2枚举值项

此函数是提取指定值项(通过序号指定)的信息,如:值,值项类型,值项名称等。

LONG WINAPI RegEnumValue(

 __in   HKEY hKey, //已打开的项句柄,必须有KEY_QUERY_VALUE权限,

//同时也可以是几大根键值:

//HKEY_CLASSES_ROOT

//HKEY_CURRENT_CONFIG

//HKEY_CURRENT_USER

//HKEY_LOCAL_MACHINE

//HKEY_USERS

 __in DWORD dwIndex, //值项序号,第一次调用可为0,如果序号溢出将返回259号错误

 __out LPTSTR lpValueName,//装值项名的buff

 __inout     LPDWORD lpcchValueName,//前一个参数的容量,同时返回其长度

 __reserved  LPDWORD lpReserved,//保留,为NULL

 __out_opt   LPDWORD lpType,//返回值项类型,有REG_SZ,REG_DWORD等类型

 __out_opt   LPBYTE lpData,//装值项值的buff

 __inout_opt LPDWORD lpcbData//lpData的容量,同时返回lpData接收的字节数

);

以下是伪代码:

char szValueName[100]; memset(szValueName, 0, 100);

BYTE pValue[100]; memset(pValue, 0, 100);

HKEY hKey; long nErr = 0;

DWORD nNameLen = 100, nValueLen = 100, nType = 0;;

FILETIME timeFile;

if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

" REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)) {

        if (ERROR_SUCCESS == (nErr = RegEnumValue(hKey, 1, szValueName, &nNameLen,

NULL, &nType, pValue, &nValueLen))){

                  CString szResult;

                  if (REG_SZ == nType)

                           szResult.Format(_T("%s的值是:%s"), szValueName, (char*)pValue);

                  else if (REG_DWORD == nType)

                           szResult.Format(_T("%s的值是:%d"), szValueName, *((DWORD*)pValue));

                  AfxMessageBox(szResult);

        }

}

2.4.3项批量查询(提取)

查询指定项下面的子项数据与其下值项数据,如:子项的数量,值项的数量,子项中名称最长的长度,值项中名称最长的长度。其函数原型如下:

LONG WINAPI RegQueryInfoKey(

 __in        HKEY hKey, //已打开的项句柄,必须有KEY_QUERY_VALUE权限,

//同时也可以是几大根键值:

//HKEY_CLASSES_ROOT

//HKEY_CURRENT_CONFIG

//HKEY_CURRENT_USER

//HKEY_LOCAL_MACHINE

//HKEY_USERS

 __out_opt   LPTSTR lpClass, //返回项的类型

 __inout_opt LPDWORD lpcClass,//lpClass容量,同时返回其长度

 __reserved  LPDWORD lpReserved,//保留,必须为NULL

 __out_opt   LPDWORD lpcSubKeys,//返回其下子项的数量

 __out_opt   LPDWORD lpcMaxSubKeyLen,//返回子项中名称最长的项的长度

 __out_opt   LPDWORD lpcMaxClassLen,//返回子项中类型名最长的长度

 __out_opt   LPDWORD lpcValues,//返回指定项的值项的数量

 __out_opt   LPDWORD lpcMaxValueNameLen,//返回指定项的值项中名称最长的长度

 __out_opt   LPDWORD lpcMaxValueLen,//返回指定项的值项中值的最长长度

 __out_opt   LPDWORD lpcbSecurityDescriptor,//安全描述,可以为NULL

 __out_opt   PFILETIME lpftLastWriteTime//指定项,或其下的所有项中最晚修改时间

);

以下为伪代码:

char szClassName[100]; memset(szClassName, 0, 100);

DWORD nClassLen = 0, nSubKeys = 0, nMaxSubKey = 0, nMaxClass = 0;

DWORD nValues = 0, nMaxValueNameLen = 0, nMaxValueLen = 0;

FILETIME timeFile;

HKEY hKey; long nError = 0;

if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\360desktop\\",

 0, KEY_ALL_ACCESS, &hKey)) {

        if (ERROR_SUCCESS == (nError = RegQueryInfoKey(hKey, szClassName, &nClassLen,

NULL, &nSubKeys, &nMaxSubKey, &nMaxClass, &nValues, &nMaxValueNameLen, &nMaxValueLen, NULL, &timeFile ))){

                  CString szResult;

                  szResult.Format(_T("szClassName:%s, nClassLen:%d, nSubKeys:%d, \

nMaxSubKey:%d, nMaxClass:%d,\

                                                       nValues:%d, nMaxValueNameLen:%d, nMaxValueLen:%d "), 

                                                       szClassName, nClassLen, nSubKeys, nMaxSubKey,

nMaxClass, nValues, nMaxValueNameLen, nMaxValueLen);

                  AfxMessageBox(szResult);

        }

}

2.4.4值项批量查询(提取)

RegQueryMultipleValue此方法是批量查询、提取指定项下的值项数据,操作繁琐,不是很方便,不建议新手用,新手可用RegEnumValueRegQueryValueEx一个一个提取。

RegQueryMultipleValue函数原型如下:

LONG WINAPI RegQueryMultipleValues(

 __in        HKEY hKey, //已打开的项句柄,必须有KEY_QUERY_VALUE权限,

//同时也可以是几大根键值:

//HKEY_CLASSES_ROOT

//HKEY_CURRENT_CONFIG

//HKEY_CURRENT_USER

//HKEY_LOCAL_MACHINE

//HKEY_USERS

 __out       PVALENT val_list,//数组指针,装值项信息用的,对这个参数下面详细介绍

 __in        DWORD num_vals,//val_list数组元素个数

 __out_opt   LPTSTR lpValueBuf,//装值项的值的buff,全部值项的值串行存放,配合

//val_list中的信息提取值,所以说麻烦吧

 __inout_opt LPDWORD ldwTotsize//plValueBuf容量,返回实际接收字节数

);

此函数,通过第四个参数lpValueBuf接收指定项下所有值项的值,把所有值项的值安串行方式装载,提取的时候,配合第二个参数val_list提取,VALENT结构中存储了值项的值类型,还有值在lpValueBuf中的具体位置,还有值数据在lpValueBuf中占的字节数。下面介绍一下VALENT结构原型:

typedef struct value_ent {

LPTSTR ve_valuename; //值项名称,调用RegQueryMultipleValue前必须填充,

                                           //RegQueryMultipleValue函数是通过这个名称来提取值项数据的

 DWORD    ve_valuelen;//取回的值项的值的字节数

 DWORD_PTR ve_valueptr;//值项的值在RegQueryMultipleValues参数lpValueBuf中的位置

 DWORD    ve_type;  //取回值项的值的类型

} VALENT, *PVALENT;

以下为伪代码:

char szClassName[100]; memset(szClassName, 0, 100);

VALENT pValent[3]; DWORD nValentCount = 3;

memset(pValent, 0, sizeof(pValent));

pValent[0].ve_valuename = _T("Version");//输入值项名称

pValent[1].ve_valuename = _T("uac0");

pValent[2].ve_valuename = _T("TestDword");

 

char szVale[1024]; DWORD nValueLen = 1024;

FILETIME timeFile;

HKEY hKey; long nError = 0;

if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\360desktop\\",

        0, KEY_ALL_ACCESS, &hKey)) {

        if (ERROR_SUCCESS == (nError = RegQueryMultipleValues(hKey, pValent,

                  nValentCount, szVale, &nValueLen))){

                           CString szResult;

                           for (int i = 0; i < nValentCount; ++i) {

                                    CString szTemp;

                                    if(REG_SZ == pValent[i].ve_type){

                                              szTemp.Format(_T("%d个参数[%s]的值是:%s\r"), i,

                                                       pValent[i].ve_valuename, (char*)pValent[i].ve_valueptr);

                                    }

                                    else if (REG_DWORD == pValent[i].ve_type){

                                              szTemp.Format(_T("%d个参数[%s]的值是:%d\r"), i,

                                                       pValent[i].ve_valuename, *((DWORD*)pValent[i].ve_valueptr));

                                    }

                                    if(!szTemp.IsEmpty())

                                              szResult += szTemp;

                  }

                  AfxMessageBox(szResult);

        }

}

注册表相关项的切图如下:

https://img-my.csdn.net/uploads/201211/27/1353981205_2299.jpg

效果图如下:

https://img-my.csdn.net/uploads/201211/27/1353981209_1849.jpg

3. 示例代码

以上每个函数具体使用操作都写了源码,并测试通过,编译环境是VC++6.0,每个函数对应一个按钮,如图:

https://img-my.csdn.net/uploads/201211/27/1353981213_5914.jpg

以下链接可下载源码:http://download.csdn.net/detail/mingojiang/4439227

不想下载的,我把代码片段粘在下面,使用时稍加修改复制到自己工程里就OK了。

void CRegTestDlg::OnAddValue()

{

        HKEY hKey;

        if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

                  " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)){

                  DWORD nType = REG_SZ;

                  char szName[] = {"我叫小王"};

                  RegSetValueEx(hKey, "Name", 0, nType,

                           (const PBYTE)szName, strlen(szName));

                  nType = REG_DWORD;

                  DWORD nYears = 60;

                  RegSetValueEx(hKey, "Years", 0, nType, (const PBYTE)&nYears, 4);

        }

}

 

void CRegTestDlg::OnDeleteValue()

{

        HKEY hKey;

        if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

                  " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)){

                  RegDeleteValue(hKey, "Name");

                  RegDeleteValue(hKey, "Years");

        }

}

 

void CRegTestDlg::OnKeyCreate()

{

        HKEY hKey;

        DWORD dw;

        if(ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_CONFIG,

                  " REGTEST\\GPS设备网络通道\\", 0,

                  NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,

                  NULL, &hKey, &dw))

                  AfxMessageBox(_T("创建成功"));

}

 

void CRegTestDlg::OnKeyOpen()

{

        HKEY hKey;

        if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

                  " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey))

                  AfxMessageBox(_T("打开成功"));

}

 

void CRegTestDlg::OnKeyClose()

{

        HKEY hKey;

        if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

                  " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)){

                  if (ERROR_SUCCESS == RegCloseKey(hKey))

                           AfxMessageBox(_T("关闭成功"));

        }

}

 

void CRegTestDlg::OnKeyDelete()

{

        if(ERROR_SUCCESS == RegDeleteKey(HKEY_CURRENT_CONFIG,

                  " REGTEST\\GPS设备网络通道\\"))

                  AfxMessageBox(_T("删除成功"));

}

 

void CRegTestDlg::OnRegQueryValue()

{

        HKEY hKey;

        if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

                  " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)){

                  DWORD nType = 0, nLen = 100;

                  char szName[100];

                  RegQueryValueEx(hKey, "Name", 0, &nType, (const PBYTE)szName, &nLen);

                  nType = 0;

                  DWORD nYears = 0; nLen = 4;

                  RegQueryValueEx(hKey, "Years", 0, &nType, (const PBYTE)&nYears, &nLen);

                  int i = 0;

        }

}

 

void CRegTestDlg::OnRegEnumKey()

{

        char szKeyName[100]; memset(szKeyName, 0, 100);

        char szClass[100]; memset(szClass, 0, 100);

        HKEY hKey; long nErr = 0;

        DWORD nNameLen = 100, nClassLen = 100;

        FILETIME timeFile;

        if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG, " REGTEST", 0,

                  KEY_ALL_ACCESS, &hKey)) {

                  if (ERROR_SUCCESS == (nErr = RegEnumKeyEx(HKEY_CURRENT_CONFIG/*hKey*/, 0,

                           szKeyName, &nNameLen, NULL, szClass, &nClassLen, &timeFile)))

                           AfxMessageBox(szKeyName);

        }

}

 

void CRegTestDlg::OnRegEnumValue()

{

        char szValueName[100]; memset(szValueName, 0, 100);

        BYTE pValue[100]; memset(pValue, 0, 100);

        HKEY hKey; long nErr = 0;

        DWORD nNameLen = 100, nValueLen = 100, nType = 0;;

        if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

                  " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)) {

                  if (ERROR_SUCCESS == (nErr = RegEnumValue(hKey, 1, szValueName,

                           &nNameLen, NULL, &nType, pValue, &nValueLen))){

                           CString szResult;

                           if (REG_SZ == nType) {

                                   szResult.Format(_T("%s的值是:%s"), szValueName, (char*)pValue);

                           }

                           else if (REG_DWORD == nType) {

                                    szResult.Format(_T("%s的值是:%d"), szValueName, *((DWORD*)pValue));

                           }

                           AfxMessageBox(szResult);

                  }

        }

}

 

void CRegTestDlg::OnRegQueryInfoKey()

{

        char szClassName[100]; memset(szClassName, 0, 100);

        DWORD nClassLen = 0, nSubKeys = 0, nMaxSubKey = 0, nMaxClass = 0;

        DWORD nValues = 0, nMaxValueNameLen = 0, nMaxValueLen = 0;

 

        FILETIME timeFile;

        HKEY hKey; long nError = 0;

        if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,

                  "SOFTWARE\\360desktop\\", 0, KEY_ALL_ACCESS, &hKey)) {

                  if (ERROR_SUCCESS == (nError = RegQueryInfoKey(hKey, szClassName,

                           &nClassLen, NULL, &nSubKeys, &nMaxSubKey,

                           &nMaxClass, &nValues, &nMaxValueNameLen, &nMaxValueLen,

                           NULL, &timeFile ))){

                           CString szResult;

                           szResult.Format(_T("szClassName:%s, nClassLen:%d, nSubKeys:%d, \

                                                                          nMaxSubKey:%d, nMaxClass:%d,

                                                                nValues:%d, nMaxValueNameLen:%d, nMaxValueLen:%d "), 

                                                                szClassName, nClassLen, nSubKeys, nMaxSubKey,

                                                                nMaxClass, nValues, nMaxValueNameLen, nMaxValueLen);

                           

                           AfxMessageBox(szResult);

                  }

        }

}

 

void CRegTestDlg::OnRegQueryMutipleValue()

{

        char szClassName[100]; memset(szClassName, 0, 100);

        VALENT pValent[3]; DWORD nValentCount = 3;

        memset(pValent, 0, sizeof(pValent));

        pValent[0].ve_valuename = _T("Version");

        pValent[1].ve_valuename = _T("uac0");

        pValent[2].ve_valuename = _T("TestDword");

 

        char szVale[1024]; DWORD nValueLen = 1024;

        HKEY hKey; long nError = 0;

        if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,

                  "SOFTWARE\\360desktop\\",0, KEY_ALL_ACCESS, &hKey)) {

                  if (ERROR_SUCCESS == (nError = RegQueryMultipleValues(hKey, pValent,

                           nValentCount, szVale, &nValueLen))){

                                    CString szResult;

                                    for (UINT i = 0; i < nValentCount; ++i) {

                                              CString szTemp;

                                              if(REG_SZ == pValent[i].ve_type){

                                                       szTemp.Format(_T("%d个值项[%s]的值是:%s\r"), i,

                                                                pValent[i].ve_valuename, (char*)pValent[i].ve_valueptr);

                                              }

                                              else if (REG_DWORD == pValent[i].ve_type){

                                                       szTemp.Format(_T("%d个值项[%s]的值是:%d\r"), i,

pValent[i].ve_valuename, *((DWORD*)pValent[i].ve_valueptr));

                                              }

                                              if(!szTemp.IsEmpty())

                                                       szResult += szTemp;

                           }

                           AfxMessageBox(szResult);

                  }

        }

}

【转载】https://blog.csdn.net/MingoJiang/article/details/7764348

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值