串口编程,求获得串口逻辑名和设备名的的方法?

a99899s1 2016-12-13 09:04:11
RegEnumValue 枚举注册表只能获得COM1..2..这样的名.不能获得设备名,
SetupDiGetDeviceRegistryProperty 这个函数能获得设亩名.却不能得到类似COM1这样的名字.
CreateFile 打开串口用的是类似COM1这样的名字.
问下有什么方法可以一次性得到串口名和设备名这2个名字.?谢谢
...全文
4007 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
fanzy1984 2019-05-16
  • 打赏
  • 举报
回复
我现在和楼主一样,连接了一个继电器,电脑连接不止继电器一个COM口的设备,所以希望程序自动找到继电器,并且自动连接,然后按照其它地方的结果来控制继电器自动开自动关。
  • 打赏
  • 举报
回复
引用 10 楼 a99899s1 的回复:
[quote=引用 9 楼 zhao4zhong1 的回复:]
[quote=引用 8 楼 a99899s1 的回复:]
[quote=引用 7 楼 zhao4zhong1 的回复:]
devcon findall * | find /i "serial port"

你这不是命令行么..[/quote]
WinExec("cmd /c devcon findall * | find /i \"serial port\" >d:\\result.txt",SW_HIDE);
//然后读文件d:\result.txt的内容
//这才叫编程序?
[/quote]
你这不行的.,虽然没用过这全东西,百度devcon .exe,这个东西要下载.程序换电脑用总不能都要下载次吧.
再说命令行保存文件再读这样多绕圈子.,同时运行2个程序,文件不就成共享了,
你净整不靠谱的.真是记住你了.[/quote]
不用管这家伙,在好多地方碰到过这厮,回答的都是似是而非的东西,对写程序没什么鸡毛帮助,现在反正看到这货的回答我都直接跳过。
小木鱼%2345 2018-03-14
  • 打赏
  • 举报
回复
哎,我干嘛要挖坟呢,补充一下,函数就那几个,中心思路就是你去注册表里面直接去查看它们之间的关联。建议先查看COM口号反推,或者根据硬件ID号去查看
小木鱼%2345 2018-03-14
  • 打赏
  • 举报
回复
通过查看注册表的com口信息,然后查看设备名,判断是否是你想要的那个com口。具体函数的话:RegOpenKeyEx; RegEnumValue;RegQueryValueEx。
xiaobai_8001 2016-12-21
  • 打赏
  • 举报
回复
不赞同楼主的用法。对于用户而言,下拉列表里显示COM3,COM4应该比显示USB-SERIAL CH340 (COM5)更直观一些,何苦还要再从设备名转回COMX呢。如果你的电脑连接多个U转串,你的设备列表里拉出来一排排的USB-SERIAL CH340,这又让人怎么区分呢。
笨笨仔 2016-12-21
  • 打赏
  • 举报
回复
基本了解楼主的意图知,你是要使用多个设备连接,但是串口是系统硬件的部分,在应用层使用打开命令前并不能知道设备连接状态,你现在的作法貌似不能正确解决设备的实际连接。建议使用自动探测的方法:1、遍历串口;2、每打开一个串口即向连接的设备发送询问,设备不应答则放弃此口;3、设备应答再返回设备名称,将此口与设备绑定并写入下拉列表。
用户 昵称 2016-12-17
  • 打赏
  • 举报
回复
第三方工具可以嵌到你的Exe里面嘛。
天冰天降 2016-12-17
  • 打赏
  • 举报
回复
到最后,才算是看明白楼主的用意了,不过它只能得到USB-SERIAL CH340 (COM5)这样的字串,感觉截取这个字串不是太靠谱,对这个结论怎么就不靠谱了,能想到这么做,无非就是在下拉选项里面剔除非关键词设备名约定的com口,上面这个函数已经足够了,一般的人,也就是弄个com1到com16的下拉菜单供选择,至于什么是,用户自己看设备管理器去吧,usb的不行就是插拔一下看看确定,赞叹楼主这么为用户着想,贴心呀,精力充沛。 自己玩吗?还是老板或者客户的要求?
赵4老师 2016-12-15
  • 打赏
  • 举报
