通過讀登錄檔檢測本機串列埠資訊
阿新 • • 發佈:2019-01-05
用QT做上位機,使用串列埠通訊時,想自動掃描串列埠裝置,即在下拉列表框中,只顯示已有的串列埠。
本來挺簡單的,只要輪詢HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM就能找到已有的串列埠,但QT的QSettings有個bug,如果鍵名裡有斜槓'/',則讀出的鍵值就是空的。參考別人使用API函式讀取鍵值的文章,寫了下面這個函式。
UINT32 comPortInfo(QStringList *qslKeyValList) { //1.從登錄檔中取出 鍵名 QString qsRegPath = "HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM"; QSettings *reg = new QSettings(qsRegPath,QSettings::NativeFormat); QStringList qsListKeys = reg->allKeys(); //childKeys(); QList<int> qlTmp; //2.再依次取出 鍵值 for (UINT32 i=0; i < qsListKeys.size(); i++) { HKEY hKey; wchar_t wsKeyName[256]; //鍵名陣列 char sKeyVal[32]; //鍵值陣列 DWORD ulKeyNameSize = sizeof(wsKeyName); DWORD ulKeyValSize = sizeof(sKeyVal); RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"),0,KEY_READ,&hKey); RegEnumValue(hKey, /*要查詢的已開啟的鍵的控制代碼*/ i, /*索引號*/ wsKeyName, /*返回所讀取的名稱*/ &ulKeyNameSize, /*返回讀取名稱的長度,不含chr(0)*/ 0, /*保留*/ 0, /*返回所讀取的資料型別*/ (BYTE*)sKeyVal, /*返回所讀取的資料*/ &ulKeyValSize); /*返回所讀取的資料長度*/ //取出類似 COM3 COM20 這樣的鍵值 //只取第3位以後的數字,放入list (方便排序) qlTmp.append( QString::fromUtf16((ushort*)sKeyVal).mid(3).toUInt() ); } //3.排序 // 因為字串排序 "COM12" < "COM3", 所以不能簡單地QStringList.sort() // 故先提取出數字, 再按數字排序, 再附加上字首COM qSort(qlTmp); for (UINT32 i=0; i<qsListKeys.size(); i++) { qslKeyValList->append(QString("COM%1").arg(qlTmp[i])); } //qDebug() << *qslKeyValList; return qsListKeys.size();
使用方法:
// 檢查本機串列埠裝置
QStringList qslKeyValList;
UINT32 uiComCount = comPortInfo(&qslKeyValList);
if(uiComCount == 0)
QMessageBox::about(NULL, "錯誤", "本機無串列埠裝置,請檢查串列埠線");
qDebug() << QString("=== 本機有%1個串列埠:").arg(uiComCount) << qslKeyValList;