用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. wp8 入门到精通 Animation 背景加字体颜色从下向上变化颜色效果

    <phone:PhoneApplicationPage.Resources> <Style x:Key="ButtonStyle1" TargetType=&qu ...

  2. ios内购

    1.添加框架,storeKit.framework 需要真机调试 /* 内购五步: 1.请求可销售商品的列表 2.展示课销售的商品 3.点击购买 4.开具小票 5.创建交易对象并添加到交易队列 6.创 ...

  3. 使用postMesssage()实现跨域iframe页面间的信息传递----转载

    由于web同源策略的限制,当页面使用跨域iframe链接时,主页面与子页面是无法交互的,这对页面间的信息传递造成了不小的麻烦,经过一系列的尝试,最后我发现有以下方法可以实现: 1. 子页面url传参 ...

  4. Java学习笔记(二)——变量与常量

    一.java中的关键字 Java 语言中有一些具有特殊用途的词被称为关键字.关键字对 Java 的编译器有着特殊的意义,在程序中应用时一定要慎重哦!! 二.认识Java标识符 1.定义 标识符就是用于 ...

  5. Spring官网改版后下载

    Spring官网改版后找了好久都没有找到直接下载Jar包的链接,下面汇总些网上提供的方法,亲测可用. 1.直接输入地址,改相应版本即可:http://repo.springsource.org/lib ...

  6. python 的特殊方法 __str__和__repr__

    __str__和__repr__ 如果要把一个类的实例变成 str,就需要实现特殊方法__str__(): class Person(object): def __init__(self, name, ...

  7. css学习(2)-- 常见的CSS属性和值

    1.CSS中修饰字体的属性 属    性 描    述 属  性  值 font-family 字体族科 任意字体族科名称都可以使用例如Times.serif等,而且多个族科的赋值是可以使用的,中间用 ...

  8. 2016.8.25 JavaScript入门之二

    1.字符串中,引用字符串:要用/"转换: 例如:var myStr="I am a \"double quoted\" string inside \" ...

  9. SU suvelan命令学习

  10. 快销品 车销批发管理手持终端PDA系统 打印开单 入库 库存 盘点多功能一体

    手持POS终端PDA移动开单 PDA通过扫描商品条码移动开单,实现便携式办公,伴随式销售,浩瀚技术研发团队开发的一款最新产品,PDA能通过WIFI无线局域网.GPRS互联网直接与主机连接,让公司业务人 ...