VC下如何获得可使用的COM口?

mandysss 2009-06-19 09:45:03
如何获得目前可使用的COM口.除了电脑自带的COM1外,比如通过USB连接的手机,虚拟成的COM口.怎么得到这些?
...全文
323 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
fly2106 2009-09-02
  • 打赏
  • 举报
回复
///////////////////////////////////////////////////////////////////////////////////////读注册表
void CMyDlg::ShowComm()
{
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(_T("Open Registry Error!\n"));
return;
}

lReg=RegQueryInfoKeyA(hKey,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
&dwValueNumber, //返回和hKey关联的值
&MaxValueLength,
NULL,
NULL,
NULL);
if(lReg!=ERROR_SUCCESS) //没有成功
{
AfxMessageBox(_T("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(_T("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(_T("Can not get the name of the port"));
continue;
}

CString strCommList(pCOMNumber);

BOOL m_bInsert=0;

if(((CComboBox*)GetDlgItem(IDC_COM_PORT))->GetCount()==0)
{
((CComboBox*)GetDlgItem(IDC_COM_PORT))->AddString(strCommList);
}
else
{
CString strTemp=strCommList;
strCommList.TrimLeft("COM");
for(int icurrent=0;icurrent<((CComboBox*)GetDlgItem(IDC_COM_PORT))->GetCount();icurrent++)
{
CString strCurrent;
((CComboBox*)GetDlgItem(IDC_COM_PORT))->GetLBText(icurrent,strCurrent);
strCurrent.TrimLeft("COM");
if(_ttol(strCurrent)>_ttol(strCommList))
{
((CComboBox*)GetDlgItem(IDC_COM_PORT))->InsertString(icurrent,strTemp);
m_bInsert = 1;
break;
}
}
if(!m_bInsert)
((CComboBox*)GetDlgItem(IDC_COM_PORT))->InsertString(icurrent,strTemp);
}

VirtualFree(pValueName,0,MEM_RELEASE);
VirtualFree(pCOMNumber,0,MEM_RELEASE);
}
}
tcp8587 2009-07-23
  • 打赏
  • 举报
回复
不建议直接读注册表。还是逐一打开试试,代码如下:
CString strCom;
int nCom = 0;
int count = 0;
HANDLE hCom;
do {
nCom++;
strCom.Format("COM%d", nCom);
hCom = CreateFile(strCom, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
m_ctrlPort.AddString( strCom );

GetDlgItem(IDC_CLOSEPORT)->EnableWindow();

if(INVALID_HANDLE_VALUE == hCom )
{
DWORD error=::GetLastError();//取得错误信息


break;
}
count++;
} while(1);
zaodt 2009-07-23
  • 打赏
  • 举报
回复
注册表也不见得好在哪里;


一些 USB 转串口的,就会出现乱七八糟的东西!
codelast.com 2009-07-23
  • 打赏
  • 举报
回复
我就是直接读注册表的。逐一打开进行测试的方法有个不可避免的问题:当前串口正在使用中的时候,就无法打开了
fanlibing1984 2009-07-21
  • 打赏
  • 举报
回复
看不懂,深奥
hfcarrey 2009-07-14
  • 打赏
  • 举报
回复
哈哈,最简单就是逐个打开试试
killbug2004 2009-07-14
  • 打赏
  • 举报
回复
我的程序就是用5楼的代码,遍历注册表
bool SerialEnum::query()
{
HKEY hKey = NULL;

// try to open target registry key
if (ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE,
TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"),
0,
KEY_READ,
&hKey))
{
return false;
}

bool bResult = false;
TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name
DWORD cchClassName = MAX_PATH; // size of class string
DWORD cSubKeys=0; // number of subkeys
DWORD cbMaxSubKey; // longest subkey size
DWORD cchMaxClass; // longest class string
DWORD cValues; // number of values for key
DWORD cchMaxValue; // longest value name
DWORD cbMaxValueData; // longest value data
DWORD cbSecurityDescriptor; // size of security descriptor
FILETIME ftLastWriteTime; // last write time

DWORD DataType; //key data type
unsigned char KeyData[MAX_VALUE_DATA]; //key data buffer
DWORD DataSize = MAX_VALUE_DATA; //key data size
TCHAR achValue[MAX_VALUE_NAME];
DWORD cchValue = MAX_VALUE_NAME;
char tempstr[8];

LONG retCode = 0;

// Get the class name and the value count.
retCode = RegQueryInfoKey(
hKey, // key handle
achClass, // buffer for class name
&cchClassName, // size of class string
NULL, // reserved
&cSubKeys, // number of subkeys
&cbMaxSubKey, // longest subkey size
&cchMaxClass, // longest class string
&cValues, // number of values for this key
&cchMaxValue, // longest value name
&cbMaxValueData, // longest value data
&cbSecurityDescriptor, // security descriptor
&ftLastWriteTime); // last write time
if (retCode != ERROR_SUCCESS)
{
bResult = false;
goto _query_end;
}

// Enumerate the key values.
if (cValues == 0)
{
bResult = false;
goto _query_end;
}

for (int i=0; i<cValues; i++)
{
cchValue = MAX_VALUE_NAME;
achValue[0] = '\0';
DataType=0;
DataSize = MAX_VALUE_DATA;
KeyData[0]='\0';

retCode = RegEnumValue(
hKey, i,
achValue,
&cchValue,
NULL,
&DataType,
KeyData,
&DataSize);

if (retCode == ERROR_SUCCESS )
{
if (strstr(achValue,"USBSER") != NULL)
{
int k, j;
for (k=0,j=0; k<(int)DataSize; k++)
{
if ((KeyData[k]>'0' || KeyData[k]=='0') && (KeyData[k]<'9' || KeyData[k]=='9'))
{
tempstr[j] = KeyData[k];
j++;
}
}
tempstr[j]='\0';

m_arrItem[m_nCount] = atoi(tempstr);
m_nCount++;
}
}
}
bResult = (m_nCount > 0);

_query_end:
RegCloseKey(hKey);
return bResult;
}
sanguomi 2009-07-14
  • 打赏
  • 举报
