Qt5 解决读取Windows系统注册表,无法读取带"\"键的键值问题
最近遇到一个问题,就是在
这样的注册表项,在QT中,可以读取注册表左边的key,但是无法获取右边的value,
发现之前的人也遇到相同的问题:http://www.qtcn.org/bbs/read-htm-tid-55782.html
其实,这个东西Qt的文档中说的很明确:
Note that the backslash character is, as mentioned, used by QSettings to separate subkeys. As a result, you cannot read or write windows registry entries that contain slashes or backslashes; you should use a native windows API if you need to do so.
遇到这种情况,需要在QT中调用windows API进行解决。
(1)在QT中添加windows API操作注册表需要的静态库和头文件
在项目pro文件中添加:
LIBS += -lAdvapi32
添加头文件
#include <qt_windows.h>
(2)在QT中读取
QSettings reg("HKEY_CURRENT_USER\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\MuiCache",QSettings::NativeFormat); for(int i = 0; i < reg.allKeys().size(); ++i) { QString key = reg.allKeys().at(i); QString value = reg.value(key).toString(); qDebug() << "key is: " << key << "value is: " <<value; }
在windows7和windows 10中均有该注册表项,该注册表中有部分应用程序的执行路径,目标是通过找到这些路径,关联应用程序启动。QT读取注册表还是比较简单的,
发现可以打印出key,但是value始终为空。查找了很多资料,发现本文开头也遇到这样的问题,只可惜当时他们怎么解决的,没有记录下来,我这里就把自己解决的方法记录下来。
继续上面的代码,在下面添加:
#define Q_WS_WIN #ifdef Q_WS_WIN //声明要使用windows API HKEY hKey; //打开启动项Key if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\MuiCache", 0, KEY_READ, &hKey) != ERROR_SUCCESS) { qDebug() << "windows api read reg failed!"; } else{ qDebug() << "windows api read reg success"; } for(int i = 0; i < reg.allKeys().size(); ++i) { QString key = reg.allKeys().at(i); DWORD dwSize = 1024; //这个值太小,容纳不下返回值的话,RegQueryValueEx会返回一个错误码 DWORD dwType = REG_DWORD; //值的类型REG_SZ,返回键值类型 WCHAR buf[1024]; QString backslash_key = key.replace(QChar('/'), QChar('\\')); const wchar_t * w_key = reinterpret_cast<const wchar_t *>(backslash_key.utf16());//char * 转换为 wchar_t * 类型 //DWORD dwRet = RegQueryValueEx(hKey, L"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\devenv.exe.FriendlyAppName", NULL, NULL, (LPBYTE)(&buf), &dwSize); DWORD dwRet = RegQueryValueEx(hKey, w_key, NULL, &dwType, (LPBYTE)(&buf), &dwSize); if (ERROR_SUCCESS != dwRet) { qDebug() << "RegQueryValueEx failed " << dwRet; RegCloseKey(hKey); }else { if(dwType == REG_SZ) //字符串类型 { QString strMessage = QString::fromUtf16(reinterpret_cast<const ushort *>(buf), dwSize/2 - 1); qDebug() << "dwSize is: " << dwSize << "value is: " << strMessage; } if(dwType == REG_BINARY) { qDebug() << "dwType == REG_BINARY ==============================="; } } } RegCloseKey(hKey); #endif
利用QT读取注册的keys,然后用windows API解决读取不了带"\"键的键值问题。
在读取注册表项时候的遇到的错误码:
返回值为2 表示系统找不到这个文件,多半是路径写错了。
返回值为6 表示handle无效
欢迎正在学习QT和在利用QT开发项目过程中遇到的问题,都可以在这里进行讨论:
Qt学习交流 678387732
相关参考资料:
使用RegOpenKeyEx 等windows注册函数时,编译无法解析问题 https://blog.csdn.net/linuxsmallping/article/details/51722648
注册表操作函数:https://msdn.microsoft.com/en-us/library/windows/desktop/ms724897(v=vs.85).aspx
操作注册表错误码:https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx
QString和widows API中需要的字符串格式转换问题解决:https://www.cnblogs.com/findumars/p/7011198.html
https://stackoverflow.com/questions/11279371/converting-utf-16-qbytearray-to-qstring
windows API操作注册表教程:https://lellansin.wordpress.com/2014/07/28/windows-api-%E6%95%99%E7%A8%8B%EF%BC%88%E5%8D%81%EF%BC%89-%E6%B3%A8%E5%86%8C%E8%A1%A8%E6%93%8D%E4%BD%9C/
https://blog.csdn.net/end_ing/article/details/23766453
https://bbs.csdn.net/topics/391857416