自动识别查找特定的串口号 比如设备管理器中Modem属性里的串口 按这个方法可以获取设备管理器任意信息。C++

1.目标: 自动识别查找特定的串口号

2.注册表里搜串口号

设备管理器中所有的信息都在注册表中有,那么我直接在注册表里搜COM143。

搜到了这个,但这里有2个名称key相同的。后面193,192还是可能会变的,不方便精确识别。继续搜。

这里可以。 

 最后一个了。

共有5个地方存在:

计算机\HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM
计算机\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{4d36e96d-e325-11ce-bfc1-08002be10318}\0010
计算机\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\USB\VID_05C6&PID_9091&MI_01\6&c6a59d9&0&0001\Device Parameters
计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4d36e96d-e325-11ce-bfc1-08002be10318}\0010
计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_05C6&PID_9091&MI_01\6&c6a59d9&0&0001\Device Parameters 

 计算机\HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM列出了所有串口

3.具体筛选

1)看看ControlSet001、ControlSet002、CurrentControlSet的区别

1、ControlSet001:系统真实的配置信息
2、ControlSet002:最后一次成功启动的配置信息
3、CurrentControlSet:系统运行时的配置信息

一、系统启动时,从ControlSet001复制到CurrentControlSet中。
二、系统运行时,修改的都是CurrentControlSet中的信息。
三、系统重启时,从CurrentControlSet复制到ControlSet001中。
四、系统正常启动时,从ControlSet001和CurrentControlSet复制到ControlSet002。
五、开机选择“最近一次正确配置”时,从ControlSet002复制到CurrentControlSet中。

所有选CurrentControlSet分支。

2)Control与Enum分支的区别

Windows驱动有三种注册表键负责配置。它们是硬件(或实例), 类和 服务。

  • 硬件(或实例)键包含单个设备的信息。
  • 类键涉及所有相同类型设备的共同信息。
  • 服务键包含驱动程序信息。
注册表路径
硬件(hardware)键[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ Enum\总线\硬件ID]
类(class)键[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ Control\Class\GUID]
服务(service)键[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ Services\服务名]

因为GUID我可以获取,我这里选Control,即

计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4d36e96d-e325-11ce-bfc1-08002be10318}\0010

4.代码实现

C# python自动获取modem里的串口号 高通芯片C++ MFC_小黄人软件的博客-CSDN博客

C++ C#自动获得特定串口 获得串口列表_小黄人软件的博客-CSDN博客_c#获取串口列表

C++实现:

先拼成注册表路径,再读注册表。

 

// PrintDeviceInfo.cpp : 定义控制台应用程序的入口点。
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <Windows.h>
#include <setupapi.h>
#pragma comment(lib, "setupapi.lib")

// 注册表  找特定的串口号 
//计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4d36e96d-e325-11ce-bfc1-08002be10318}\0010
//AttachedTo=?
//return 特定的串口号 或 -1没找到特定串口  -2打开串口注册表 失败
int getF200SpecialComNumByRegister(char *guid)
{
	HKEY hkey;
	int result;
	int i = 0;
	//char path[100] = "SYSTEM\\CurrentControlSet\\Control\\Class\\{4d36e96d-e325-11ce-bfc1-08002be10318}\\0010";
	char path[100] = "SYSTEM\\CurrentControlSet\\Control\\Class\\";
	strcat_s(path, guid);
	result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, NULL, KEY_READ, &hkey);
	if (ERROR_SUCCESS == result)   //打开串口注册表   
	{
		do
		{
			TCHAR portName[0x100] = { 0 };//portName是注册表名称(不是设备管理器里的前缀),commName就是值 串口名字COMN
			TCHAR commName[0x100] = { 0 };
			DWORD dwSize = sizeof(portName) / sizeof(TCHAR);
			DWORD dwLong = dwSize;
			result = RegEnumValue(hkey, i, portName, &dwLong, NULL, NULL, (LPBYTE)commName, &dwSize);
			if (ERROR_NO_MORE_ITEMS == result) { break; }  			//   枚举串口				 	
			printf("%d %s %s\n", i, portName, commName); //显示名称及值

			if ((strcmp(portName, "AttachedTo") == 0)) //特定串口
			{
				RegCloseKey(hkey); //关闭注册表
				return atoi(commName + 3);//去掉COM只取号 正常返回
			}
			i++;
		} while (TRUE);
		RegCloseKey(hkey); //关闭注册表
		return -1;//没找到特定串口
	}
	return -2;//打开串口注册表 失败
}

//获取特定串口号 示例Qualcomm HS-USB Diagnostics 9091 (COM20)
int getSpecialComNum(const char *in)
{
	char out[100] = { 0 };
	sscanf_s(in, "Qualcomm HS-USB Diagnostics 9091 (COM%[0-9])", out,sizeof(out)); //不是%d哦
	return atoi(out);
}
//从设备信息中 获取特定串口号  @return <=0无效
int  getSpecialComNumFromDevInfo()
{
	printf("Locale is: %s\n", setlocale(LC_ALL, "chs"));//设置为中文
	HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
	if (hDevInfo == INVALID_HANDLE_VALUE)
	{
		printf("SetupDiGetClassDevs Err:%d", GetLastError());
		return -2;
	};
	SP_DEVINFO_DATA spDevInfoData = { 0 };
	spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
	for (DWORD i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &spDevInfoData); i++)	
	{

		//char  szBuf[MAX_PATH] = { 0 };
		//if (!SetupDiGetDeviceRegistryPropertyA(hDevInfo, &spDevInfoData, SPDRP_CLASS, NULL, (PBYTE)szBuf, MAX_PATH, 0))	{	continue;		};
		//if (strcmp(szBuf, "Ports") != 0  && strcmp(szBuf, "Modem") != 0) //只取端口
		//{		continue;		}

		char  szName[MAX_PATH] = { 0 };
		if (SetupDiGetDeviceRegistryPropertyA(hDevInfo, &spDevInfoData, SPDRP_FRIENDLYNAME, NULL, (PBYTE)szName, MAX_PATH - 1, 0))
		{
			if (strcmp(szName, "Qualcomm HS-USB Modem 9091 #3") != 0) { continue; } //只取这个
			printf("FriendlyName:%s\r\n", szName);	
		}
		else { continue; }

		memset(szName,0,sizeof(szName));
		if (SetupDiGetDeviceRegistryPropertyA(hDevInfo, &spDevInfoData, SPDRP_DRIVER, NULL, (PBYTE)szName, MAX_PATH - 1, 0))
		{
			printf("%d Device:%s\r\n", i, szName);
			return getF200SpecialComNumByRegister(szName);
			break;
		}
	}
	SetupDiDestroyDeviceInfoList(hDevInfo);
	printf("Can not find Modem COM");
	return -4;
}
 
int  main(int  argc, char* argv[])
{
	printf("自动识别串口号:%d\n",getSpecialComNumFromDevInfo());
	getchar();
	return  0;
}

按这个方法可以获取设备管理器任意信息。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小黄人软件

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值