设为首页 收藏本站
查看: 1192|回复: 0

[经验分享] Windows系统信息获取之一 -- 注册表操作

[复制链接]
累计签到:2 天
连续签到:1 天
发表于 2015-12-16 07:12:01 | 显示全部楼层 |阅读模式
前言:刚刚到了一个新公司,学习MFC。说来可笑,一直在Windows下开发软件,而且一直用着C++,而我竟然不会MFC。呵呵,无所谓了,反正学就是了。学习了一段时间,公司需要一个小工具,看着闲着无聊的我就让我做这个小工具。需求不是很复杂,获取Windows系统的一系列信息,诸如系统版本,CPU速度,内存大小,已安装的软件,正在运行的进程。这个小工具做了一周左右,算是完成了吧。这这里就把自己学习到的东西记录下来。如果,有和我一样对于这些基本操作不熟悉的人,可以看看。

这一篇先记录一些基本操作的使用。首先是注册表的操作:
用Windows系统的时间也不短了,平时如果手动杀毒也会用到注册表。但在接触到注册表之后我才发现,windows几乎将所有的信息基本都记录在了注册表中。闲话少说,先列出我用的注册表操作。

1.
打开注册表中的某一项:
WINADVAPI LSTATUS APIENTRY RegOpenKeyEx (HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult);
第一个参数是就是注册表的五大类如:HKEY_CLASS_ROOT,HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE,
HKEY_USERS, HKEY_CURRENT_CONFIG.
第二个参数是要打开的注册表项的其余路径:如要打开HKEY_CURRENT_USER\Software\Microsoft的话就
填上Software\\Microsoft.[注意\\,因为\需要转义]
第三个参数是根据MSDN上所说:must be zero.
第四个参数是读写模式,是个枚举值有很多查MSDN好了,我主要用到的就是KEY_READ
第五个参数就是你要把这个想保存在一个HKEY中,所以先定义好。
举个小例子:
比如要打开HKEY_CURRENT_USER\Software\Microsoft,就这样写:

HKEY hSubKey;
LONG lRet = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Microsoft"), 0, KEY_READ, &hSubKey);
if(ERROR_SUCESS == hSubKey)
{
    //成功
}
else
{
    //失败
}

刚才忘说返回值了,如果返回值为0的话就说明成功了。

2.获取一个项目下的键值

LONG RegQueryValueEx(
  HKEY hKey,            // handle to key
  LPCTSTR lpValueName,  // value name
  LPDWORD lpReserved,   // reserved
  LPDWORD lpType,       // type buffer
  LPBYTE lpData,        // data buffer
  LPDWORD lpcbData      // size of data buffer
);

从MSDN上拷贝来的解释,我想已经解释的听详细了,那就举个例子吧。
假如要获取HKEY_CURRENT_USER\Software\Microsoft下一个叫DisplayName的类型为REG_SZ的键值
那么请先写上一个函数的示例代码,如果打开成功了,那么就写:

DWORD dwType = REG_SZ;
DWORD dwBufferSize = 256;
CString strKeyValue;
LONG lRet = RegQueryValueEx(hSubKey, _T("DisplayName"), 0, &dwType, (BYTE*)strKeyValue.GetBuffer(dwBufferSize), &dwBufferSize)

如果返回值lRet为0则说明成功了。但这里我说明一点,在这里我获取的Key Value的变量类型是CStirng,
在写代码时如果这么写很方便,但是在获取值后,如果再对这个CString进行操作就会有问题。根据我调试的结果可以看出,这个CString的变量保存的字符串没有一null结尾从而导致对这个变量进行的如字符串连接这种操作会认为这个CString是一个空的字符串。我不知道是因为我机器的原因导致的这个问题还是在MFC中的操作都是这样。至少在OpenFileDialog中利用CString获取的文件路径也是这样的。所以,如果各位遇到了这个问题请注意。
我解决这个问题的方法有两种:1.用一个TCHAR数组来代替这个CString获取Key Value。2.用另一个CString将这个字符串拷贝进来,在我的程序中使用的都是Format函数。

3.枚举一个项目下的所有子项目:

