VS2013环境下获取设备串口号及友好名(friendly name)


最近需要写一个上位机,用到串口,由于串口设备比较多,为了快速选择指定的设备,必须读取可用的串口列表以及友好名,尝试了半天才完成,虽然网上也有类似代码,但说明的都不是很完整,我用的开发环境是VS2013+WIN10,分享给大家。

实现代码

1、首先复制文件

  • 将"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib\Setupapi.lib"复制到工程目录下面
  • 将"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include\Setupapi.h"复制到工程目录下面
  • 需要注意的是,不同电脑位置可能不一样

2、***Dlg.cpp文件里添加头文件

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

3、添加依赖文件

  • 有两种方法,选其一:
  • a):在刚刚添加的头文件下添加,如下:
#include <setupapi.h>
#include "devguid.h"
#pragma comment(lib, "Setupapi.lib")
  • b):打开:工程->属性->配置属性->链接器->输入,在附加依赖项里面添加:Setupapi.lib
    在这里插入图片描述

4、在OnInitDialog()添加代码:

	// TODO:  在此添加额外的初始化代码
	HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS, NULL, NULL, 0);	//获取一个指定类别或全部类别的所有已安装设备的信息
	HANDLE hCom;
	if (hDevInfo)
	{
		int sum = 0;
		SP_DEVINFO_DATA SpDevInfo = { sizeof(SP_DEVINFO_DATA) };
		for (DWORD i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &SpDevInfo); i++)	//枚举指定设备信息集合的成员,并将数据放在PSP_DEVINFO_DATA中
		{
			TCHAR szName[512] = { 0 };
			if (SetupDiGetDeviceRegistryProperty(hDevInfo, &SpDevInfo, SPDRP_FRIENDLYNAME, NULL, (PBYTE)szName, sizeof(szName), NULL))	//获得单个装置的详细资料
			{
				_tprintf(TEXT("%s\n"), szName);
				CString com, str, strComOpen;
				str.Format(TEXT("%s"), szName);	//获取串口的友好名称,如:XXXX(COM2)
				//AfxMessageBox(str);			//这里会输出所有的设备名称,包含可用和不可用的

				//从这里开始,验证这些设备,哪些是可用的
				int posBeg = str.Find('(');
				int posEnd = str.Find(')');
				com = str.Mid(posBeg + 1, posEnd - posBeg - 1);//通过左右括号定位串口号在字符串里的位置来获取串口的名称,如:COM2
				strComOpen = TEXT("\\\\.\\") + com;		//需要打开的串口
				hCom = CreateFile(strComOpen, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);//如果返回不为空则此串口可用
				if (INVALID_HANDLE_VALUE != hCom)
				{
					AfxMessageBox(str);	//这里只输出可用的设备名称
					sum++;
				}
				else DWORD error = ::GetLastError();//取得错误信息				
				CloseHandle(hCom);
			}
		}
		SetupDiDestroyDeviceInfoList(hDevInfo);	//销毁设备信息集合,并且释放所有关联的内存
	}
  • 这部分代码可以在按钮或下拉框响应函数里面使用,效果是一样的。
  • 不过需要注意的是,这段代码会唤醒所有的串口硬件,比如我使用的CP2102,一旦运行这段代码就会亮灯,因为这里用到了CreateFile来判断串口是否能正常打开。解决办法是从注册表里读取可用的串口列表后再对应起来处理,这样就可以不用唤醒串口硬件。具体实现后面再更新。

相关函数

1、SetupDiGetClassDevs:枚举设备信息

HDEVINFO SetupDiGetClassDevs(
IN PGUID ClassGuid,
IN PCTSTR Enumerator,
IN HWND hwndParent,
IN DWORD Flags
);
  • SetupDiGetClassDevs 获取一个指定类别或全部类别的所有已安装设备的信息

  • 参数说明:

  • ClassGuid
    一个特定类别GUID(需要查询注册表)的指针,如果设置了DIGCF_ALLCLASSES标记,该参数备忽略,将返回所有类别的设备信息表

  • Enumerator
    过滤梅举的内容:如:PCI则只显示PCI设备,

  • hwndParent
    用于关联到集合成员中的用户接口的顶层窗口句柄

  • Flags
    建立设备信息表的控制选项,可以是下列值

  • DIGCF_PRESENT
    (只列出当前存在的设备信息)

  • DIGCF_ALLCLASSES
    (列出所有类别的一安装的设备表,如果设置了此值,则指定的类别将备忽略)

  • DIGCF_PROFILE
    (只返回当前硬件概况部分)

  • Return Value
    如成功,返回包含所有与指定参数匹配的已经安装设备信息句柄
    如失败则返回INVALID_HANDLE_VALUE