回复
高兴了楼主可以试试用API Monitor软件监视devcon内部是怎么获取系统所有设备名及其关联设备的。
a99899s1 2016-12-15
  • 打赏
  • 举报
回复
引用 11 楼 wxhxj0268 的回复:
我们使用“探测”程序查找设备插在哪个口上,再直接连接。连接例程仅供参考


这个只是打开串口的例子啊. 我的思路是这样的: 1.先列出所有连接在电脑上的设备名,. //关键函数SetupDiGetDeviceRegistryProperty 2.选择设备名后,//通过控件,CComboBox 3.通过设备名找到对应的COM口, 4.打开串口./ 5.串口通信... 6........ 我就是卡在了第3步,找到了役备名,没有方法能通过设备名查找到正确的COM口, 因为SetupDiGetDeviceRegistryProperty只能找到设备名, 不能直接找到COM口.RegEnumValue 只能找到COM口.这2个函数参数不通用,相对独立.打开串口用的OpenFile,参数是COMx, 没办法.只好发贴求助下大神们了,
a99899s1 2016-12-15
  • 打赏
  • 举报
回复
引用 12 楼 zhao4zhong1 的回复:
有命令行工具不用,非得自己使用底层API的码农都属于脑子不开窍。我觉得。
你那个命令行工具要下载.安装,多台电脑不方便, 再说了,保存成文件,如果多开.,会选成数据混乱共享, 实现也不直接,,绕圈子.,会拖慢运行,, 还有,串口通信API也不算是底层,用来打开串口的OpenFile你觉得就是底层API? 看你这种编程思路,你写出来的程序差不多都是又大又慢吧.BUG有N多吧.
赵4老师 2016-12-15
  • 打赏
  • 举报
回复
有命令行工具不用,非得自己使用底层API的码农都属于脑子不开窍。我觉得。
笨笨仔 2016-12-15
  • 打赏
  • 举报
回复
我们使用“探测”程序查找设备插在哪个口上,再直接连接。连接例程仅供参考

// 建立连接
void CCommThread::NetConnect(void)
{
	// 1.打开串行通信口,保存串口句柄
	hCom=CreateFile(m_sPortParam.com,
				GENERIC_READ | GENERIC_WRITE,
				0,
				NULL,
				OPEN_EXISTING,
				FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,		// 使用重叠方式
				NULL);
	if(hCom==(HANDLE)INVALID_FILE_SIZE)
	{
		ErrorProc(ERROR_OPEN);	// 报告端口打开失败
		return;
	}
	if(hCom != INVALID_HANDLE_VALUE)
	{
		// 设置端口
		SetupComm(hCom,OUT_BUFF_SIZE,IN_BUFF_SIZE);
		DCB myDCB;
		GetCommState(hCom, &myDCB);
		myDCB.BaudRate=m_sPortParam.baud;		// 波特率
		myDCB.fBinary=TRUE;						// 通信方式=二进制
		myDCB.fParity=FALSE;					// 奇偶校验 TRUE=使用,FALSE=不使用
		myDCB.Parity=m_sPortParam.parity;		// 校验方式:0-无 1-奇 2-偶 3-标志 4-空格
		myDCB.ByteSize=m_sPortParam.bytesize;	// 数据位数
		myDCB.StopBits=m_sPortParam.stopbits;	// 停止位数:0-1位 1-1.5位 2-2位
		if(!SetCommState(hCom, &myDCB))
		{
			// 设置参数失败
			ErrorProc(ERROR_SET);
			return;
		}
	}
	else
	{
		// 设置失败
		ErrorProc(ERROR_SET);
		return;
	}

	// 为传送消息,保存本窗口线程ID
	dwWinThreadID=this->m_nThreadID;
	if(!fEvent)				// 事件线程未启动
	{
		// 2.启动事件线程
		DWORD dwParam;
		if(!SetCommMask(hCom,EV_RXCHAR | EV_TXEMPTY))			// 设置允许的事件类型
		{
			// 建立事件掩码失败
			ErrorProc(ERROR_MASK);
			return;
		}
		// 创建事件线程
		hThreadEvent=::CreateThread(NULL,
				0,
				(LPTHREAD_START_ROUTINE)ThreadProcEvent,			// 指向线程函数的指针
				&dwParam,											// 传递的参数(未使用)
				0,													// 创建后立即激活
				&dwThreadID);										// 新线程的ID(未使用),可用于消息传送
		if(hThreadEvent==INVALID_HANDLE_VALUE)
		{
			// 事件线程创建失败
			ErrorProc(ERROR_CREAT);
			return;
		}
		else
			fEvent=true;					// 创建事件线程成功
	}
	fEventRun=true;							// 允许事件函数执行循环体
	ReportUp(CONNECT_OK);					// 报告端口打开成功
}
a99899s1 2016-12-15
  • 打赏
  • 举报