回复
读注册表就可以了,
hawking81 2009-07-14
  • 打赏
  • 举报
回复
可以打开文件(就是串口了) 看返回值正常就可用
swb986 2009-07-07
  • 打赏
  • 举报
回复
吼吼,不错啊
一条晚起的虫 2009-06-29
  • 打赏
  • 举报
回复
//可以通过遍历注册表项
//HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM\\

HKEY hKey;
int rtn;

m_cmbComm.ResetContent();
rtn = RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Hardware\\DeviceMap\\SerialComm",
NULL, KEY_READ, &hKey);
if( rtn == ERROR_SUCCESS) // 打开串口注册表
{
int i=0;
char portName[256],commName[256];
DWORD dwLong,dwSize;
while(1)
{
dwSize = sizeof(portName);
dwLong = dwSize;
rtn = RegEnumValue( hKey, i, portName, &dwLong,
NULL, NULL, (PUCHAR)commName, &dwSize );
if( rtn == ERROR_NO_MORE_ITEMS ) // 枚举串口
break; // commName就是串口名字
i++;
}
RegCloseKey(hKey);
}
用户 昵称 2009-06-29
  • 打赏
  • 举报
回复
就是读注册表。
Conry 2009-06-28
  • 打赏
  • 举报
回复
HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM\\
z888c 2009-06-27
  • 打赏
  • 举报
回复
HANDLE CreateFile(
LPCTSTR lpFileName,

The following reserved device names cannot be used as the name of a file: CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9.
huohuo777777 2009-06-21
  • 打赏
  • 举报
回复
谢谢楼上的
fengrx 2009-06-19
  • 打赏
  • 举报
回复
看下这个:
点击:
CSerialPort v1.03 - Serial Port Wrapper
现在USB设备却很多,因此对USB设备的查找与读写就必不可少了。但是能找到关于USB读写的资料很少。这里使用VC++示范了一些获得USB的信息的方法。 一、枚举USB设备   通过枚举USB控制器->枚举此控制器上的USB HUB->枚举HUB的各个端->获得设备信息。 枚举控制器: wsprintf(HCName, "\\\\.\\HCD%d", HCNum); hHCDev = CreateFile(HCName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);   计算机上的USB主控制器以HCD1,HCD2等命名。通过控制器名称,使用CCreateFile 打开它。使用DeviceIoControl即可得到其驱动程序名,以及与它连接的HUB的名称。用CCreateFile打开HUB,获得连接信息。再枚举HUB的各个端即可获得连接的设备信息。 二、枚举HID设备   HID设备是微软定义的标准人机接规范。比如USB鼠标,USB游戏手柄等。不用查找具体设备的GUID,使用API HidD_GetHidGuid(&guidHID)即可得到GUID。有了GUID通过API SetupDiEnumDeviceInterfaces可获得是否有设备连接。如果此类设备连接通过SetupDiGetDeviceInterfaceDetail获得它的设备路径信息。使用CCreateFile 打开它,通过HidD_GetAttributes获得其基本属性信息。使用DeviceIoControl可以获得更详细的属性。在本代码中如果计算机上插有USB游戏手柄,可获得其信息。但不知道为什么xp下却不能获得USB鼠标的信息。 三 枚举U盘   先用GetDriveType API获得设备的类型,若类型为REMOVABLE(当然有些大容量U盘可能报告为FIXED,那就需要其他方法来确定了),即可能是U盘。用CCreateFile 打开之后,再用IOCTL_STORAGE_QUERY_PROPERTY为参数的DeviceIoControl来获得其属性。 四、结束语   示例工程在winxp+xpDDK+VC6下编译通过。USB设备种类比较多,也比较特殊,不同厂商的硬件不同,控制软件也不尽相同(我想主要是ICTL码不同,也不容易查到)。使得访问USB的设备不象串那么方便。这个例程只是展示了访问的基本方法。其中还有些问题还没有解决,发出来希望大家解决之后能通知我或者发表出来。 参考了USBPort,USBview等代码,一并致谢。

2,643

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