LONG RegEnumKeyEx(
  HKEY hKey,                  // handle to key to enumerate
  DWORD dwIndex,              // subkey index
  LPTSTR lpName,              // subkey name
  LPDWORD lpcName,            // size of subkey buffer
  LPDWORD lpReserved,         // reserved
  LPTSTR lpClass,             // class string buffer
  LPDWORD lpcClass,           // size of class string buffer
  PFILETIME lpftLastWriteTime // last write time
);

这也是从MSDN中Copy过来的解释,下面直接上代码,比如我们要枚举HKEY_CURRENT_USER\Software\Microsoft下所有子项目:

DWORD dwIndex = 0;
CString strKeyName;
DWORD dwNameSize = 256;

LONG lRet = RegEnumKeyEx(hSubKey, dwIndex, strKeyName.GetBuffer(dwNameSize ), &dwNameSize, 0, NULL, NULL, NULL);
while(ERROR_SUCCESS == lRet)
{
    dwIndex++;
    dwNameSize = 256;
    lRet = RegEnumKeyEx(hSubKey, dwIndex, strKeyName.GetBuffer(dwNameSize ), &dwNameSize, 0, NULL, NULL, NULL);
}

解释一下上面的代码:
dwIndex是枚举用的索引,注册表的枚举和数组一样是从0开始的。
strKeyName是用来保存枚举出来的子项目的名字
dwNameSize和第二示例代码的意义是一样的
函数调用完毕后需要考察返回值,如果返回值为0说明这个项目下有子项,如果不为0一般有两种可能一种是这个子项的名字长度大于你预定的长度在上面代码中是256,另一种就是这个项目下面没有子项。
在取得第一个子项后需要继续向下检索,所以需要dwIndex++,而且因为在函数调用中dwNameSize会被改写,所以需要重新为它赋值[切记这一点否则在接下来的枚举中可能会失败],然后就是继续获取下一项,知道获取完毕为止。
----------------------------------------------------------------------------------
接下来介绍如何通过注册表获取CPU的个主频,以及通过注册表获取本机已经安装的软件。

1.CPU的主频:
在Windows注册表下保存CPU主频的位置在:
HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0
的名为"~MHz"的键中。当然0表示第一个CPU,如果你有两个CPU也可以继续读下去如果有1、2....这些项
就可以把其他CPU的速度读出来了。
下面是我写的代码:

DWORD GetProcessorSpeed()
{
    HKEY hKey;
    DWORD dwType = REG_DWORD, dwSize = sizeof(DWORD);
    DWORD dwCpuSpeed;
    //Open the appropriate registry key

    LONG lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
            _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
             0, KEY_READ, &hKey);
    if(ERROR_SUCCESS != lRet)
    {
        return 0;
    }
    lRet = RegQueryValueEx(hKey, _T("~MHz"), NULL,
                            &dwType, (BYTE*)&dwCpuSpeed, &dwSize);
    RegCloseKey(hKey);

    if(ERROR_SUCCESS != lRet)
    {
        return 0;
    }
    return dwCpuSpeed;
}

哦,对了在Open一个Key使用完毕后不要忘了用RegCloseKey(HKEY hKey)来关闭这个Key。

2.已安装的软件列表:
  在Windows注册表中有两个位置保存这已经安装的软件:
  HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall
  HKEY_LOCAL_MACHINE\
Software\Microsoft\Windows\CurrentVersion\Uninstall
  前者下面一般不会有什么子项的,但是比如Google Chrome浏览器的内容就是记录在这个下面的。
  还有一点是我对比Windows软件类表和360软件管家得到的一个规律。
  就是一个子项中如果包含一个叫SystemComponent的键(REG_DWORD)类型的而且它的值是0x00000001
  的话可以不用在软件列表中列出它来,因为这个项可能是某个软件的组件而不是一个独立的软件。当然,
  这也是有例外的,比如Office Plus 2007这一项就含有SystemComponent项而且值是1,但是Windows
  和360的软件管家仍然把它给列出来了。
  由于这个代码比较长就不列出来了。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-151699-1-1.html 上篇帖子: 利用Windows批处理脚本实现SNMP弱口令检测 下篇帖子: Windows7中重建图标缓存的方法(Rebuild Icon Cache)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表