C++第五十篇 -- 获取串口的描述信息
如何知道自己的电脑上有无串口呢? -- 手动
1. 查看电脑,看是否有串口器件(串口是一个九针的D型接口)
2. 在设备管理器上查看
乍一看,还以为是有两个串口,其实仔细看描述就知道,这是蓝牙虚拟串口,并不是真实的串口,这台电脑上是没有接真实的串口的。(附上)Win10开启蓝牙虚拟串口的方法。
3. 在注册表中查看
【运行】--》【regedit】--》【HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM】,可以在右侧看到COM的信息
也可以看到蓝牙虚拟串口的信息,占用了COM5, COM6端口。
4. 通过系统自带的WMI方式查询
【运行】--》【wbemtest】
用程序的方式获取串口的信息
参考链接:https://www.cnblogs.com/HPAHPA/p/7928719.html
https://blog.csdn.net/md521/article/details/8191871
方法一:知道串口的GUID,通过API的方式获取串口的信息
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 方法一: 通过API的方式获取串口信息 void EnumerCOMPortByGUID() { HDEVINFO hDevInfo; SP_DEVINFO_DATA DeviceInfoData; DWORD i = 0; hDevInfo = SetupDiGetClassDevs((LPGUID)&GUID_DEVCLASS_PORTS, 0, 0, DIGCF_PRESENT); /* GUID_DEVCLASS_FDC软盘控制器 GUID_DEVCLASS_DISPLAY显示卡 GUID_DEVCLASS_CDROM光驱 GUID_DEVCLASS_KEYBOARD键盘 GUID_DEVCLASS_COMPUTER计算机 GUID_DEVCLASS_SYSTEM系统 GUID_DEVCLASS_DISKDRIVE磁盘驱动器 GUID_DEVCLASS_MEDIA声音、视频和游戏控制器 GUID_DEVCLASS_MODEMMODEM GUID_DEVCLASS_MOUSE鼠标和其他指针设备 GUID_DEVCLASS_NET网络设备器 GUID_DEVCLASS_USB通用串行总线控制器 GUID_DEVCLASS_FLOPPYDISK软盘驱动器 GUID_DEVCLASS_UNKNOWN未知设备 GUID_DEVCLASS_SCSIADAPTERSCSI 和 RAID 控制器 GUID_DEVCLASS_HDCIDE ATA/ATAPI 控制器 GUID_DEVCLASS_PORTS端口(COM 和 LPT) GUID_DEVCLASS_MONITOR监视器 */ if (hDevInfo == INVALID_HANDLE_VALUE) { DWORD dwError = GetLastError(); // Insert error handling here. return; } // Enumerate through all devices in Set. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++) { DWORD DataT = 0; char buffer[256] = { 0 }; char buffer1[512] = { 0 }; DWORD buffersize = sizeof(buffer); DWORD buffersize1 = sizeof(buffer1); while (!SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_FRIENDLYNAME, &DataT, (PBYTE)buffer, buffersize, &buffersize)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // Change the buffer size. //if (buffer) LocalFree(buffer); printf("111"); } else { // Insert error handling here. //cout << "Friend Name is " << buffer << endl; printf("222"); break; } } cout << "Friend Name is " << buffer << endl; while (!SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_HARDWAREID, &DataT, (PBYTE)buffer1, buffersize1, &buffersize1)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // Change the buffer size. //if (buffer) LocalFree(buffer); printf("333"); } else { // Insert error handling here. //cout << "Friend Name is " << buffer << endl; printf("444"); break; } } cout << "HWID is " << buffer1 << endl; //if (buffer) //{ // LocalFree(buffer); //} } if (GetLastError() != NO_ERROR && GetLastError() != ERROR_NO_MORE_ITEMS) { return; } // Cleanup SetupDiDestroyDeviceInfoList(hDevInfo); }
方法二:通过注册表的方式获取串口的信息
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 方法二:通过注册表的方式获取串口消息 void EnumerCOMPortByGenKey() { CRegKey RegKey; int nCount = 0; if (RegKey.Open(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM") == ERROR_SUCCESS) { while (true) { char ValueName[_MAX_PATH]; unsigned char ValueData[_MAX_PATH]; DWORD nValueSize = _MAX_PATH; DWORD nDataSize = _MAX_PATH; DWORD nType; if (::RegEnumValue(HKEY(RegKey), nCount, ValueName, &nValueSize, NULL, &nType, ValueData, &nDataSize) == ERROR_NO_MORE_ITEMS) { break; } printf("%s\n", ValueName); printf("%s\n", ValueData); nCount++; } } printf("%d\n", nCount); }
方法三:通过Createfile方法轮询读取串口
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 方法三:使用CreateFile函数轮询读取串口 void GetSerialPortState(char* sp) { int nCom = 0; HANDLE hCom; int count = 0; do { nCom++; char strCom[8]; sprintf_s(strCom, "%s%d", sp, nCom); printf("%s\n", strCom); hCom = CreateFile(strCom, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0);//轮询打开串口 if (INVALID_HANDLE_VALUE == hCom) { DWORD err = ::GetLastError(); } else { count++; printf("%s has opened\n", strCom); } CloseHandle(hCom);//关闭串口 } while (nCom < 256); printf("count = %d\n", count); } int main(int argc, char* argv[]) { if (strcmp(argv[1], "COM") == 0) GetSerialPortState(argv[1]); else if(strcmp(argv[1], "LPT") == 0) GetSerialPortState(argv[1]); }
涉及到的头文件有
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <Windows.h> #include "setupapi.h" #include "devguid.h" #include <atlbase.h> using namespace std; #pragma comment(lib, "setupapi.lib")
方法四:通过WMI的方式
这个方法比较通用,就不详细说了,随便找一篇WMI的文章就可以了。