2、SetupDiEnumDeviceInfo:枚举指定设备信息集合的成员

SetupDiEnumDeviceInfo 枚举指定设备信息集合的成员,并将数据放在PSP_DEVINFO_DATA中

BOOLEAN
SetupDiEnumDeviceInfo(
IN HDEVINFO DeviceInfoSet,
IN DWORD MemberIndex,
OUT PSP_DEVINFO_DATA DeviceInfoData
);
  • 参数说明:

  • DeviceInfoSet
    提供一个设备信息集合的句柄

  • MemberIndex
    指定一个要取得的设备信息成员序号,从0开始

  • DeviceInfoData
    指向SP_DEVINFO_DATA结构的指针,关于指定成员的返回信息就放在该结构中

  • Return ValueThe
    成功返回True,否则返回False)

  • 如果要枚举全部设备信息成员,装载者首先应该将MemberIndex设为0调用SetupDiEnumDeviceInfo,然后递增MemberIndex(使用一个for循环),调用SetupDiEnumDeviceInfo,直至所有成员全部遍历(此时函数返回False,并且GetLastError返回ERROR_NO_MORE_ITEMS)

3、SetupDiGetDeviceRegistryProperty:获得单个装置的详细资料

WINSETUPAPI BOOL WINAPI
SetupDiGetDeviceRegistryProperty(
IN HDEVINFO DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData,
IN DWORD Property,
OUT PDWORD PropertyRegDataType, OPTIONAL
OUT PBYTE PropertyBuffer,
IN DWORD PropertyBufferSize,
OUT PDWORD RequiredSize OPTIONAL
);
  • 参数说明:

  • DeviceInfoSet
    设备信息句柄

  • DeviceInfoData
    SP_DEVINFO_DATA结构体,包含DeviceInfoSet 中的设备信息

  • Property
    取以下的值:

  • SPDRP_ADDRESS
    查询设备的地址

  • SPDRP_BUSNUMBER
    查询设备的bus号

  • SPDRP_BUSTYPEGUID
    查询设备的GUID号

  • SPDRP_CAPABILITIES
    The function retrieves a bitwise OR of the following CM_DEVCAP_Xxx flags in a DWORD. The device capabilities that are represented by these flags correspond to the device capabilities that are represented by the members of the DEVICE_CAPABILITIES structure. The CM_DEVCAP_Xxx constants are defined in cfgmgr32.h.
    CM_DEVCAP_Xxx flag Corresponding DEVICE_CAPABILITIES structure member
    CM_DEVCAP_LOCKSUPPORTED LockSupported
    CM_DEVCAP_EJECTSUPPORTED EjectSupported
    CM_DEVCAP_REMOVABLE Removable
    CM_DEVCAP_DOCKDEVICE DockDevice
    CM_DEVCAP_UNIQUEID UniqueID
    CM_DEVCAP_SILENTINSTALL SilentInstall
    CM_DEVCAP_RAWDEVICEOK RawDeviceOK
    CM_DEVCAP_SURPRISEREMOVALOK SurpriseRemovalOK
    CM_DEVCAP_HARDWAREDISABLED HardwareDisabled
    CM_DEVCAP_NONDYNAMIC NonDynamic

  • SPDRP_CHARACTERISTICS
    The function retrieves a bitwise OR of a device’s characteristics flags in a DWORD. For a description of these flags, which are defined in wdm.h and ntddk.h, see the IoCreateDevice function’s DeviceCharacteristics parameter.

  • SPDRP_CLASS
    The function retrieves a REG_SZ string that contains the device setup class of a device.

  • SPDRP_CLASSGUID
    The function retrieves a REG_SZ string that contains the GUID that represents the device setup class of a device.
    SPDRP_COMPATIBLEIDS
    The function retrieves a REG_MULTI_SZ string containing the list of compatible IDs for a device. For information about compatible IDs, see Device Identification Strings.

  • SPDRP_CONFIGFLAGS
    The function retrieves a bitwise OR of a device’s configuration flags in a DWORD value. The configuration flags are represented by the CONFIGFLAG_Xxx bitmasks that are defined in regstr.h.

  • SPDRP_DEVICE_POWER_DATA
    (Windows XP and later) The function retrieves a CM_POWER_DATA structure containing the device’s power management information.

  • SPDRP_DEVICEDESC
    The function retrieves a REG_SZ string containing the description of a device.

  • SPDRP_DEVTYPE
    The function retrieves a DWORD value representing the device’s type (see Specifying Device Types).

  • SPDRP_DRIVER
    The function retrieves a string identifying the device’s software key (sometimes called the driver key). See Driver Information in the Registry.

  • SPDRP_ENUMERATOR_NAME
    The function retrieves a REG_SZ string containing the name of the device’s enumerator.

  • SPDRP_EXCLUSIVE
    The function retrieves a DWORD value that indicates whether a user can obtain exclusive use of the device. The returned value is one if exclusive use is allowed, or zero otherwise. For more information, see IoCreateDevice.

  • SPDRP_FRIENDLYNAME
    The function retrieves a REG_SZ string that contains the friendly name of a device.

  • SPDRP_HARDWAREID
    The function retrieves a REG_MULTI_SZ string containing the list of hardware IDs for a device. For information about hardware IDs, see Device Identification Strings.

  • SPDRP_INSTALL_STATE
    (Windows XP and later) The function retrieves a DWORD value that indicates the installation state of a device. The installation state is represented by one of the CM_INSTALL_STATE_Xxx values that are defined in Cfgmgr32.h. The CM_INSTALL_STATE_Xxx values correspond to the DEVICE_INSTALL_STATE enumeration values.

  • SPDRP_LEGACYBUSTYPE
    The function retrieves the device’s legacy bus type as an INTERFACE_TYPE value (defined in wdm.h and ntddk.h).

  • SPDRP_LOCATION_INFORMATION
    The function retrieves a REG_SZ string that contains the hardware location of a device.

  • SPDRP_LOCATION_PATHS
    (Windows Server 2003 and later) The function retrieves a REG_MULTI_SZ string that represents the location of the device in the device tree.

  • SPDRP_LOWERFILTERS
    The function retrieves a REG_MULTI_SZ string that contains the names of a device’s lower-filter drivers.

  • SPDRP_MFG
    The function retrieves a REG_SZ string that contains the name of the device manufacturer.

  • SPDRP_PHYSICAL_DEVICE_OBJECT_NAME
    The function retrieves a REG_SZ string that contains the name that is associated with the device’s PDO. For more information, see IoCreateDevice.

  • SPDRP_REMOVAL_POLICY
    (Windows XP and later) The function retrieves the device’s current removal policy as a DWORD containing one of the CM_REMOVAL_POLICY_Xxx values defined in cfgmgr32.h.

  • SPDRP_REMOVAL_POLICY_HW_DEFAULT
    (Windows XP and later) The function retrieves the device’s hardware-specified default removal policy as a DWORD containing one of the CM_REMOVAL_POLICY_Xxx values defined in cfgmgr32.h.

  • SPDRP_REMOVAL_POLICY_OVERRIDE
    (Windows XP and later) The function retrieves the device’s override removal policy (if it exists) from the registry, as a DWORD containing one of the CM_REMOVAL_POLICY_Xxx values defined in cfgmgr32.h.

  • SPDRP_SECURITY
    The function retrieves a SECURITY_DESCRIPTOR structure for a device.

  • SPDRP_SECURITY_SDS
    The function retrieves a REG_SZ string that contains the device’s security descriptor. The format of security descriptor strings is described in Microsoft Windows SDK documentation.

  • SPDRP_SERVICE
    The function retrieves a REG_SZ string containing the service name for a device.

  • SPDRP_UI_NUMBER
    The function retrieves a DWORD value set to the value of the UINumber member of the device’s DEVICE_CAPABILITIES structure.

  • SPDRP_UI_NUMBER_DESC_FORMAT
    The function retrieves a format string (REG_SZ) used to display the UINumber value.

  • SPDRP_UPPERFILTERS
    The function retrieves a REG_MULTI_SZ string that contains the names of a device’s upper filter drivers.

  • PropertyRegDataType
    A pointer to a variable that receives the data type of the property that is being retrieved. This is one of the standard registry data types. This parameter is optional and can be NULL.

  • PropertyBuffer
    A pointer to a buffer that receives the property that is being retrieved. If this parameter is set to NULL, and PropertyBufferSize is also set to zero, the function returns the required size for the buffer in RequiredSize.

  • PropertyBufferSize
    The size, in bytes, of the PropertyBuffer buffer.

  • RequiredSize
    A pointer to a variable of type DWORD that receives the required size, in bytes, of the PropertyBuffer buffer that is required to hold the data for the requested property. This parameter is optional and can be NULL.

  • Return Value
    SetupDiGetDeviceRegistryProperty returns TRUE if the call was successful. Otherwise, it returns FALSE and the logged error can be retrieved with a call to GetLastError. SetupDiGetDeviceRegistryProperty returns the ERROR_INVALID_DATA error code if the requested property does not exist for a device or if the property data is not valid.

