C++ 通过RegEnumKeyEx枚举的问题
2016-05-25 16:43
507 查看
问题描述:
这几天在做列举IE浏览器插件的问题,后来想到了用注册列表的方法做。大体思路是从HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Ext\\Stats目录下获取所有的CLSID值,
然后从HKEY_CLASSES_ROOT\\CLSID下找到对应的值得到具体的信息
(网上有个老外写的软件:BrowserAddonsView可能做到)
问题出在通过CLSID找到具体信息这步上,发现使用RegEnumKeyEx枚举的信息总是和手动regedit进去看到对应键目录中值不一致,
有时会多,有时会少
问题代码:
BOOL GetRegListKey( HKEY iHeyIn, std::string sRegSubDir, std::vector<std::string> &sKeyList ) { TCHAR *pRegSubDir = _bstr_t( sRegSubDir.c_str() ); HKEY nKeyOut, nKeySubOut; DWORD iIndex = 0; TCHAR szSubKey[MAX_PATH] = _T(""); DWORD dSize = MAX_PATH; if ( CheckHkeyType(iHeyIn) == FALSE ) { std::cout << "Unknow HKEY type" << std::endl; return false; } LONG nLResult = RegOpenKeyEx(iHeyIn, pRegSubDir, 0, KEY_CREATE_LINK | KEY_WRITE | KEY_READ | KEY_NOTIFY, &nKeyOut); if( ERROR_SUCCESS != nLResult ) { std::cout << "Open Registor Error: " << nLResult << std::endl; return false; } while( ( nLResult = RegEnumKeyEx( nKeyOut, iIndex, szSubKey, &dSize, NULL, NULL, NULL, NULL) ) == ERROR_SUCCESS ) { //std::wcout << pRegSubDir << "\\" << pBuffer << std::endl; sKeyList.push_back( std::string(_bstr_t(szSubKey)) ); memset( szSubKey, 0, sizeof(szSubKey) ); dSize = MAX_PATH; iIndex++; } cout << nLResult << endl; return true; }
解决方法及其原因:
通过把HKEY_CLASSES_ROOT\CLSID下面没有出现的节点(而在程序中能够输出打印出来的节点)进行查找发现在Wow6432Node/CLSID下面。原来Win7及其以上的系统中,在注册列表HKEY_CLASSES_ROOT根键下面,有个Wow6432Node这个子主键,这个主键从网上查找发现
是个映射虚拟节点,会根据本地主机是32位还是64位系统进行映射。所以通过RegEnumKeyEx得到的节点是映射过后的,
可以通过在Wow6432Node/CLISID下面进行对比。
解决方法:
将上面函数改为:
BOOL GetRegListKey( HKEY iHeyIn, std::string sRegSubDir, std::list<std::string> &sKeyList ) { TCHAR *pRegSubDir = _bstr_t( sRegSubDir.c_str() ); HKEY nKeyOut = NULL; DWORD iIndex = 1; TCHAR szSubKey[MAX_PATH] = _T(""); DWORD dSize = MAX_PATH; if ( CheckHkeyType(iHeyIn) == FALSE ) { std::cout << "Unknow HKEY type" << std::endl; return false; } LONG nLResult = RegOpenKeyEx(iHeyIn, pRegSubDir, 0, /*KEY_CREATE_LINK | KEY_WRITE |*/ KEY_READ /*| KEY_NOTIFY*/ | KEY_WOW64_32KEY, &nKeyOut); switch ( nLResult ) { case ERROR_SUCCESS: break; case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: { if ( ( nLResult = RegOpenKeyEx(iHeyIn, pRegSubDir, 0, KEY_CREATE_LINK | KEY_WRITE | KEY_READ | KEY_NOTIFY | KEY_WOW64_64KEY, &nKeyOut) ) == ERROR_SUCCESS ) { break; } } break; case ERROR_ACCESS_DENIED: { std::cout << "请使用管理员身份运行" << endl; } break; default: { std::cout << "出现错误: " << nLResult << endl; } break; } if( ERROR_SUCCESS != nLResult ) { return false; } nLResult = RegEnumKeyEx( nKeyOut, iIndex, szSubKey, &dSize, NULL, NULL, NULL, NULL ); while ( nLResult == ERROR_SUCCESS ) { sKeyList.push_back( std::string(_bstr_t(szSubKey)) ); memset( szSubKey, 0, sizeof(szSubKey) ); dSize = MAX_PATH; iIndex++; nLResult = RegEnumKeyEx( nKeyOut, iIndex, szSubKey, &dSize, NULL, NULL, NULL, NULL) ; } RegCloseKey( nKeyOut ); return true; }
相关文章推荐
- 【CF 应用开发大赛】IT Share(IT分享网)
- 如何重装TCP/IP协议
- Windows 8 官方高清壁纸欣赏与下载
- 谁是桌面王者?Win PK Linux三大镇山之宝
- 对《大家都在点赞 Windows Terminal,我决定给你泼一盆冷水》一文的商榷
- Windows Clang开发环境备忘
- IT职场英语,必须学会
- 从Windows系统下访问Linux分区相关软件
- 对《大家都在点赞 Windows Terminal,我决定给你泼一盆冷水》一文的商榷
- Windows下搭建本地SVN服务器
- 使用Windows原生命令一键清空剪贴板
- 利用开源软件打造自己的全功能远程工具
- Windows 8虚拟机不能全屏的解决方法
- Visual Studio 2012 示例代码浏览器 - 数以千计的开发示例近在手边,唾手可得
- Visual Studio 2012 示例代码浏览器 - 数以千计的开发示例近在手边,唾手可得
- 微软镜像下载
- windows server域用户提升到本地更高权限组中的方法