原理其实非常简单,利用注册表查找在线的设备来枚举可用的串口
注册表位置及步骤:
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);
}
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/carlward/archive/2009/06/17/4275412.aspx