4、SetupDiDestroyDeviceInfoList: 销毁一个设备信息集合,并且释放所有关联的内存

BOOL SetupDiDestroyDeviceInfoList( HDEVINFO DeviceInfoSet );
  • 参数说明:
  • DeviceInfoSet
    [in]要释放的设备信息句柄
  • Return Values
    成功返回非零,否则返回零

5、CreateFile

  • 函数原型:
HANDLE CreateFile(
  LPCTSTR lpFileName, //指向文件名的指针
  DWORD dwDesiredAccess, //访问模式(写/读)
  DWORD dwShareMode, //共享模式
  LPSECURITY_ATTRIBUTES lpSecurityAttributes, //指向安全属性的指针
  DWORD dwCreationDisposition, //如何创建
  DWORD dwFlagsAndAttributes, //文件属性
  HANDLE hTemplateFile //用于复制文件句柄
);
  • 参数说明:

  • lpFileName String
    要打开的文件的名字

  • dwDesiredAccess Long
    如果为 GENERIC_READ 表示允许对设备进行读访问;如果为 GENERIC_WRITE 表示允许对设备进行写访问(可组合使用);如果为零,表示只允许获取与一个设备有关的信息

  • dwShareMode Long
    零表示不共享; FILE_SHARE_READ 和/或 FILE_SHARE_WRITE 表示允许对文件进行共享访问

  • lpSecurityAttributes SECURITY_ATTRIBUTES

  • 指向一个SECURITY_ATTRIBUTES结构的指针,定义了文件的安全特性(如果操作系统支持的话)

  • dwCreationDisposition Long
    下述常数之一:
    CREATE_NEW 创建文件;如文件存在则会出错
    CREATE_ALWAYS 创建文件,会改写前一个文件
    OPEN_EXISTING 文件必须已经存在。由设备提出要求
    OPEN_ALWAYS 如文件不存在则创建它
    TRUNCATE_EXISTING 讲现有文件缩短为零长度

  • dwFlagsAndAttributes Long
    一个或多个下述常数

  • FILE_ATTRIBUTE_ARCHIVE
    标记归档属性

  • FILE_ATTRIBUTE_COMPRESSED
    将文件标记为已压缩,或者标记为文件在目录中的默认压缩方式

  • FILE_ATTRIBUTE_NORMAL
    默认属性

  • FILE_ATTRIBUTE_HIDDEN
    隐藏文件或目录

  • FILE_ATTRIBUTE_READONLY
    文件为只读

  • FILE_ATTRIBUTE_SYSTEM
    文件为系统文件

  • FILE_FLAG_WRITE_THROUGH
    操作系统不得推迟对文件的写操作

  • FILE_FLAG_OVERLAPPED
    允许对文件进行重叠操作

  • FILE_FLAG_NO_BUFFERING
    禁止对文件进行缓冲处理。文件只能写入磁盘卷的扇区块

  • FILE_FLAG_RANDOM_ACCESS
    针对随机访问对文件缓冲进行优化

  • FILE_FLAG_SEQUENTIAL_SCAN
    针对连续访问对文件缓冲进行优化

  • FILE_FLAG_DELETE_ON_CLOSE
    关闭了上一次打开的句柄后,将文件删除。特别适合临时文件

  • 也可在Windows NT下组合使用下述常数标记:
    SECURITY_ANONYMOUS, SECURITY_IDENTIFICATION, SECURITY_IMPERSONATION, SECURITY_DELEGATION, SECURITY_CONTEXT_TRACKING, SECURITY_EFFECTIVE_ONLY

  • hTemplateFile Long
    如果不为零,则指定一个文件句柄。新文件将从这个文件中复制扩展属性

  • 返回值
    如执行成功,则返回文件句柄。
    INVALID_HANDLE_VALUE表示出错,会设置GetLastError。即使函数成功,但若文件存在,且指定了CREATE_ALWAYS 或 OPEN_ALWAYS,GetLastError也会设为ERROR_ALREADY_EXISTS

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值