C++第五十篇 — 获取串口的描述信息

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

  1. 查看电脑,看是否有串口器件(串口是一个九针的D型接口)

C++第五十篇 -- 获取串口的描述信息

  1. 在设备管理器上查看

C++第五十篇 -- 获取串口的描述信息

乍一看,还以为是有两个串口,其实仔细看描述就知道,这是蓝牙虚拟串口,并不是真实的串口,这台电脑上是没有接真实的串口的。(附上)Win10开启蓝牙虚拟串口的方法

  1. 在注册表中查看

【运行】--》【regedit】--》【HKEY_LOCAL_MACHINEHARDWAREDEVICEMAPSERIALCOMM】,可以在右侧看到COM的信息

C++第五十篇 -- 获取串口的描述信息

也可以看到蓝牙虚拟串口的信息,占用了COM5, COM6端口。

  1. 通过系统自带的WMI方式查询

【运行】--》【wbemtest】

C++第五十篇 -- 获取串口的描述信息C++第五十篇 -- 获取串口的描述信息

C++第五十篇 -- 获取串口的描述信息C++第五十篇 -- 获取串口的描述信息

C++第五十篇 -- 获取串口的描述信息C++第五十篇 -- 获取串口的描述信息

C++第五十篇 -- 获取串口的描述信息

用程序的方式获取串口的信息

参考链接:https://www.cnblogs.com/HPAHPA/p/7928719.html

https://blog.csdn.net/md521/article/details/8191871

方法一:知道串口的GUID,通过API的方式获取串口的信息
C++第五十篇 -- 获取串口的描述信息C++第五十篇 -- 获取串口的描述信息

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

View Code

方法二:通过注册表的方式获取串口的信息
C++第五十篇 -- 获取串口的描述信息C++第五十篇 -- 获取串口的描述信息

// 方法二:通过注册表的方式获取串口消息
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("%sn", ValueName);

            printf("%sn", ValueData);

            nCount++;
        }
    }
    printf("%dn", nCount);

}

View Code

方法三:通过Createfile方法轮询读取串口
C++第五十篇 -- 获取串口的描述信息C++第五十篇 -- 获取串口的描述信息

// 方法三:使用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("%sn", 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 openedn", strCom);
        }
        CloseHandle(hCom);//关闭串口
    } while (nCom < 256);
    printf("count = %dn", 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]);
}

View Code

涉及到的头文件有
C++第五十篇 -- 获取串口的描述信息C++第五十篇 -- 获取串口的描述信息

#include <iostream>
#include <Windows.h>
#include "setupapi.h"
#include "devguid.h"

#include <atlbase.h>

using namespace std;

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

View Code

方法四:通过WMI的方式

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

原文链接: https://www.cnblogs.com/smart-zihan/p/13790328.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/203827

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 下午9:39
下一篇 2023年2月12日 下午9:39

相关推荐