1 MFC中
1.1 文件准备
这是被人写的,我也忘了从哪儿找的了,我放在网盘了:http://pan.baidu.com/s/1qtEQ
1.2 使用(当然,要包含头文件了:#include "EnumSerial.h" )
CArray asi;
// Populate the list of serial ports.
EnumSerialPorts(asi, FALSE);
for (int ii=0; ii
{
CString s_comName(asi[ii].strFriendlyName); // 这个就是可用串口名称,这个名称除了COMX外,可能还有其他描述字符,下面可以按照自己需求进行处理了
}
2 其他
下面的内容来自网页:http://www.xinfanghuatai.com/js_Show.asp?ArticleID=150,为防止网页失效特意粘过来,未加以测试:
方法一:通过注册表枚举串口号。本方法相对比较可靠,建议使用。另外,在USB转串口及虚拟串口的情况下,请多试几个厂家。
int GetSerialPortsReg(char (*pListStr)[80])
{
HKEY hKey;
LPCTSTR data_Set="HARDWARE//DEVICEMAP//SERIALCOMM//";
long ret0 = (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, data_Set, 0, KEY_READ, &hKey));
if(ret0 != ERROR_SUCCESS)
{
return -1;
}
int i = 0;
CHAR Name[25];
UCHAR szPortName[80];
LONG Status;
DWORD dwIndex = 0;
DWORD dwName;
DWORD dwSizeofPortName;
DWORD Type;
dwName = sizeof(Name);
dwSizeofPortName = sizeof(szPortName);
do
{
Status = RegEnumValue(hKey, dwIndex++, Name, &dwName, NULL, &Type,
szPortName, &dwSizeofPortName);
if((Status == ERROR_SUCCESS)||(Status == ERROR_MORE_DATA))
{
if (pListStr != NULL)
{
memcpy(*(pListStr + i), (LPCSTR)szPortName, 80);
}
i++;
}
} while((Status == ERROR_SUCCESS)||(Status == ERROR_MORE_DATA));
RegCloseKey(hKey);
return i;
}
方法二:通过EnumPorts函数枚举串口号。有网上信息说当虚拟串口号时,此种方式可能监测不到。使用本方法的人员请自行验证一下。
int GetSerialPortsSys(char (*pListStr)[80])
{
DWORD pcReturned = 0;
DWORD pcbNeeded = 0;
BYTE *outb = NULL;
EnumPorts(NULL, 2, outb, 0, &pcbNeeded, &pcReturned);
outb = new byte[pcbNeeded];
EnumPorts(NULL, 2, &outb[0], pcbNeeded, &pcbNeeded, &pcReturned);
PORT_INFO_2 *portsArray ;
portsArray = (PORT_INFO_2 *)(outb);
for (unsigned int i = 0; i< pcReturned; i++)
{
if (((AnsiString)(*(portsArray + i)).pPortName).Pos("COM") > 0)
{
memcpy(*(pListStr + i), (*(portsArray + i)).pPortName, 80);
}
}
return pcReturned;
}
方法三:一个一个试的方式,虽然笨拙却很有效,避免USB转串口,或者虚拟串口等问题。但该方法用的时间比较长,大约需要7秒左右。
//获取主机串口列表:一个一个试的方式。
void EnumerateSerialPorts(TStringList* comStrings)
{
AnsiString asPort = "";
//清除串口数组内容
comStrings->Clear();
//因为至多有255个串口,所以依次检查各串口是否存在
//如果能打开某一串口,或打开串口不成功,但返回的是 ERROR_ACCESS_DENIED错误信息,
//都认为串口存在,只不过后者表明串口已经被占用
//否则串口不存在
for (int i=1; i<256; i++)
{
//Form the Raw device name
asPort = "\\\\.\\COM" + IntToStr(i);
//Try to open the port
BOOL bSuccess = FALSE;
HANDLE hPort = ::CreateFile(asPort.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if (hPort == INVALID_HANDLE_VALUE)
{
DWORD dwError = ::GetLastError();
if (dwError != 2) //串口存在,被占用 ERROR_ACCESS_DENIED
{
bSuccess = TRUE;
}
}
else //串口可被打开
{
//The port was opened successfully
bSuccess = TRUE;
//Don't forget to close the port, since we are going to do nothing with it anyway
CloseHandle(hPort);
}
//Add the port number to the array which will be returned
if (bSuccess) //所有存在的串口
{
comStrings->Add("COM"+IntToStr(i));
}
}
return;
}