Qt5 解決讀取Windows系統註冊表,沒法讀取帶"\"鍵的鍵值問題

最近遇到一個問題,就是在html

這樣的註冊表項,在QT中,能夠讀取註冊表左邊的key,可是沒法獲取右邊的value,linux

發現以前的人也遇到相同的問題:http://www.qtcn.org/bbs/read-htm-tid-55782.htmlwindows

其實,這個東西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.api

遇到這種狀況,須要在QT中調用windows API進行解決。wordpress

(1)在QT中添加windows API操做註冊表須要的靜態庫和頭文件函數

在項目pro文件中添加:post

LIBS += -lAdvapi32

添加頭文件學習

#include <qt_windows.h> 

(2)在QT中讀取ui

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讀取註冊表仍是比較簡單的,spa

發現能夠打印出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中須要的字符串格式轉換問題解決:http://www.javashuo.com/article/p-vrdiznnj-z.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

相關文章
相關標籤/搜索