C++第五十篇 -- 获取串口的描述信息
阅读原文时间:2023年07月08日阅读:2

如何知道自己的电脑上有无串口呢? -- 手动

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的方式获取串口的信息

// 方法一: 通过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);  

}

方法二:通过注册表的方式获取串口的信息

// 方法二:通过注册表的方式获取串口消息
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方法轮询读取串口

// 方法三:使用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]);
}

涉及到的头文件有

#include
#include
#include "setupapi.h"
#include "devguid.h"

#include

using namespace std;

#pragma comment(lib, "setupapi.lib")

方法四:通过WMI的方式

这个方法比较通用,就不详细说了,随便找一篇WMI的文章就可以了。

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章