借助网络配置,控制Modbus工具的日志显示,避免卡死界面
智能大石头 authored at 2021-12-11 22:09:19
8.68 KiB
XCoder
using ALib.Audio;
using ALib.Camera;
using ALib.ComPort;
using ALib.Hid;
using ALib.Net;
using NewLife;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ALib.UsbHub
{
    /// <summary>
    /// 本类描述 USB_HUB 物理插口上的 设备/子设备
    /// 作用:描述一个HUB的插口情况,多个插口一起描述的时候可以直接判断此HUB是否存在
    /// </summary>
    public class UsbHubPort
    {
        [Description("设备名")]
        public String Name { get; set; } = "USB";

        [Description("HUB编组")]
        public int HubGroup { get; set; } = 0;

        [Description("HUB物理端口号,插口号。通常从1开始,没有看到0的")]
        public int Port { get; set; } = 0;

        [Description("复合设备的子设备编号")]
        public int SubDev { get; set; } = 0;

        [Description("实际接入的HUB")]
        public int HubId = -1;

        /// <summary>构造</summary>
        /// <param name="grp">编组</param>
        /// <param name="port">插口号</param>
        /// <param name="type">类型</param>
        /// <param name="sub">子设备编号</param>
        public UsbHubPort(int grp, int port, DevType type, int sub = 0)
        {
            HubGroup = grp;
            Port = port;
            SubDev = sub;
            Type = type;
        }

        /// <summary>获取USB设备</summary>
        /// <returns></returns>
        public UsbDevice GetUsbDevice()
        {
            if(HubId < 0) return null;

            var all = UsbHelper.GetAllUsbInfo();
            if (!all.ContainsKey(HubId)) return null;

            var hubdevs = all[HubId];
            return hubdevs.FirstOrDefault(e => e.Port == Port);
        }

        #region 判定设备是否存在

        public enum DevType
        {
            Hid,
            Camera,
            Audio,
            Com,
            Network,
            Hub,
            // 判断 VID  PID
            Other
        };

        /// <summary>设备类型</summary>
        public DevType Type { get; set; } = DevType.Other;

        /// <summary>type=Other时判定</summary>
        public ushort VID { get; set; }
        /// <summary>type=Other时判定</summary>
        public ushort PID { get; set; }

        /// <summary>判断设备在这个位置是否存在</summary>
        /// <param name="devs">hub下所有设备集合</param>
        /// <returns></returns>
        public bool Exists(List<UsbDevice> devs)
        {
            return Exists(devs, Port, Type, SubDev, PID, VID);
        }

        /// <summary>判断设备在这个位置是否存在</summary>
        /// <param name="hubid">系统中hub的编号,默认直接用HubId判断</param>
        /// <returns></returns>
        public bool Exists(int hubid = -1)
        {
            if (hubid < 0) hubid = HubId;
            if (hubid < 0) return false;

            return Exists(hubid, Port, Type, SubDev, PID, VID);
        }

        /// <summary>判定设备是否存在</summary>
        /// <param name="hubdevs"></param>
        /// <param name="port"></param>
        /// <param name="type">类型</param>
        /// <param name="subIdx">复合设备的子设备编号,默认0</param>
        /// <param name="pid">type=Other时判定</param>
        /// <param name="vid">type=Other时判定</param>
        /// <returns></returns>
        public static bool Exists(List<UsbDevice> hubdevs, int port, DevType type, int subIdx = 0, ushort pid = 0, ushort vid = 0)
        {
            /*
            var devs = hubdevs;
            var dic = devs.ToDictionary(e => e.Port, e => e);
            // 端口没有插入设备
            if (!dic.ContainsKey(port)) return false;
            var usbdev = dic[port];
            */
            // 端口没有插入设备
            var usbdev = hubdevs.FirstOrDefault(e => e.Port == port);
            if (usbdev == null) return false;

            bool res = false;
            // 根据类型判断是否存在
            switch (type)
            {
                case DevType.Hid:
                    var hiddev = usbdev.GetHidDevice(subIdx);
                    if (hiddev != null) res = true;
                    break;
                case DevType.Camera:
                    var pnp = usbdev.GetCameraPnp();
                    if (!pnp.IsNullOrEmpty()) res = true;
                    break;
                case DevType.Audio:
                    var ad = usbdev.GetAudioDevice();
                    if (ad != null) res = true;
                    break;
                case DevType.Com:
                    var cname = usbdev.GetComName(subIdx);
                    if (cname.StartsWith("COM")) res = true;
                    break;
                case DevType.Network:
                    var netobj = usbdev.GetNetworkCard();
                    if (netobj != null) res = true;
                    break;
                case DevType.Hub:
                    if (usbdev.Name.Contains("集线器")) res = true;
                    break;
                case DevType.Other:
                    var _pid = BitConverter.ToUInt16(usbdev.PID.GetBytes(), 0);
                    var _vid = BitConverter.ToUInt16(usbdev.VID.GetBytes(), 0);
                    if ((_pid == pid) && (_vid == vid)) res = true;
                    break;
                default: break;
            }

            return res;
        }

        /// <summary>判定设备是否存在</summary>
        /// <param name="hubid"></param>
        /// <param name="port"></param>
        /// <param name="type">类型</param>
        /// <param name="subIdx">复合设备的子设备编号,默认0</param>
        /// <param name="pid">type=Other时判定</param>
        /// <param name="vid">type=Other时判定</param>
        /// <returns></returns>
        public static bool Exists(int hubid, int port, DevType type, int subIdx = 0, ushort pid = 0, ushort vid = 0)
        {
            if (hubid < 0) return false;

            var all = UsbHelper.GetAllUsbInfo();
            if (!all.ContainsKey(hubid)) return false;

            return Exists(all[hubid], port, type, subIdx, pid, vid);
        }

        #endregion

        #region 查找HUB

        /// <summary>获取检查有效的hub</summary>
        /// <param name="pdevs"></param>
        /// <param name="ignore">pdevs中不参与匹配的。 注意:成员和pdevs内的是同一个对象</param>
        /// <returns>key是group,value是满足条件的hubids</returns>
        public static Dictionary<int,List<int>> FindHubs(UsbHubPort[] pdevs, UsbHubPort[] ignore = null)
        {
            // 拿到所有去重后的 group id
            var gps = pdevs.Select(e => e.HubGroup).Distinct().ToList();

            // 满足hub筛查条件的hub集合
            var dic = new Dictionary<int, List<int>>();
            foreach (var hub in UsbHelper.GetAllUsbInfo())
            {
                // 分别判断是否满足分组
                foreach (var gp in gps)
                {
                    bool grpOk = true;
                    foreach (var udev in pdevs)
                    {
                        if ((ignore!=null) && ignore.Contains(udev)) continue;

                        // 是相关分组
                        if (udev.HubGroup != gp) continue;
                        if (!udev.Exists(hub.Value))
                        {
                            grpOk = false;
                            break;
                        }
                    }

                    if (grpOk)
                    {
                        if (!dic.ContainsKey(gp))
                        {
                            var list = new List<int>();
                            list.Add(hub.Key);
                            dic.Add(gp, list);
                        }
                        else
                        {
                            dic[gp].Add(hub.Key);
                        }
                    }
                }
            }

            return dic;
        }

        /// <summary>获取检查有效的hub,每个Group只且只有一个匹配项</summary>
        /// <param name="pdevs"></param>
        /// <param name="ignore"></param>
        /// <returns>key是group,value是满足条件的hubid</returns>
        public static Dictionary<int, int> FindHubs_JustOne(UsbHubPort[] pdevs, UsbHubPort[] ignore = null)
        {
            var dic = FindHubs(pdevs, ignore);

            if (dic == null || dic.Count < 1) return null;
            foreach (var item in dic)
            {
                if (item.Value.Count != 1) return null;
            }

            return dic.ToDictionary(e => e.Key, e => e.Value[0]);
        }

        #endregion
    }
}