转自:http://www.armce.cn/bbs/thread-188-1-1.html
原理其实非常简单,利用注册表查找在线的设备来枚举可用的串口
注册表位置及步骤:
1、取串口
HKEY_LOCAL_MACHINE/Drivers/Active/*
2、取COM设备键值Key名称
3、取来的键值 (eg. Drivers/BuiltIn/Serial)
HKEY_LOCAL_MACHINE/Drivers/BuiltIn/Serial
4、取FriendlyName友好名称值(eg.Serial Cable on COM1:)
取其它设置在这里省略了(eg. IRQ、DLL、Port...... )
- //************************************************************************
- // Popzone@ARMCE VS2005 学习代码片断:
- // Data : 2009.06.01
- //************************************************************************
- // sub1 OpenActiveDriverKey 查询在线可用驱动
- // sub2 GetKeyValue 取键值内容
- // main EnumeratePorts 枚举端口
- //************************************************************************
- 子函数:
- LONG OpenActiveDriverKey(LPCTSTR pszDriver, HKEY *phKey)
- {
- CString strFullName(_T("Drivers//Active//"));
- LONG lRes;
- strFullName += pszDriver;
- lRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strFullName, 0, KEY_READ, phKey);
- return lRes;
- }
- 子函数:
- LONG GetKeyValue(HKEY hKey, LPCTSTR pszValueName, CString &strValue)
- {
- LONG lRes;
- DWORD dwSize = 0,
- dwType;
- lRes = RegQueryValueEx(hKey, pszValueName, NULL, &dwType, NULL, &dwSize);
- if(lRes == ERROR_SUCCESS)
- {
- TCHAR* pszValue = new TCHAR[dwSize / sizeof(TCHAR)];
- if(pszValue != NULL)
- {
- lRes = RegQueryValueEx(hKey, pszValueName, NULL, &dwType, (BYTE*)pszValue, &dwSize);
- if(lRes == ERROR_SUCCESS)
- strValue = pszValue;
- delete [] pszValue;
- }
- else
- lRes = ERROR_NOT_ENOUGH_MEMORY;
- }
- return lRes;
- }
- 主代码:
- void CEmunCommPortDlg::EnumeratePorts()
- {
- HKEY hKey;
- LONG lRes;
- int iItem = 0;
- lRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Drivers//Active"), 0, KEY_READ, &hKey);
- if(lRes == ERROR_SUCCESS)
- {
- DWORD dwIndex;
- for(dwIndex = 0; ; ++dwIndex)
- {
- TCHAR szKeyName[128];
- DWORD dwNameSize = 128;
- lRes = RegEnumKeyEx(hKey, dwIndex, szKeyName, &dwNameSize, NULL, NULL, NULL, NULL);
- if(lRes == ERROR_SUCCESS)
- {
- HKEY hKeyDrv;
- lRes = OpenActiveDriverKey(szKeyName, &hKeyDrv);
- if(lRes == ERROR_SUCCESS)
- {
- CString strDriverName, //驱动名称
- strDriverKey, //驱动建值
- strFriendlyName; //友好名称
- if(GetKeyValue(hKeyDrv, _T("Name"), strDriverName) == ERROR_SUCCESS)
- {
- CString strPrefix(strDriverName.Left(3));
- // 验证COMM Port端口
- if(strPrefix.CompareNoCase(_T("COM")) == 0)
- {
- if(GetKeyValue(hKeyDrv, _T("Key"), strDriverKey) == ERROR_SUCCESS)
- {
- HKEY hKeyBase;
- lRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strDriverKey, 0, KEY_READ, &hKeyBase);
- if(lRes == ERROR_SUCCESS)
- {
- GetKeyValue(hKeyBase, _T("FriendlyName"), strFriendlyName);
- RegCloseKey(hKeyBase);
- }
- }
- //这是我用的ListContorl,你们可以自行定义输出:
- //iItem = lst_CommPortList.InsertItem(iItem,strDriverName);
- //lst_CommPortList.SetItemText(iItem,1,strFriendlyName);
- }
- }
- RegCloseKey(hKeyDrv);
- }
- }
- else
- break;
- }
- RegCloseKey(hKey);
- }
- }