用C#做串口通讯很方便,因为dotfx2.0已经集成了Serial Port控件,此控件使用上比MSComm控件更简单,当然它也有一个小bug

(RecievedBytesThreshold设置有时候不好使),但是这个问题很好解决,而做串口通讯最最基本的问题就是如何获得目标机器的要与

之通讯的特定设备的特定com号,有许多软件在处理这个问题的时候都是要求用户手动去选择对应的串口号,这多少有些不人性化,这篇

文章就是介绍如何自动获得目标机器对应特定串口设备的串口号,从而达到软件与目标设备的自动通讯。
方法基本上是我前一篇文章的一个应用,代码如下(注意自己添加引用的命名空间)
// <summary>
/// 通过vid,pid获得串口设备号
/// </summary>
/// <param name="vid">vid</param>
/// <param name="pid">pid</param>
/// <returns>串口号</returns>
public static string GetPortNameFormVidPid(string vid, string pid)
{
Guid myGUID = Guid.Empty;
string enumerator = "USB";
try
{
IntPtr hDevInfo = HardWareLib.SetupDiGetClassDevs(ref myGUID, enumerator, IntPtr.Zero, HardWareLib.DIGCF_ALLCLASSES | HardWareLib.DIGCF_PRESENT);
if (hDevInfo.ToInt32() == HardWareLib.INVALID_HANDLE_VALUE)
{
throw new Exception("没有该类设备");
}
HardWareLib.SP_DEVINFO_DATA deviceInfoData;//想避免在api中使用ref,就把structure映射成类
deviceInfoData = new HardWareLib.SP_DEVINFO_DATA();
deviceInfoData.cbSize = 28;//如果要使用SP_DEVINFO_DATA,一定要给该项赋值28=16+4+4+4
deviceInfoData.devInst = 0;
deviceInfoData.classGuid = System.Guid.Empty;
deviceInfoData.reserved = 0;
UInt32 i;
StringBuilder property = new StringBuilder(HardWareLib.MAX_DEV_LEN);
for (i = 0; HardWareLib.SetupDiEnumDeviceInfo(hDevInfo, i, deviceInfoData); i++)
{
// Console.Write(deviceInfoData.classGuid.ToString());
// HardWareOperation.SetupDiGetDeviceInstanceId(hDevInfo, deviceInfoData, porperty, (uint) porperty.Capacity, 0);
HardWareLib.SetupDiGetDeviceRegistryProperty(hDevInfo, deviceInfoData,
(uint)HardWareLib.SPDRP_.SPDRP_CLASS,
0, property, (uint)property.Capacity, IntPtr.Zero);
if (property.ToString().ToLower() != "ports") continue;//首先看看是不是串口设备(有些USB设备不是串口设备)
HardWareLib.SetupDiGetDeviceRegistryProperty(hDevInfo, deviceInfoData,
(uint)HardWareLib.SPDRP_.SPDRP_HARDWAREID,
0, property, (uint)property.Capacity, IntPtr.Zero);
if (!(property.ToString().ToLower().Contains(vid.ToLower())
&& property.ToString().ToLower().Contains(pid.ToLower()))) continue;//找到对应于vid&pid的设备
HardWareLib.SetupDiGetDeviceRegistryProperty(hDevInfo, deviceInfoData,
(uint)HardWareLib.SPDRP_.SPDRP_FRIENDLYNAME,
0, property, (uint)property.Capacity, IntPtr.Zero);
break; }
HardWareLib.SetupDiDestroyDeviceInfoList(hDevInfo);//记得用完释放相关内存
string friendlyName = property.ToString();
string pattern=@"(COM[1-9][0-9]?)$";//friendlyName一般形式为以(COMn)结尾,n为1-99
if (Regex.IsMatch(friendlyName, pattern, RegexOptions.IgnoreCase))
{
string portName=Regex.Match(friendlyName, pattern, RegexOptions.IgnoreCase).Value;
return portName.Trim(new char[] { '(', ')' });
}
return null;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return null;
}
}
HardWareLib.cs(也就是前一篇文章的一个类)
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices; namespace ForGeneralUse
{
public class HardWareLib
{
/// <summary>
/// 设备的各项属性,注意有些属性是不通用的,例如SPDRP_FRIENDLYNAME只适用于端口设备
/// </summary>
public enum SPDRP_
{
SPDRP_DEVICEDESC = (0x00000000), // DeviceDesc (R/W)
SPDRP_HARDWAREID = (0x00000001), // HardwareID (R/W)
SPDRP_SERVICE = (0x00000004), // Service (R/W)
SPDRP_CLASS = (0x00000007), // Class (R--tied to ClassGUID)
SPDRP_CLASSGUID = (0x00000008), // ClassGUID (R/W)
SPDRP_DRIVER = (0x00000009), // Driver (R/W)
SPDRP_CONFIGFLAGS = (0x0000000A), // ConfigFlags (R/W)
SPDRP_MFG = (0x0000000B), // Mfg (R/W)
SPDRP_FRIENDLYNAME = (0x0000000C), // FriendlyName (R/W)
SPDRP_PHYSICAL_DEVICE_OBJECT_NAME = (0x0000000E), // PhysicalDeviceObjectName (R)
SPDRP_CAPABILITIES = (0x0000000F), // Capabilities (R)
SPDRP_REMOVAL_POLICY_HW_DEFAULT = (0x00000020), // Hardware Removal Policy (R)
SPDRP_INSTALL_STATE = (0x00000022), // Device Install State (R)
}
public const int DIGCF_ALLCLASSES = (0x00000004);
public const int DIGCF_DEVICEINTERFACE = 0x00000010;
public const int DIGCF_PRESENT = (0x00000002);
public const int INVALID_HANDLE_VALUE = -1;
public const int MAX_DEV_LEN = 1000; /// <summary>
/// 获取一个指定类别或全部类别的所有已安装设备的信息
/// </summary>
/// <param name="gClass">该类别对应的guid</param>
/// <param name="iEnumerator">类别名称(在HKLMSYSTEMCurrentControlSetEnum内获取)</param>
/// <param name="hParent">应用程序定义的窗口句柄</param>
/// <param name="nFlags">获取的模式</param>
/// <returns>设备信息集合的句柄</returns>
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr SetupDiGetClassDevs(ref Guid gClass, String enumerator, IntPtr hParent, UInt32 nFlags); /// <summary>
/// 获得该设备的设备范例ID
/// </summary>
/// <param name="DeviceInfoSet">设备信息集合</param>
/// <param name="DeviceInfoData">表示该设备</param>
/// <param name="DeviceInstanceId">设备范例ID(输出)</param>
/// <param name="DeviceInstanceIdSize">该ID所占大小(字节)</param>
/// <param name="RequiredSize">需要多少字节</param>
/// <returns>是否成功</returns>
DllImport("setupapi.dll", SetLastError = true)]
public static extern bool SetupDiGetDeviceInstanceId(IntPtr DeviceInfoSet,
HardWareLib.SP_DEVINFO_DATA DeviceInfoData,
StringBuilder DeviceInstanceId,
UInt32 DeviceInstanceIdSize,
UInt32 RequiredSize); /// <summary>
/// 枚举指定设备信息集合的成员,并将数据放在SP_DEVINFO_DATA中
/// </summary>
/// <param name="lpInfoSet">设备信息集合句柄</param>
/// <param name="dwIndex">元素索引</param>
/// <param name="devInfoData">表示一个设备(作为输出)</param>
/// <returns>是否成功</returns>
[DllImport("setupapi.dll", SetLastError = true)]
public static extern bool SetupDiEnumDeviceInfo(IntPtr lpInfoSet, UInt32 dwIndex, SP_DEVINFO_DATA devInfoData); // <summary>
/// 获取指定设备的属性
/// </summary>
/// <param name="lpInfoSet">设备信息集合</param>
/// <param name="DeviceInfoData">表示该设备</param>
/// <param name="Property">表示要获取哪项属性</param>
/// <param name="PropertyRegDataType">注册类型</param>
/// <param name="PropertyBuffer">属性(输出)</param>
/// <param name="PropertyBufferSize">存储属性的字节大小</param>
/// <param name="RequiredSize">需要的字节大小</param>
/// <returns>是否成功</returns>
[DllImport("setupapi.dll", SetLastError = true)]
public static extern bool SetupDiGetDeviceRegistryProperty(IntPtr lpInfoSet,
SP_DEVINFO_DATA DeviceInfoData,
UInt32 Property,
UInt32 PropertyRegDataType,
StringBuilder PropertyBuffer,
UInt32 PropertyBufferSize,
IntPtr RequiredSize); /// <summary>
/// 销毁一个设备信息集合,并且释放所有关联的内存
/// </summary>
/// <param name="lpInfoSet">设备信息集合</param>
/// <returns></returns>
[DllImport("setupapi.dll", SetLastError = true)]
public static extern bool SetupDiDestroyDeviceInfoList(IntPtr lpInfoSet);
/// <summary>
/// 设备信息数据
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public class SP_DEVINFO_DATA
{
public int cbSize;//本结构的大小(字节表示)
public Guid classGuid;//本结构所表示的设备的GUID
public int devInst;//设备句柄
public ulong reserved;//没用
};
}
}
如果大家想了解正则表达式的简单使用,推荐大家访问如下网址
http://www.szwblm.com/Netvb/ShowArticle.asp?ArticleID=19633,
http://www.szwblm.com/Netvb/ShowArticle.asp?ArticleID=14918 本文来自转载,小编尚未尝试,静待。。。