回复
引用 18 楼 zgl7903 的回复:
试了一下 SetupDiGetDeviceRegistryProperty SPDRP_FRIENDLYNAME 好像是可以的

这个函数的所有宏我都试过了,不能直接得到COMx的 从0到0x24;
a99899s1 2016-12-15
  • 打赏
  • 举报
回复
引用 18 楼 zgl7903 的回复:
试了一下 SetupDiGetDeviceRegistryProperty SPDRP_FRIENDLYNAME 好像是可以的

我就是用的这个宏,SPDRP_FRIENDLYNAME, 它只能得到USB-SERIAL CH340 (COM5)这样的字串,感觉截取这个字串不是太靠谱, 所以想找个能通过设备名直接得到COMx这样名字的方法.
zgl7903 2016-12-15
  • 打赏
  • 举报
回复
试了一下 SetupDiGetDeviceRegistryProperty SPDRP_FRIENDLYNAME 好像是可以的

#include <devguid.h>
#include <setupapi.h>
#pragma comment(lib, "Setupapi.lib")

void main()
{
  HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS, NULL, NULL, 0);

  if(hDevInfo)
  {
    SP_DEVINFO_DATA SpDevInfo={sizeof(SP_DEVINFO_DATA)};
    for(DWORD iDevIndex=0; SetupDiEnumDeviceInfo(hDevInfo, iDevIndex, &SpDevInfo); iDevIndex++)
    {      
      TCHAR szName[512] = {0};
      if(SetupDiGetDeviceRegistryProperty(hDevInfo, &SpDevInfo, SPDRP_FRIENDLYNAME, 
        NULL, (PBYTE)szName, sizeof(szName), NULL))
      {
        _tprintf(_T("%s\n"), szName);
      }
    }

    SetupDiDestroyDeviceInfoList(hDevInfo);
  }

}
a99899s1 2016-12-15
  • 打赏
  • 举报
回复
引用 16 楼 xiaohuh421 的回复:
一般的串口设备名字者是类似这样: \\.\COM22 CreateFile 也正是需要这样的名字. 特别是当串口号大于之后, 一定要写成上面那样, 不然打开会失败.
我想显示出设备的名字.比如CH340 通过比较设备名,找到这个设备的COM口.比如,COM5...
xiaohuh421 2016-12-15
  • 打赏
  • 举报
回复
一般的串口设备名字者是类似这样: \\.\COM22 CreateFile 也正是需要这样的名字. 特别是当串口号大于之后, 一定要写成上面那样, 不然打开会失败.
zgl7903 2016-12-14
  • 打赏
  • 举报
回复
串口用 文件名 "COM1" "COM2" 等已经足够了, 不管是原生的,还是USB PCI转的, 都不影响使用
a99899s1 2016-12-14
  • 打赏
  • 举报
回复
引用 1 楼 wxhxj0268 的回复:
我的应用从没用到这二个函数,我控制设备而不是设备控制我。
..这是串口通信的函数 .没这几个函数你怎么用串口和外部设备通信?
加载更多回复(8)

2,641

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