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

 

 

 

posted @ 2018-04-27 10:43  懒猫的新窝  阅读(1022)  评论(0编辑  收藏  举报