通过串口设备vid,pid自动获得该设备所对应的串口号的更多相关文章

  1. adb设备,根据serial获取vid pid

    使用adb devices命令,可以轻松获取到所有连接到PC的adb设备的serial值. 但是adb命令无法获取adb usb设备的vendor id和product id. 本程序根据adb协议, ...

  2. USB VID PID 查询

    USB VID PID 查询:http://www.linux-usb.org/usb.ids 说明: USB设备中有VID何PID,分别表示此USB设备是哪个厂商的哪种设备. 一个USB的VID对应 ...

  3. Linux自动共享USB设备:udev+Samba

    一.概述 公司最近要我实现USB设备插入Ubuntu后,自动共享到网络上,能像Windows共享一样(如\\192.168.1.10)访问里面的内容,不需要写入权限.当时听完这需求,我这新人表示惊呆了 ...

  4. 自动创建字符设备,不需mknod

    自动创建设备文件 1.自动创建设备文件的流程 字符设备驱动模块 -->创建一个设备驱动class--->创建属于class的device--->调用mdev工具(自动完成)--> ...

  5. C# 获取 串口 设备名称 与 串口号 ManagementObjectSearcher类

    1.效果图: 2.代码 class Program { static void Main(string[] args) { GetComList(); } private static void Ge ...

  6. 根据PID和VID得到USB转串口的串口号

    /******************************************************************************* * * FindAppUART.cpp ...

  7. Appium自动获取 Android 设备 id 和包名等信息(python)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/zhusongziye/article/d ...

  8. 根据设备id自动打开本设备的串口

    对于串口设备经常遇到重新拔插串口设备时候,程序又需要重新选择串口打开.对此很少麻烦的要死. 现在我们可以根据该设备的id去遍历串口设备,一旦符合就打开此串口即可. public void init() ...

  9. udisk2阻止自动Mount某些设备

    1.在/etc/udev/rules.d/目录下添加一个诸如99.udisk2.rules 2.其中的内容诸如: # This file contains udev rules for udisks ...

随机推荐

  1. 把VSO作为GitHub上JavaScript项目的免费CI服务器

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:微软变得更加开放后,走向开放的不仅有.NET运行时.IDE工具,还有ALM服务器核心组 ...

  2. Java 类装载器

    类装载器 基本概念: 顾名思义,类加载器(class loader)用来把Java 类动态的加载到 Java 虚拟机中.也就是说当程序需要某个类时,类加载器就把这个类的二进行加入到虚拟机中. 类加载器 ...

  3. mysql编译时报的一个警告warning: type-punning to incomplete type might break strict-aliasing rules,可能是bug

    cmake的时候报了一个警告: /softdb/mysql-5.5.37/storage/innobase/handler/ha_innodb.cc:11870: warning: type-punn ...

  4. mysql的启动

    1.直接用mysqld手工启动 [root@ora11g bin]# ./mysqld --defaults-file=../my.cnf :: [ERROR] Fatal error: Please ...

  5. 在Salesforce中实现对Object的增删改查操作

    1): Insert Statement    http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#CSHID=ap ...

  6. ubuntu12.04 安装eclipse

    1:去官网下载最新版的eclipse for linux; 2:cd  /usr/local 用命令 sudo mkdir eclipse 建立一个Eclipse的目录 3:将下载的文件copy到ec ...

  7. 智能车学习(五)—— dac学习

    一.代码共享: 1.dac.h #ifndef DAC_H_ #define DAC_H_ #include "common.h" // 2.2 DAC控制寄存器0 位定义 #de ...

  8. (转载)一个用于Gnome桌面的下拉式终端: Guake 0.7.0 发布

    转自:https://linux.cn/article-5507-1.html Linux的命令行是最好.最强大的东西,它使新手着迷,并为老手和极客的提供极其强大的功能.那些在服务器和生产环境下工作的 ...

  9. 网上下载的CHM帮助文件打不开的解决办法。

    我的机器 装的是 Windows server 2008 操作系统.他的安全性比较高. 我在网上下载了一个 CHM 帮助文档.结果打不开. 现象: 打开时 ,提示 安全警告, 提示:来自Interne ...

  10. Liferay 6.2 改造系列之二十四:修改liferay密码的加密方式

    为了便于后期与Cas集成过程中使用数据库用户的方便,将liferay密码的加密方式改为SHA. 在/portal-master/portal-impl/src/portal.properties配置文 ...