C#枚举所有串口COM

在实际项目中,如需都COM进行操作,往往需要枚举当前电脑中可用的所有串口COM。

我们第一想到的就是SerialPort.GetPortNames()方法。但这种方法有个缺陷那就是不能罗列那些通过USB连接虚拟出来的COM口。

public abstract class PortInfoBase
    {
        public string PortName { get; set; }

        public string Description { get; set; }

        public string DeviceId { get; set; }
    }

 

    public class ComPortInfo : PortInfoBase
    {
        public string Manufacturer { get; set; }

        public override string ToString()
        {
            return string.Format("PortName='{0}', Description='{1}', DeviceId='{2}', Manufacturer='{3}'",
                                 PortName, Description, DeviceId, Manufacturer);
        }
    }

 

    internal class ComPortInfoBuilder
    {
        private readonly ManagementBaseObject _mbo;
        private readonly ComPortInfo _comPortInfo = new ComPortInfo();

        public ComPortInfoBuilder(ManagementBaseObject mbo)
        {
            mbo.AssertNotNull("mbo");
            _mbo = mbo;
        }

        public ComPortInfo Build()
        {
            BuildPortName();
            BuildDescription();
            BuildDeviceId();
            BuildManufacturer();

            return _comPortInfo;
        }

        private void BuildPortName()
        {
            const string pattern = @"COM\d+";
            _comPortInfo.PortName = Regex.Match((string)_mbo["Caption"], pattern, RegexOptions.RightToLeft).Value;
        }

        private void BuildDescription()
        {
            _comPortInfo.Description = (string)_mbo["Description"];
        }

        private void BuildDeviceId()
        {
            _comPortInfo.DeviceId = (string)_mbo["DeviceID"];
        }

        private void BuildManufacturer()
        {
            _comPortInfo.Manufacturer = (string)_mbo["Manufacturer"];
        }
    }

 

    public interface IComPortEnumerator
    {
        ComPortInfo[] Enumerate();
    }

    public class ComPortEnumerator : IComPortEnumerator
    {
        private readonly ILog _logger = LogManager.GetLogger(typeof(ComPortEnumerator));

        public ComPortInfo[] Enumerate()
        {
            var comPortInfos = new List<ComPortInfo>();

            try
            {
                //Because Win32_SerialPort can't find the virtual COM ports, use Win32_PnPEntity here
                using (var searcher = new ManagementObjectSearcher(@"root\CIMV2", "SELECT * FROM Win32_PnPEntity WHERE Status='OK'"))
                {
                    foreach (var mbo in searcher.Get())
                    {
                        var result = Parse(mbo);

                        if (result.Item1)
                            comPortInfos.Add(result.Item2);
                    }
                }
            }
            catch (Exception exception)
            {
                _logger.Error(exception);
            }

            return comPortInfos.ToArray();
        }

        private Tuple<bool, ComPortInfo> Parse(ManagementBaseObject mbo)
        {
            try
            {
                if (BelongsToComPort(mbo))
                {
                    var comPortInfo = BuildComPortInfo(mbo);
                    return Tuple.Create(true, comPortInfo);
                }
            }
            catch (Exception exception)
            {
                _logger.Error(exception);
            }

            return Tuple.Create(false, (ComPortInfo)null);
        }

        private static bool BelongsToComPort(ManagementBaseObject mbo)
        {
            var value = mbo["Caption"] as string;

            if (value == null)
                return false;

            const string pattern = @"(\(COM\d+\))$";
            return Regex.IsMatch(value, pattern);
        }

        private static ComPortInfo BuildComPortInfo(ManagementBaseObject mbo)
        {
            var builder = new ComPortInfoBuilder(mbo);
            return builder.Build();
        }
    }

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值