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;
-
}
按这个方法可以获取设备管理器任意信息。
转载:https://blog.csdn.net/chenhao0568/article/details/128862067