在开发一个Modbus的串口监测工具软件的时候,启动工具软件,希望一开始就能在下拉框检测到当前有效的USB串口。
刚开始做的时候是用的穷举法,就是“COM0”~“COM15”一个一个尝试打开。但是,这样做一个是效率低下,另一个是换了新的USB-串口适配器,有可能虚拟串口端口号超过了COM15,这样就找不到可用串口了。网上查找了资料,通过读取windows注册表的方式,很好解决了这个问题。
void CSerialCtrlDemoDlg::GetAllCom(void){long lReg; HKEY hKey;DWORD MaxValueLength; DWORD dwValueNumber; lReg=RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_QUERY_VALUE, &hKey); if(lReg!=ERROR_SUCCESS) { AfxMessageBox("Please check comport!\n"); return; } lReg=RegQueryInfoKeyA( hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwValueNumber, //返回和hKey关联的值 &MaxValueLength, NULL, NULL, NULL); if( lReg != ERROR_SUCCESS ) {//没有成功AfxMessageBox("Getting Info Error!\n"); return; } LPSTR pValueName,pCOMNumber; DWORD cchValueName,dwValueSize=6; for(DWORD i=0; i < dwValueNumber; i++) { cchValueName = MaxValueLength + 1; dwValueSize = 6; pValueName=(LPSTR)VirtualAlloc(NULL, cchValueName, MEM_COMMIT, PAGE_READWRITE); lReg=RegEnumValueA( hKey, i, pValueName, &cchValueName, NULL, NULL, NULL, NULL); if( (lReg != ERROR_SUCCESS) && (lReg != ERROR_NO_MORE_ITEMS) ) { AfxMessageBox("Enum Registry Error or No More Items!\n"); continue; } pCOMNumber = (LPSTR)VirtualAlloc(NULL, 6, MEM_COMMIT, PAGE_READWRITE); lReg=RegQueryValueExA( hKey, pValueName, NULL, NULL, (LPBYTE)pCOMNumber, &dwValueSize); if(lReg != ERROR_SUCCESS) { AfxMessageBox("Can not get the name of the port"); continue; } CString strCommList;//CharToUnicode(pCOMNumber,&strCommList);strCommList.Format("%s", pCOMNumber);BOOL m_bInsert=0;if( ((CComboBox*)GetDlgItem(IDC_COMBO_SN))->GetCount() == 0 )((CComboBox*)GetDlgItem(IDC_COMBO_SN))->AddString(strCommList);else{CString strTemp=strCommList;strCommList.TrimLeft("COM");int icurrent;for( icurrent=0; icurrent<((CComboBox*)GetDlgItem(IDC_COMBO_SN))->GetCount(); icurrent++ ){CString strCurrent;((CComboBox*)GetDlgItem(IDC_COMBO_SN))->GetLBText(icurrent,strCurrent);strCurrent.TrimLeft("COM");if( _ttol(strCurrent) > _ttol(strCommList) ){((CComboBox*)GetDlgItem(IDC_COMBO_SN))->InsertString(icurrent,strTemp);m_bInsert = 1;break;}}if(!m_bInsert)((CComboBox*)GetDlgItem(IDC_COMBO_SN))->InsertString(icurrent,strTemp);}VirtualFree(pValueName,0,MEM_RELEASE); VirtualFree(pCOMNumber,0,MEM_RELEASE); } }