C#:USB设备枚举 --转自CSDN作者:Splash

(一)DeviceIoControl的PInvoke

/* ----------------------------------------------------------
文件名称:DeviceIoControl.cs

作者:秦建辉

MSN:[email protected]
QQ:36748897

博客:http://blog.csdn.net/jhqin

开发环境:
    Visual Studio V2010
    .NET Framework 4 Client Profile

版本历史:
    V1.0    2011年10月10日
            实现对DeviceIoControl接口的PInvoke

参考资料:
    http://www.pinvoke.net/
------------------------------------------------------------ */
using System;
using System.Runtime.InteropServices;

namespace Splash.IO.PORTS
{
    #region ENUM
    public enum USB_HUB_NODE : uint
    {
        UsbHub,
        UsbMIParent
    }

    public enum USB_CONNECTION_STATUS
    {
        NoDeviceConnected,
        DeviceConnected,
        DeviceFailedEnumeration,
        DeviceGeneralFailure,
        DeviceCausedOvercurrent,
        DeviceNotEnoughPower,
        DeviceNotEnoughBandwidth,
        DeviceHubNestedTooDeeply,
        DeviceInLegacyHub
    }

    public enum USB_DEVICE_SPEED : byte
    {
        UsbLowSpeed,    // 低速USB 1.1
        UsbFullSpeed,   // 全速USB 1.1
        UsbHighSpeed,   // 高速USB 2.0
        UsbSuperSpeed   // 极速USB 3.0
    }
    #endregion

    public partial class USB
    {
        internal const Int32 IOCTL_GET_HCD_DRIVERKEY_NAME = 0x220424;
        internal const Int32 IOCTL_USB_GET_ROOT_HUB_NAME = 0x220408;
        internal const Int32 IOCTL_USB_GET_NODE_CONNECTION_NAME = 0x220414;
        internal const Int32 IOCTL_USB_GET_NODE_INFORMATION = 0x220408;
        internal const Int32 IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX = 0x220448;
        internal const Int32 IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION = 0x220410;

        internal const Int32 MAXIMUM_USB_STRING_LENGTH = 255;
        internal const Int32 USB_STRING_DESCRIPTOR_TYPE = 3;

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        internal struct USB_HCD_DRIVERKEY_NAME
        {
            public Int32 ActualLength;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
            public String Name;
        }

        #region USB_NODE_INFORMATION
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        internal struct USB_HUB_DESCRIPTOR
        {
            public Byte bDescriptorLength;
            public Byte bDescriptorType;    // 描述符类型:0x29
            public Byte bNumberOfPorts;     // 支持的下游端口数目
            public Int16 wHubCharacteristics;   // 特征描述
            public Byte bPowerOnToPowerGood;    // 从端口加电到端口正常工作的时间间隔(以2ms为单位)
            public Byte bHubControlCurrent;     // 设备所需最大电流
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
            public Byte[] bRemoveAndPowerMask;  // 指示连接在集线器端口的设备是否可移走
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct USB_HUB_INFORMATION
        {
            public USB_HUB_DESCRIPTOR HubDescriptor;
            public Byte HubIsBusPowered;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct USB_MI_PARENT_INFORMATION
        {
            public Int32 NumberOfInterfaces;
        };

        [StructLayout(LayoutKind.Explicit)]
        internal struct UsbNodeUnion
        {
            [FieldOffset(0)]
            public USB_HUB_INFORMATION HubInformation;
            [FieldOffset(0)]
            public USB_MI_PARENT_INFORMATION MiParentInformation;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct USB_NODE_INFORMATION
        {
            public USB_HUB_NODE NodeType;
            public UsbNodeUnion u;
        }
        #endregion

        #region USB_NODE_CONNECTION_INFORMATION
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        internal struct USB_DEVICE_DESCRIPTOR
        {
            public Byte bLength;
            public Byte bDescriptorType;
            public UInt16 bcdUSB;
            public Byte bDeviceClass;
            public Byte bDeviceSubClass;
            public Byte bDeviceProtocol;
            public Byte bMaxPacketSize0;
            public UInt16 idVendor;
            public UInt16 idProduct;
            public UInt16 bcdDevice;
            public Byte iManufacturer;
            public Byte iProduct;
            public Byte iSerialNumber;
            public Byte bNumConfigurations;
        }       

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        internal struct USB_ENDPOINT_DESCRIPTOR
        {
            public Byte bLength;
            public Byte bDescriptorType;
            public Byte bEndpointAddress;
            public Byte bmAttributes;
            public UInt16 wMaxPacketSize;
            public Byte bInterval;
        }

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        internal struct USB_PIPE_INFO
        {
            public USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
            public UInt32 ScheduleOffset;
        }

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        internal struct USB_NODE_CONNECTION_INFORMATION_EX
        {
            public Int32 ConnectionIndex;
            public USB_DEVICE_DESCRIPTOR DeviceDescriptor;
            public Byte CurrentConfigurationValue;
            public Byte Speed;
            public Byte DeviceIsHub;
            public Int16 DeviceAddress;
            public Int32 NumberOfOpenPipes;
            public USB_CONNECTION_STATUS ConnectionStatus;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
            public USB_PIPE_INFO[] PipeList;
        }
        #endregion

        #region USB_DESCRIPTOR_REQUEST
        [StructLayout(LayoutKind.Sequential)]
        internal struct USB_SETUP_PACKET
        {
            public Byte bmRequest;
            public Byte bRequest;
            public UInt16 wValue;
            public UInt16 wIndex;
            public UInt16 wLength;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        internal struct USB_STRING_DESCRIPTOR
        {
            public Byte bLength;
            public Byte bDescriptorType;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXIMUM_USB_STRING_LENGTH)]
            public String bString;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct USB_DESCRIPTOR_REQUEST
        {
            public Int32 ConnectionIndex;
            public USB_SETUP_PACKET SetupPacket;
            public USB_STRING_DESCRIPTOR Data;
        }
        #endregion

        #region USB_NODE_CONNECTION_DRIVERKEY_NAME
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        internal struct USB_NODE_CONNECTION_DRIVERKEY_NAME
        {
            public Int32 ConnectionIndex;
            public Int32 ActualLength;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXIMUM_USB_STRING_LENGTH)]
            public String DriverKeyName;
        }
        #endregion

        #region DeviceIoControl
        [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
        internal static extern Boolean DeviceIoControl(
            IntPtr hFile,
            Int32 dwIoControlCode,
            IntPtr lpInBuffer,
            Int32 nInBufferSize,
            ref USB_HCD_DRIVERKEY_NAME lpOutBuffer,
            Int32 nOutBufferSize,
            out Int32 nBytesReturned,
            IntPtr lpOverlapped
            );

        [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
        internal static extern Boolean DeviceIoControl(
            IntPtr hFile,
            Int32 dwIoControlCode,
            ref USB_NODE_INFORMATION lpInBuffer,
            Int32 nInBufferSize,
            ref USB_NODE_INFORMATION lpOutBuffer,
            Int32 nOutBufferSize,
            out Int32 lpBytesReturned,
            IntPtr lpOverlapped
            );

        [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
        internal static extern Boolean DeviceIoControl(
            IntPtr hFile,
            Int32 dwIoControlCode,
            ref USB_NODE_CONNECTION_INFORMATION_EX lpInBuffer,
            Int32 nInBufferSize,
            ref USB_NODE_CONNECTION_INFORMATION_EX lpOutBuffer,
            Int32 nOutBufferSize,
            out Int32 lpBytesReturned,
            IntPtr lpOverlapped
            );

        [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
        internal static extern Boolean DeviceIoControl(
            IntPtr hFile,
            Int32 dwIoControlCode,
            ref USB_DESCRIPTOR_REQUEST lpInBuffer,
            Int32 nInBufferSize,
            ref USB_DESCRIPTOR_REQUEST lpOutBuffer,
            Int32 nOutBufferSize,
            out Int32 lpBytesReturned,
            IntPtr lpOverlapped
            );

        [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
        internal static extern Boolean DeviceIoControl(
            IntPtr hFile,
            Int32 dwIoControlCode,
            ref USB_NODE_CONNECTION_DRIVERKEY_NAME lpInBuffer,
            Int32 nInBufferSize,
            ref USB_NODE_CONNECTION_DRIVERKEY_NAME lpOutBuffer,
            Int32 nOutBufferSize,
            out Int32 lpBytesReturned,
            IntPtr lpOverlapped
            );
        #endregion
    }
}

(二)设备枚举API

/* ----------------------------------------------------------
文件名称:WDKUsbEnum.cs

作者:秦建辉

MSN:[email protected]
QQ:36748897

博客:http://blog.csdn.net/jhqin

开发环境:
    Visual Studio V2010
    .NET Framework 4 Client Profile

版本历史:
    V1.0    2011年10月10日
            基于WDK枚举USB设备
------------------------------------------------------------ */
using System;
using System.Collections.Generic;
using System.Management;
using System.Runtime.InteropServices;
using System.Text;

namespace Splash.IO.PORTS
{
    /// <summary>
    /// USB主控制器信息
    /// </summary>
    public struct HostControllerInfo
    {
        public String PNPDeviceID;      // 设备ID
        public String Name;             // 设备名称
    }

    /// <summary>
    /// USB Hub信息
    /// </summary>
    public struct UsbHubInfo
    {
        public String PNPDeviceID;      // 设备ID
        public String Name;             // 设备名称
        public String Status;           // 设备状态
    }

    /// <summary>
    /// USB HUB节点信息
    /// </summary>
    public struct UsbNodeInformation
    {
        public String DevicePath;           // 设备路径
        public String PNPDeviceID;          // 设备ID
        public String Name;                 // 设备名称

        public USB_HUB_NODE NodeType;       // 节点类型

        // USB_HUB_INFORMATION
        public Boolean HubIsBusPowered;     // 供电方式:true-总线供电 false-独立供电
        public Int32 NumberOfPorts;         // 端口数
        public Int16 HubCharacteristics;    // 特征描述
        public Byte PowerOnToPowerGood;     // 从端口加电到端口正常工作的时间间隔(以2ms为单位)
        public Byte HubControlCurrent;      // 设备所需最大电流

        // USB_MI_PARENT_INFORMATION
        public Int32 NumberOfInterfaces;    // 接口数
    }

    /// <summary>
    /// USB设备描述符
    /// </summary>
    public struct UsbDeviceDescriptor
    {
        public Byte bDescriptorType;    // 描述符类型 USB_DEVICE_DESCRIPTOR_TYPE
        public String UsbVersion;       // USB规格版本号
        public Byte bDeviceClass;       // 设备类型
        public Byte bDeviceSubClass;    // 设备子类型
        public Byte bDeviceProtocol;    // 设备协议
        public Byte bMaxPacketSize0;    // 最大封包大小
        public UInt16 idVendor;         // VID
        public UInt16 idProduct;        // PID
        public String DeviceVersion;    // 设备版本号
        public String Manufacturer;     // 制造商
        public String Product;          // 产品描述
        public String SerialNumber;     // 序列号
        public Byte bNumConfigurations; // 配置总数
    }

    /// <summary>
    /// USB管道信息
    /// </summary>
    public struct UsbPipeInfo
    {
        public UInt32 ScheduleOffset;
        public Byte bDescriptorType;
        public Byte bEndpointAddress;
        public Byte bmAttributes;
        public UInt16 wMaxPacketSize;
        public Byte bInterval;
    }

    /// <summary>
    /// USB节点连接信息
    /// </summary>
    public struct UsbNodeConnectionInformation
    {
        public String DevicePath;           // 设备路径
        public Int32 ConnectionIndex;       // 端口号

        public UsbDeviceDescriptor DeviceDescriptor;

        public Byte CurrentConfigurationValue;  // 当前设备配置
        public Byte Speed;                  // 设备速度
        public Boolean DeviceIsHub;         // 是否是集线器
        public Int32 DeviceAddress;         // 设备地址
        public Int32 NumberOfOpenPipes;     // 管道数
        public USB_CONNECTION_STATUS ConnectionStatus;  // 连接状态

        public List<UsbPipeInfo> PipeList;  // 管道信息
    }

    /// <summary>
    /// USB设备枚举
    /// </summary>
    public partial class USB
    {
        #region HostController
        /// <summary>
        /// USB主控制器
        /// </summary>
        public static HostControllerInfo[] AllHostControllers
        {
            get
            {
                List<HostControllerInfo> HostControllers = new List<HostControllerInfo>();

                // 获取USB控制器及其相关联的设备实体
                ManagementObjectCollection MOC = new ManagementObjectSearcher("SELECT * FROM Win32_USBController").Get();
                if (MOC != null)
                {
                    foreach (ManagementObject MO in MOC)
                    {
                        HostControllerInfo Element;
                        Element.PNPDeviceID = MO["PNPDeviceID"] as String;  // 设备ID
                        Element.Name = MO["Name"] as String;    // 设备描述
                        HostControllers.Add(Element);
                    }
                }

                if (HostControllers.Count == 0) return null; else return HostControllers.ToArray();
            }
        }

        /// <summary>
        /// 获取驱动键名
        /// </summary>
        /// <param name="PNPDeviceID">USB主控制器设备ID</param>
        /// <returns>获取设备驱动在注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class下的路径</returns>
        public static String GetHcdDriverKeyName(String PNPDeviceID)
        {
            if (String.IsNullOrEmpty(PNPDeviceID)) return null;

            // 打开设备
            IntPtr hHCDev = Kernel32.CreateFile(
                "\\\\.\\" + PNPDeviceID.Replace(‘\\‘, ‘#‘) + "#{3ABF6F2D-71C4-462A-8A92-1E6861E6AF27}",
                NativeFileAccess.GENERIC_WRITE,
                NativeFileShare.FILE_SHARE_WRITE,
                IntPtr.Zero,
                NativeFileMode.OPEN_EXISTING,
                IntPtr.Zero,
                IntPtr.Zero);
            if (hHCDev == Kernel32.INVALID_HANDLE_VALUE) return null;

            // 获取驱动键名
            Int32 nBytesReturned;
            USB_HCD_DRIVERKEY_NAME Buffer = new USB_HCD_DRIVERKEY_NAME();
            Boolean Status = DeviceIoControl(hHCDev,
                IOCTL_GET_HCD_DRIVERKEY_NAME,
                IntPtr.Zero,
                0,
                ref Buffer,
                Marshal.SizeOf(Buffer),
                out nBytesReturned,
                IntPtr.Zero);            

            // 关闭设备
            Kernel32.CloseHandle(hHCDev);
            return Status ? Buffer.Name : null;
        }
        #endregion

        #region USBHUB
        /// <summary>
        /// USB Hub信息集合
        /// </summary>
        public static UsbHubInfo[] AllUsbHubs
        {
            get
            {
                List<UsbHubInfo> UsbHubs = new List<UsbHubInfo>();

                // 获取USB控制器及其相关联的设备实体
                ManagementObjectCollection MOC = new ManagementObjectSearcher("SELECT * FROM Win32_USBHub").Get();
                if (MOC != null)
                {
                    foreach (ManagementObject MO in MOC)
                    {
                        UsbHubInfo Element;
                        Element.PNPDeviceID = MO["PNPDeviceID"] as String;  // 设备ID
                        Element.Name = MO["Name"] as String;        // 设备描述
                        Element.Status = MO["Status"] as String;    // 设备状态
                        UsbHubs.Add(Element);
                    }
                }

                if (UsbHubs.Count == 0) return null; else return UsbHubs.ToArray();
            }
        }

        /// <summary>
        /// USB ROOT HUB设备路径
        /// </summary>
        /// <param name="PNPDeviceID">USB主控制器设备ID</param>
        /// <returns>USB ROOT HUB设备路径</returns>
        public static String GetUsbRootHubPath(String PNPDeviceID)
        {
            if (String.IsNullOrEmpty(PNPDeviceID)) return null;            

            // 打开设备
            IntPtr hHCDev = Kernel32.CreateFile(
                "\\\\.\\" + PNPDeviceID.Replace(‘\\‘, ‘#‘) + "#{3ABF6F2D-71C4-462A-8A92-1E6861E6AF27}",
                NativeFileAccess.GENERIC_WRITE,
                NativeFileShare.FILE_SHARE_WRITE,
                IntPtr.Zero,
                NativeFileMode.OPEN_EXISTING,
                IntPtr.Zero,
                IntPtr.Zero);
            if (hHCDev == Kernel32.INVALID_HANDLE_VALUE) return null;

            // 获取USB ROOT HUB名称
            Int32 nBytesReturned;
            USB_HCD_DRIVERKEY_NAME Buffer = new USB_HCD_DRIVERKEY_NAME();
            Boolean Status = DeviceIoControl(hHCDev,
                IOCTL_USB_GET_ROOT_HUB_NAME,
                IntPtr.Zero,
                0,
                ref Buffer,
                Marshal.SizeOf(Buffer),
                out nBytesReturned,
                IntPtr.Zero);

            // 关闭设备
            Kernel32.CloseHandle(hHCDev);
            return Status ? Buffer.Name : null;
        }

        /// <summary>
        /// USB HUB设备名称
        /// </summary>
        /// <param name="DevicePath">设备路径</param>
        /// <returns>设备名称</returns>
        public static String GetUsbHubName(String DevicePath)
        {
            if (String.IsNullOrEmpty(DevicePath)) return null;

            // 从设备路径中提取设备ID
            String DeviceID = DevicePath.Substring(0, DevicePath.LastIndexOf(‘#‘)).Replace(‘#‘, ‘_‘);

            // 从Win32_USBHub获取设备描述
            ManagementObjectCollection MOC = new ManagementObjectSearcher("SELECT * FROM Win32_USBHub WHERE DeviceID LIKE ‘" + DeviceID + "‘").Get();
            if (MOC != null)
            {
                foreach (ManagementObject MO in MOC)
                {
                    return MO["Name"] as String;
                }
            }

            return null;
        }

        /// <summary>
        /// 获取USB HUB节点信息
        /// </summary>
        /// <param name="DevicePath">USB HUB设备路径</param>
        /// <returns>节点信息</returns>
        public static UsbNodeInformation[] GetUsbNodeInformation(String DevicePath)
        {
            if (String.IsNullOrEmpty(DevicePath)) return null;

            // 打开设备文件
            IntPtr hHubDevice = Kernel32.CreateFile(
                "\\\\.\\" + DevicePath,
                NativeFileAccess.GENERIC_WRITE,
                NativeFileShare.FILE_SHARE_WRITE,
                IntPtr.Zero,
                NativeFileMode.OPEN_EXISTING,
                IntPtr.Zero,
                IntPtr.Zero);
            if (hHubDevice == Kernel32.INVALID_HANDLE_VALUE) return null;

            // 查询节点信息
            Int32 nBytesReturned;
            USB_NODE_INFORMATION Buffer = new USB_NODE_INFORMATION();
            Boolean Status = DeviceIoControl(hHubDevice,
                IOCTL_USB_GET_NODE_INFORMATION,
                ref Buffer,
                Marshal.SizeOf(Buffer),
                ref Buffer,
                Marshal.SizeOf(Buffer),
                out nBytesReturned,
                IntPtr.Zero);

            // 关闭设备文件
            Kernel32.CloseHandle(hHubDevice);
            if (!Status) return null;

            UsbNodeInformation Node = new UsbNodeInformation();
            Node.NodeType = Buffer.NodeType;    // 节点类型
            Node.PNPDeviceID = DevicePath.Substring(0, DevicePath.LastIndexOf(‘#‘)).Replace(‘#‘, ‘\\‘); // 设备ID
            Node.DevicePath = DevicePath;       // 设备路径
            Node.Name = GetUsbHubName(DevicePath);  // 设备名称
            if (Buffer.NodeType == USB_HUB_NODE.UsbHub)
            {
                Node.NumberOfPorts = Buffer.u.HubInformation.HubDescriptor.bNumberOfPorts;         // 端口数
                Node.HubIsBusPowered = Convert.ToBoolean(Buffer.u.HubInformation.HubIsBusPowered);  // 供电方式
                Node.HubCharacteristics = Buffer.u.HubInformation.HubDescriptor.wHubCharacteristics;
                Node.PowerOnToPowerGood = Buffer.u.HubInformation.HubDescriptor.bPowerOnToPowerGood;
                Node.HubControlCurrent = Buffer.u.HubInformation.HubDescriptor.bHubControlCurrent;
            }
            else
            {
                Node.NumberOfInterfaces = Buffer.u.MiParentInformation.NumberOfInterfaces;  // 接口数
            }

            return new UsbNodeInformation[1] { Node };
        }
        #endregion 

        #region NODECONNECTION
        /// <summary>
        /// 获取USB节点连接信息
        /// </summary>
        /// <param name="DevicePath">设备路径</param>
        /// <param name="NumberOfPorts">端口总数</param>
        /// <returns>USB节点信息连接信息集合</returns>
        public static UsbNodeConnectionInformation[] GetUsbNodeConnectionInformation(String DevicePath, Int32 NumberOfPorts)
        {
            if (String.IsNullOrEmpty(DevicePath)) return null;

            // 打开设备文件
            IntPtr hHubDevice = Kernel32.CreateFile(
                "\\\\.\\" + DevicePath,
                NativeFileAccess.GENERIC_WRITE,
                NativeFileShare.FILE_SHARE_WRITE,
                IntPtr.Zero,
                NativeFileMode.OPEN_EXISTING,
                IntPtr.Zero,
                IntPtr.Zero);
            if (hHubDevice == Kernel32.INVALID_HANDLE_VALUE) return null;

            List<UsbNodeConnectionInformation> NodeCollection = new List<UsbNodeConnectionInformation>();

            // 枚举端口
            USB_NODE_CONNECTION_INFORMATION_EX Buffer = new USB_NODE_CONNECTION_INFORMATION_EX();
            for (Int32 ConnectionIndex = 1; ConnectionIndex <= NumberOfPorts; ConnectionIndex++)
            {
                // 查询节点信息
                Int32 nBytesReturned;
                Buffer.ConnectionIndex = ConnectionIndex;
                Boolean Status = DeviceIoControl(hHubDevice,
                    IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX,
                    ref Buffer,
                    Marshal.SizeOf(Buffer),
                    ref Buffer,
                    Marshal.SizeOf(Buffer),
                    out nBytesReturned,
                    IntPtr.Zero);
                if (Status)
                {
                    // 确定语言ID
                    UInt16 LanguageID = SelectLanguageID(hHubDevice, ConnectionIndex);

                    // 提取信息
                    UsbNodeConnectionInformation Node = new UsbNodeConnectionInformation();

                    Node.DevicePath = DevicePath;
                    Node.ConnectionIndex = Buffer.ConnectionIndex;
                    Node.ConnectionStatus = Buffer.ConnectionStatus;
                    if (Buffer.ConnectionStatus == USB_CONNECTION_STATUS.DeviceConnected)
                    {
                        Node.CurrentConfigurationValue = Buffer.CurrentConfigurationValue;
                        Node.Speed = Buffer.Speed;
                        Node.DeviceIsHub = Convert.ToBoolean(Buffer.DeviceIsHub);
                        Node.DeviceAddress = Buffer.DeviceAddress;
                        Node.NumberOfOpenPipes = Buffer.NumberOfOpenPipes;                        

                        // 设备描述符
                        Node.DeviceDescriptor.bDescriptorType = Buffer.DeviceDescriptor.bDescriptorType;
                        Node.DeviceDescriptor.bDeviceClass = Buffer.DeviceDescriptor.bDeviceClass;
                        Node.DeviceDescriptor.bDeviceSubClass = Buffer.DeviceDescriptor.bDeviceSubClass;
                        Node.DeviceDescriptor.bDeviceProtocol = Buffer.DeviceDescriptor.bDeviceProtocol;

                        Node.DeviceDescriptor.UsbVersion = BcdVersionToString(Buffer.DeviceDescriptor.bcdUSB); // USB版本号
                        Node.DeviceDescriptor.DeviceVersion = BcdVersionToString(Buffer.DeviceDescriptor.bcdDevice);    // 设备版本号

                        Node.DeviceDescriptor.idVendor = Buffer.DeviceDescriptor.idVendor;      // 厂商标识
                        Node.DeviceDescriptor.idProduct = Buffer.DeviceDescriptor.idProduct;    // 产品标识

                        if (LanguageID != 0)
                        {
                            if (Buffer.DeviceDescriptor.iSerialNumber != 0)
                            {   // 序列号
                                Node.DeviceDescriptor.SerialNumber = GetStringDescriptor(hHubDevice,
                                    Buffer.ConnectionIndex,
                                    Buffer.DeviceDescriptor.iSerialNumber,
                                    LanguageID);
                            }

                            if (Buffer.DeviceDescriptor.iManufacturer != 0)
                            {   // 制造商名称
                                Node.DeviceDescriptor.Manufacturer = GetStringDescriptor(hHubDevice,
                                    Buffer.ConnectionIndex,
                                    Buffer.DeviceDescriptor.iManufacturer,
                                    LanguageID);
                            }

                            if (Buffer.DeviceDescriptor.iProduct != 0)
                            {   // 产品名称
                                Node.DeviceDescriptor.Product = GetStringDescriptor(hHubDevice,
                                    Buffer.ConnectionIndex,
                                    Buffer.DeviceDescriptor.iProduct,
                                    LanguageID);
                            }
                        }

                        Node.DeviceDescriptor.bMaxPacketSize0 = Buffer.DeviceDescriptor.bMaxPacketSize0;
                        Node.DeviceDescriptor.bNumConfigurations = Buffer.DeviceDescriptor.bNumConfigurations;

                        // 管道信息
                        Node.PipeList = new List<UsbPipeInfo>();
                        for (Int32 PipeIndex = 0; PipeIndex < Buffer.NumberOfOpenPipes; PipeIndex++)
                        {
                            UsbPipeInfo PipeInfo;

                            PipeInfo.ScheduleOffset = Buffer.PipeList[PipeIndex].ScheduleOffset;
                            PipeInfo.bDescriptorType = Buffer.PipeList[PipeIndex].EndpointDescriptor.bDescriptorType;
                            PipeInfo.bEndpointAddress = Buffer.PipeList[PipeIndex].EndpointDescriptor.bEndpointAddress;
                            PipeInfo.bmAttributes = Buffer.PipeList[PipeIndex].EndpointDescriptor.bmAttributes;
                            PipeInfo.wMaxPacketSize = Buffer.PipeList[PipeIndex].EndpointDescriptor.wMaxPacketSize;
                            PipeInfo.bInterval = Buffer.PipeList[PipeIndex].EndpointDescriptor.bInterval;

                            Node.PipeList.Add(PipeInfo);
                        }
                    }

                    NodeCollection.Add(Node);
                }
            }

            // 关闭设备文件
            Kernel32.CloseHandle(hHubDevice);

            // 返回结果
            if (NodeCollection.Count == 0)
                return null;
            else
                return NodeCollection.ToArray();
        }

        /// <summary>
        /// 获取字符串描述符
        /// </summary>
        /// <param name="hHubDevice">USB Hub设备句柄</param>
        /// <param name="ConnectionIndex">连接索引号</param>
        /// <param name="DescriptorIndex">描述符索引号</param>
        /// <param name="LanguageID">语言ID</param>
        /// <returns>字符串描述符</returns>
        public static String GetStringDescriptor(IntPtr hHubDevice, Int32 ConnectionIndex, Byte DescriptorIndex, UInt16 LanguageID)
        {
            USB_DESCRIPTOR_REQUEST Buffer = new USB_DESCRIPTOR_REQUEST();
            Buffer.ConnectionIndex = ConnectionIndex;
            Buffer.SetupPacket.wValue = (UInt16)((USB_STRING_DESCRIPTOR_TYPE << 8) | DescriptorIndex);
            Buffer.SetupPacket.wIndex = LanguageID;
            Buffer.SetupPacket.wLength = MAXIMUM_USB_STRING_LENGTH;
            Int32 nBytesReturned;
            Boolean Status = DeviceIoControl(hHubDevice,
                    IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,
                    ref Buffer,
                    Marshal.SizeOf(Buffer),
                    ref Buffer,
                    Marshal.SizeOf(Buffer),
                    out nBytesReturned,
                    IntPtr.Zero);
            if (Status)
                return Buffer.Data.bString;
            else
                return null;
        }

        /// <summary>
        /// 选择语言ID
        /// </summary>
        /// <param name="hHubDevice">USB Hub设备句柄</param>
        /// <param name="ConnectionIndex">连接索引号</param>
        /// <returns></returns>
        public static UInt16 SelectLanguageID(IntPtr hHubDevice, Int32 ConnectionIndex)
        {
            // 获取支持的语言列表
            String SupportedLanguagesString = GetStringDescriptor(hHubDevice, ConnectionIndex, 0, 0);
            if(String.IsNullOrEmpty(SupportedLanguagesString))return 0;

            UInt16 UserDefaultUILanguage = Splash.Environment.UserDefaultUILanguage;
            if(SupportedLanguagesString.IndexOf(Convert.ToChar(UserDefaultUILanguage)) != -1)
            {   // 用户缺省界面语言
                return UserDefaultUILanguage;
            }
            else if(SupportedLanguagesString.IndexOf(Convert.ToChar(0x0409)) != -1)
            {   // 美国英语 0x0409
                return 0x0409;
            }
            else
            {   // 第一个可选择的LANGID
                return Convert.ToUInt16(SupportedLanguagesString[0]);
            }
        }
        #endregion

        #region EXTERNALHUB
        /// <summary>
        /// 获取外接Hub设备路径
        /// </summary>
        /// <param name="ParentDevicePath">上层Hub设备路径</param>
        /// <param name="ConnectionIndex">连接索引号</param>
        /// <returns>外接Hub设备路径</returns>
        public static String GetExternalHubPath(String ParentDevicePath, Int32 ConnectionIndex)
        {
            if (String.IsNullOrEmpty(ParentDevicePath)) return null;

            // 打开设备文件
            IntPtr hParentHubDevice = Kernel32.CreateFile(
                "\\\\.\\" + ParentDevicePath,
                NativeFileAccess.GENERIC_WRITE,
                NativeFileShare.FILE_SHARE_WRITE,
                IntPtr.Zero,
                NativeFileMode.OPEN_EXISTING,
                IntPtr.Zero,
                IntPtr.Zero);
            if (hParentHubDevice == Kernel32.INVALID_HANDLE_VALUE) return null;

            USB_NODE_CONNECTION_DRIVERKEY_NAME Buffer = new USB_NODE_CONNECTION_DRIVERKEY_NAME();
            Buffer.ConnectionIndex = ConnectionIndex;
            Int32 nBytesReturned;
            Boolean Status = DeviceIoControl(hParentHubDevice,
                    IOCTL_USB_GET_NODE_CONNECTION_NAME,
                    ref Buffer,
                    Marshal.SizeOf(Buffer),
                    ref Buffer,
                    Marshal.SizeOf(Buffer),
                    out nBytesReturned,
                    IntPtr.Zero);

            // 关闭设备文件
            Kernel32.CloseHandle(hParentHubDevice);

            if (Status)
                return Buffer.DriverKeyName;
            else
                return null;
        }

        /// <summary>
        /// 获取外接Hub设备路径
        /// </summary>
        /// <param name="hParentHubDevice">上层Hub设备句柄</param>
        /// <param name="ConnectionIndex">连接索引号</param>
        /// <returns>外接Hub设备路径</returns>
        public static String GetExternalHubPath(IntPtr hParentHubDevice, Int32 ConnectionIndex)
        {
            if (hParentHubDevice == IntPtr.Zero || ConnectionIndex <= 0) return null;

            USB_NODE_CONNECTION_DRIVERKEY_NAME Buffer = new USB_NODE_CONNECTION_DRIVERKEY_NAME();
            Buffer.ConnectionIndex = ConnectionIndex;
            Int32 nBytesReturned;
            Boolean Status = DeviceIoControl(hParentHubDevice,
                    IOCTL_USB_GET_NODE_CONNECTION_NAME,
                    ref Buffer,
                    Marshal.SizeOf(Buffer),
                    ref Buffer,
                    Marshal.SizeOf(Buffer),
                    out nBytesReturned,
                    IntPtr.Zero);            

            if (Status)
                return Buffer.DriverKeyName;
            else
                return null;
        }
        #endregion

        #region BCDVERSION
        /// <summary>
        /// 版本BCD编码转字符串
        /// </summary>
        /// <param name="bcd">版本BCD编码</param>
        /// <returns>版本字符串</returns>
        private static String BcdVersionToString(UInt16 bcd)
        {
            StringBuilder sb = new StringBuilder(5);

            // 主版本号
            Int32 BIT4 = (bcd >> 12) & 0x0F;
            if (BIT4 != 0) sb.Append(BIT4.ToString());

            BIT4 = (bcd >> 8) & 0x0F;
            sb.Append(BIT4.ToString());

            sb.Append(".");

            // 子版本号
            BIT4 = (bcd >> 4) & 0x0F;
            sb.Append(BIT4.ToString());

            BIT4 = bcd & 0x0F;
            if (BIT4 != 0) sb.Append(BIT4.ToString());

            return sb.ToString();
        }
        #endregion
    }
}

(三)输出枚举信息到XML文档

/* ----------------------------------------------------------
文件名称:UsbEnumXML.cs

作者:秦建辉

MSN:[email protected]
QQ:36748897

博客:http://blog.csdn.net/jhqin

开发环境:
    Visual Studio V2010
    .NET Framework 4 Client Profile

版本历史:
    V1.0    2011年10月28日
            将USB设备枚举信息导出为XML文档
------------------------------------------------------------ */
using System;
using System.Collections.Generic;
using System.Xml.Linq;

namespace Splash.IO.PORTS
{
    /// <summary>
    /// 将USB设备信息写入XML文件
    /// </summary>
    public partial class USB
    {
        /// <summary>
        /// 将USB设备枚举信息导出为XML文档
        /// </summary>
        /// <param name="xmlFileName">保存的XML文件名</param>
        /// <returns>
        ///     true:成功
        ///     false:失败
        /// </returns>
        public static Boolean EnumUsbToXML(String xmlFileName)
        {   // 创建根节点
            XElement RootNode = new XElement("Computer",
                new XAttribute("MachineName", System.Environment.MachineName));

            // 深度遍历主控制器
            HostControllerInfo[] HostControllersCollection = USB.AllHostControllers;
            if (HostControllersCollection != null)
            {
                Int32 ControllerIndex = 1;
                foreach (HostControllerInfo item in HostControllersCollection)
                {   // 创建主控制器节点
                    String PNPDeviceID = item.PNPDeviceID;
                    String HcdDriverKeyName = USB.GetHcdDriverKeyName(PNPDeviceID);
                    XElement HostControllerNode = new XElement("HostController" + ControllerIndex,
                        new XAttribute("Name", item.Name),  // 设备名称
                        new XAttribute("PNPDeviceID", PNPDeviceID), // 设备ID
                        new XAttribute("HcdDriverKeyName", HcdDriverKeyName)    // 驱动键名
                        );
                    RootNode.Add(HostControllerNode);
                    ControllerIndex++;

                    // 创建根集线器节点
                    String RootHubPath = USB.GetUsbRootHubPath(PNPDeviceID);
                    AddHubNode(HostControllerNode, RootHubPath, "RootHub");
                }
            }

            // 创建XML文档
            XDocument xmlTree = new XDocument(RootNode);

            // 存储文件,序列化时对XML进行格式设置(缩进)
            xmlTree.Save(xmlFileName, SaveOptions.None);
            return true;
        }

        /// <summary>
        /// 增加集线器节点
        /// </summary>
        /// <param name="ParentNode">父节点</param>
        /// <param name="HubPath">集线器路径</param>
        private static void AddHubNode(XElement ParentNode, String HubPath, String HubNodeName)
        {
            UsbNodeInformation[] NodeInfoCollection = USB.GetUsbNodeInformation(HubPath);
            if (NodeInfoCollection != null)
            {
                USB_HUB_NODE NodeType = NodeInfoCollection[0].NodeType;
                XElement HubNode = new XElement(HubNodeName,
                    new XAttribute("Name", NodeInfoCollection[0].Name),
                    new XAttribute("PNPDeviceID", NodeInfoCollection[0].PNPDeviceID),
                    new XAttribute("Path", NodeInfoCollection[0].DevicePath),
                    new XAttribute("NodeType", NodeType)
                    );

                if (NodeType == USB_HUB_NODE.UsbHub)
                {
                    Int32 NumberOfPorts = NodeInfoCollection[0].NumberOfPorts;
                    HubNode.Add(new XAttribute("NumberOfPorts", NumberOfPorts),
                        new XAttribute("HubIsBusPowered", NodeInfoCollection[0].HubIsBusPowered),
                        new XAttribute("HubCharacteristics", "0x" + NodeInfoCollection[0].HubCharacteristics.ToString("X4")),
                        new XAttribute("PowerOnToPowerGood", NodeInfoCollection[0].PowerOnToPowerGood),
                        new XAttribute("HubControlCurrent", NodeInfoCollection[0].HubControlCurrent)
                        );

                    // 深度遍历端口
                    UsbNodeConnectionInformation[] NodeConnectionInfoCollection = USB.GetUsbNodeConnectionInformation(HubPath, NumberOfPorts);
                    if (NodeConnectionInfoCollection != null)
                    {
                        foreach (UsbNodeConnectionInformation NodeConnectionInfo in NodeConnectionInfoCollection)
                        {   // 增加端口节点
                            AddPortNode(HubNode, NodeConnectionInfo);
                        }
                    }
                }
                else
                {
                    HubNode.Add("NumberOfInterfaces", NodeInfoCollection[0].NumberOfInterfaces);
                }

                ParentNode.Add(HubNode);
            }
        }

        /// <summary>
        /// 增加端口节点
        /// </summary>
        /// <param name="HubNode">集线器节点</param>
        /// <param name="NodeConnectionInfo">USB设备节点连接信息</param>
        private static void AddPortNode(XElement HubNode, UsbNodeConnectionInformation NodeConnectionInfo)
        {
            String DevicePath = NodeConnectionInfo.DevicePath;
            Int32 ConnectionIndex = NodeConnectionInfo.ConnectionIndex;
            USB_CONNECTION_STATUS ConnectionStatus = NodeConnectionInfo.ConnectionStatus;    

            // 创建端口节点
            XElement PortNode = new XElement("Port" + ConnectionIndex,
                new XAttribute("DevicePath", DevicePath),
                new XAttribute("ConnectionIndex", ConnectionIndex),
                new XAttribute("ConnectionStatus", NodeConnectionInfo.ConnectionStatus)
                );

            if (ConnectionStatus == USB_CONNECTION_STATUS.DeviceConnected)
            {
                Boolean DeviceIsHub = NodeConnectionInfo.DeviceIsHub;
                PortNode.Add(new XAttribute("DeviceIsHub", DeviceIsHub),
                    new XAttribute("CurrentConfigurationValue", NodeConnectionInfo.CurrentConfigurationValue),
                    new XAttribute("Speed", NodeConnectionInfo.Speed),
                    new XAttribute("DeviceAddress", NodeConnectionInfo.DeviceAddress),
                    new XAttribute("NumberOfOpenPipes", NodeConnectionInfo.NumberOfOpenPipes)
                    );

                // 设备描述符信息
                AddDeviceDescriptorNode(PortNode, ref NodeConnectionInfo.DeviceDescriptor);

                // 管道信息
                AddPipeInfoNode(PortNode, ref NodeConnectionInfo.PipeList);

                // 外部集线器
                if (DeviceIsHub)
                {   // 获取外部Hub设备路径
                    String ExternalHubPath = GetExternalHubPath(DevicePath, ConnectionIndex);

                    // 增加外部集线器节点
                    AddHubNode(PortNode, ExternalHubPath, "ExternalHub");
                }
            }           

            HubNode.Add(PortNode);
        }

        /// <summary>
        /// 增加设备描述符节点
        /// </summary>
        /// <param name="PortNode"></param>
        /// <param name="DeviceDescriptor"></param>
        private static void AddDeviceDescriptorNode(XElement PortNode, ref UsbDeviceDescriptor DeviceDescriptor)
        {
            XElement DeviceDescriptorNode = new XElement("DeviceDescriptor",
                new XAttribute("bDescriptorType", "0x" + DeviceDescriptor.bDescriptorType.ToString("X2")),
                new XAttribute("UsbVersion", DeviceDescriptor.UsbVersion),
                new XAttribute("bDeviceClass", "0x" + DeviceDescriptor.bDeviceClass.ToString("X2")),
                new XAttribute("bDeviceSubClass", "0x" + DeviceDescriptor.bDeviceSubClass.ToString("X2")),
                new XAttribute("bDeviceProtocol", "0x" + DeviceDescriptor.bDeviceProtocol.ToString("X2")),
                new XAttribute("bMaxPacketSize0", DeviceDescriptor.bMaxPacketSize0),
                new XAttribute("bNumConfigurations", DeviceDescriptor.bNumConfigurations)
                );

            if (DeviceDescriptor.idVendor != 0)
            {
                DeviceDescriptorNode.Add(new XAttribute("idVendor", "0x" + DeviceDescriptor.idVendor.ToString("X4")));
            }

            if (DeviceDescriptor.idProduct != 0)
            {
                DeviceDescriptorNode.Add(new XAttribute("idProduct", "0x" + DeviceDescriptor.idProduct.ToString("X4")));
            }

            if (!String.IsNullOrEmpty(DeviceDescriptor.DeviceVersion))
            {
                DeviceDescriptorNode.Add(new XAttribute("DeviceVersion", DeviceDescriptor.DeviceVersion));
            }

            if (!String.IsNullOrEmpty(DeviceDescriptor.Manufacturer))
            {
                DeviceDescriptorNode.Add(new XAttribute("Manufacturer", DeviceDescriptor.Manufacturer));
            }

            if (!String.IsNullOrEmpty(DeviceDescriptor.Product))
            {
                DeviceDescriptorNode.Add(new XAttribute("Product", DeviceDescriptor.Product));
            }

            if (!String.IsNullOrEmpty(DeviceDescriptor.SerialNumber))
            {
                DeviceDescriptorNode.Add(new XAttribute("SerialNumber", DeviceDescriptor.SerialNumber));
            }

            PortNode.Add(DeviceDescriptorNode);
        }

        /// <summary>
        /// 增加管道信息节点
        /// </summary>
        /// <param name="PortNode">端口节点</param>
        /// <param name="PipeList">管道信息列表</param>
        private static void AddPipeInfoNode(XElement PortNode, ref List<UsbPipeInfo> PipeList)
        {
            if(PipeList != null)
            {
                XElement PipeListNode = new XElement("PipeList");
                Int32 PipeIndex = 1;
                foreach(UsbPipeInfo item in PipeList)
                {
                    XElement PipeInfoNode = new XElement("Pipe" + PipeIndex,
                        new XAttribute("ScheduleOffset", item.ScheduleOffset),
                        new XAttribute("bDescriptorType", "0x" + item.bDescriptorType.ToString("X2")),
                        new XAttribute("bEndpointAddress", "0x" + item.bEndpointAddress.ToString("X2")),
                        new XAttribute("bmAttributes", "0x" + item.bmAttributes.ToString("X2")),
                        new XAttribute("wMaxPacketSize", item.wMaxPacketSize),
                        new XAttribute("bInterval", item.bInterval)
                        );

                    PipeListNode.Add(PipeInfoNode);
                    PipeIndex++;
                }

                PortNode.Add(PipeListNode);
            }
        }
    }
}

(四)Kernel32的PInvoke

/* ----------------------------------------------------------
文件名称:Kernel32.cs

作者:秦建辉

MSN:[email protected]
QQ:36748897

博客:http://blog.csdn.net/jhqin

开发环境:
    Visual Studio V2010
    .NET Framework 4 Client Profile

版本历史:
    V1.0    2011年09月05日
            实现对Kernel32.dll接口的PInvoke

参考资料:
    http://www.pinvoke.net/
------------------------------------------------------------ */
using System;
using System.Runtime.InteropServices;
using System.Security;

namespace Splash
{
    #region Kernel32
    [SuppressUnmanagedCodeSecurity]
    internal static class Kernel32
    {
        /// <summary>
        /// 无效的文件句柄
        /// </summary>
        public static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);

        #region CreateFile
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr CreateFile(
            String fileName,
            [MarshalAs(UnmanagedType.U4)] NativeFileAccess fileAccess,
            [MarshalAs(UnmanagedType.U4)] NativeFileShare fileShare,
            IntPtr securityAttributes,
            [MarshalAs(UnmanagedType.U4)] NativeFileMode creationDisposition,
            NativeFileFlag flags,
            IntPtr template
            );

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr CreateFile(
            String fileName,
            [MarshalAs(UnmanagedType.U4)] NativeFileAccess fileAccess,
            [MarshalAs(UnmanagedType.U4)] NativeFileShare fileShare,
            IntPtr securityAttributes,
            [MarshalAs(UnmanagedType.U4)] NativeFileMode creationDisposition,
            IntPtr flags,
            IntPtr template
            );
        #endregion

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern Boolean CloseHandle(IntPtr hFile);

        #region ReadFile
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern Boolean ReadFile(
            IntPtr hFile,
            [Out] Byte[] lpBuffer,
            Int32 nNumberOfBytesToRead,
            out Int32 lpNumberOfBytesRead,
            [In] ref System.Threading.NativeOverlapped lpOverlapped
            );

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern Boolean ReadFile(
            IntPtr hFile,
            [Out] Byte[] lpBuffer,
            Int32 nNumberOfBytesToRead,
            IntPtr lpNumberOfBytesRead,
            [In] ref System.Threading.NativeOverlapped lpOverlapped
            );

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern Boolean ReadFile(
            IntPtr hFile,
            [Out] Byte[] lpBuffer,
            Int32 nNumberOfBytesToRead,
            out Int32 lpNumberOfBytesRead,
            IntPtr lpOverlapped
            );
        #endregion

        #region WriteFile
        [DllImport("kernel32.dll")]
        public static extern Boolean WriteFile(
            IntPtr hFile,
            Byte[] lpBuffer,
            Int32 nNumberOfBytesToWrite,
            out Int32 lpNumberOfBytesWritten,
            [In] ref System.Threading.NativeOverlapped lpOverlapped
            );

        [DllImport("kernel32.dll")]
        public static extern Boolean WriteFile(
            IntPtr hFile,
            Byte[] lpBuffer,
            Int32 nNumberOfBytesToWrite,
            IntPtr lpNumberOfBytesWritten,
            [In] ref System.Threading.NativeOverlapped lpOverlapped
            );

        [DllImport("kernel32.dll")]
        public static extern Boolean WriteFile(
            IntPtr hFile,
            Byte[] lpBuffer,
            Int32 nNumberOfBytesToWrite,
            IntPtr lpNumberOfBytesWritten,
            IntPtr lpOverlapped
            );
        #endregion

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern Boolean GetOverlappedResult(
            IntPtr hFile,
            [In] ref System.Threading.NativeOverlapped lpOverlapped,
            out Int32 lpNumberOfBytesTransferred,
            Boolean bWait
            );
    }
    #endregion

    #region ENUM
    [Flags]
    internal enum NativeFileAccess : uint
    {
        GENERIC_READ = (0x80000000),
        GENERIC_WRITE = (0x40000000),
        GENERIC_EXECUTE = (0x20000000),
        GENERIC_ALL = (0x10000000),

        FILE_SPECIAL = 0,
        FILE_APPEND_DATA = (0x0004),    // 文件
        FILE_READ_DATA = (0x0001),      // 文件和管道
        FILE_WRITE_DATA = (0x0002),     // 文件和管道
        FILE_READ_EA = (0x0008),        // 文件和目录
        FILE_WRITE_EA = (0x0010),       // 文件和目录
        FILE_READ_ATTRIBUTES = (0x0080),    // 所有
        FILE_WRITE_ATTRIBUTES = (0x0100),   // 所有
        DELETE = 0x00010000,
        READ_CONTROL = (0x00020000),
        WRITE_DAC = (0x00040000),
        WRITE_OWNER = (0x00080000),
        SYNCHRONIZE = (0x00100000),
        STANDARD_RIGHTS_REQUIRED = (0x000F0000),
        STANDARD_RIGHTS_READ = (READ_CONTROL),
        STANDARD_RIGHTS_WRITE = (READ_CONTROL),
        STANDARD_RIGHTS_EXECUTE = (READ_CONTROL),
        STANDARD_RIGHTS_ALL = (0x001F0000),
        SPECIFIC_RIGHTS_ALL = (0x0000FFFF),
        FILE_GENERIC_READ = (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE),
        FILE_GENERIC_WRITE = (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE),
        SPECIAL = 0
    }

    internal enum NativeFileMode : uint
    {
        CREATE_NEW = 1,
        CREATE_ALWAYS = 2,
        OPEN_EXISTING = 3,
        OPEN_ALWAYS = 4,
        TRUNCATE_EXISTING = 5,
    }

    [Flags]
    internal enum NativeFileShare : uint
    {
        NONE = 0,
        FILE_SHARE_READ = 0x00000001,
        FILE_SHARE_WRITE = 0x00000002,
        FILE_SHARE_DEELETE = 0x00000004,
    }

    [Flags]
    internal enum NativeFileFlag : uint
    {
        FILE_ATTRIBUTE_READONLY = 0x00000001,
        FILE_ATTRIBUTE_HIDDEN = 0x00000002,
        FILE_ATTRIBUTE_SYSTEM = 0x00000004,
        FILE_ATTRIBUTE_DIRECTORY = 0x00000010,
        FILE_ATTRIBUTE_ARCHIVE = 0x00000020,
        FILE_ATTRIBUTE_DEVICE = 0x00000040,
        FILE_ATTRIBUTE_NORMAL = 0x00000080,
        FILE_ATTRIBUTE_TEMPORARY = 0x00000100,
        FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200,
        FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400,
        FILE_ATTRIBUTE_COMPRESSED = 0x00000800,
        FILE_ATTRIBUTE_OFFLINE = 0x00001000,
        FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000,
        FILE_ATTRIBUTE_ENCRYPTED = 0x00004000,
        FILE_FLAG_WRITE_THROUGH = 0x80000000,
        FILE_FLAG_OVERLAPPED = 0x40000000,
        FILE_FLAG_NO_BUFFERING = 0x20000000,
        FILE_FLAG_RANDOM_ACCESS = 0x10000000,
        FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000,
        FILE_FLAG_DELETE_ON_CLOSE = 0x04000000,
        FILE_FLAG_BACKUP_SEMANTICS = 0x02000000,
        FILE_FLAG_POSIX_SEMANTICS = 0x01000000,
        FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000,
        FILE_FLAG_OPEN_NO_RECALL = 0x00100000,
        FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000,
    }
    #endregion
}

USB设备枚举(五)生成TreeView数据源

有一处错误已于2014年5月8日修正。请大家下载SkyDrive上的资源。

/* ----------------------------------------------------------
 * 文件名称:TreeViewUsbItem.cs
 *
 * 作者:秦建辉
 *
 * QQ:36748897
 *
 * 博客:http://www.firstsolver.com/wordpress/
 *
 * 开发环境:
 *      Visual Studio V2010
 *      .NET Framework 4 Client Profile
 *
 * 版本历史:
 *      V1.0    2014年05月08日
 *              修正由网友指出的一处错误
 *
 *      V1.0    2011年10月26日
 *              为USB设备枚举信息生成TreeView数据源
------------------------------------------------------------ */
using System;
using System.Collections.Generic;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Splash.IO.PORTS;

namespace WPFUsbView
{
    /// <summary>
    /// TreeView节点对象
    /// </summary>
    internal class TreeViewUsbItem
    {
        /// <summary>
        /// 节点图标
        /// </summary>
        public ImageSource Icon { get; set; }

        /// <summary>
        /// 节点名称
        /// </summary>
        public String Name { get; set; }

        /// <summary>
        /// 节点数据
        /// </summary>
        public Object Data { get; set; }

        /// <summary>
        /// 子节点列表
        /// </summary>
        public List<TreeViewUsbItem> Children { get; set; }        

        /// <summary>
        /// 计算机图标
        /// </summary>
        public static ImageSource ImageComputer
        {
            get
            {
                return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
                    Properties.Resources.notebook.Handle,
                    System.Windows.Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions()
                    );
            }
        }     

        /// <summary>
        /// 主控制器图标
        /// </summary>
        public static ImageSource ImageHostController
        {
            get
            {
                return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
                    Properties.Resources.usb.Handle,
                    System.Windows.Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions()
                    );
            }
        }

        /// <summary>
        /// Hub图标
        /// </summary>
        public static ImageSource ImageHub
        {
            get
            {
                return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
                    Properties.Resources.hub.Handle,
                    System.Windows.Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions()
                    );
            }
        }

        /// <summary>
        /// USB设备图标
        /// </summary>
        public static ImageSource ImageDevice
        {
            get
            {
                return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
                    Properties.Resources.port.Handle,
                    System.Windows.Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions()
                    );
            }
        }

        /// <summary>
        /// 连接的外部Hub数目
        /// </summary>
        public static Int32 ConnectedHubs = 0;

        /// <summary>
        /// 连接的USB设备数目
        /// </summary>
        public static Int32 ConnectedDevices = 0;

        /// <summary>
        /// 静态根节点
        /// </summary>
        public static List<TreeViewUsbItem> AllUsbDevices
        {
            get
            {
                // 初始化
                ConnectedHubs = 0;      // 连接的外部Hub数目
                ConnectedDevices = 0;   // 连接的USB设备数目

                // 创建根节点
                TreeViewUsbItem Root = new TreeViewUsbItem();
                Root.Icon = ImageComputer;
                Root.Name = "Computer";
                Root.Data = "Machine Name:" + System.Environment.MachineName;

                // 子节点列表
                // 深度遍历主控制器
                HostControllerInfo[] HostControllersCollection = USB.AllHostControllers;
                if (HostControllersCollection != null)
                {
                    List<TreeViewUsbItem> HCNodeCollection = new List<TreeViewUsbItem>(HostControllersCollection.Length);
                    foreach (HostControllerInfo item in HostControllersCollection)
                    {   // 创建主控制器节点
                        TreeViewUsbItem HCNode = new TreeViewUsbItem();

                        HCNode.Icon = ImageHostController;
                        HCNode.Name = item.Name;
                        HCNode.Data = item;

                        // 创建根集线器节点
                        String RootHubPath = USB.GetUsbRootHubPath(item.PNPDeviceID);
                        HCNode.Children = AddHubNode(RootHubPath, "RootHub");

                        HCNodeCollection.Add(HCNode);
                    }

                    Root.Children = HCNodeCollection;
                }

                return new List<TreeViewUsbItem>(1) { Root };
            }
        }

        /// <summary>
        /// Hub节点
        /// </summary>
        /// <param name="HubPath">Hub路径</param>
        /// <param name="HubNodeName">节点显示名称</param>
        /// <returns>Hub节点集合</returns>
        private static List<TreeViewUsbItem> AddHubNode(String HubPath, String HubNodeName)
        {
            UsbNodeInformation[] NodeInfoCollection = USB.GetUsbNodeInformation(HubPath);
            if (NodeInfoCollection != null)
            {
                TreeViewUsbItem HubNode = new TreeViewUsbItem();
                HubNode.Icon = ImageHub;
                if (String.IsNullOrEmpty(NodeInfoCollection[0].Name))
                {
                    HubNode.Name = HubNodeName;
                }
                else
                {
                    HubNode.Name = NodeInfoCollection[0].Name;
                }
                HubNode.Data = NodeInfoCollection[0];

                if (NodeInfoCollection[0].NodeType == USB_HUB_NODE.UsbHub)
                {
                    HubNode.Children = AddPortNode(HubPath, NodeInfoCollection[0].NumberOfPorts);
                }
                else
                {
                    HubNode.Children = null;
                }

                return new List<TreeViewUsbItem>(1) { HubNode };
            }

            return null;
        }

        /// <summary>
        /// Port节点
        /// </summary>
        /// <param name="HubPath">Hub路径</param>
        /// <param name="NumberOfPorts">端口数</param>
        /// <returns>Port节点集合</returns>
        private static List<TreeViewUsbItem> AddPortNode(String HubPath, Int32 NumberOfPorts)
        {
            // 深度遍历端口
            UsbNodeConnectionInformation[] NodeConnectionInfoCollection = USB.GetUsbNodeConnectionInformation(HubPath, NumberOfPorts);
            if (NodeConnectionInfoCollection != null)
            {
                List<TreeViewUsbItem> PortNodeCollection = new List<TreeViewUsbItem>(NumberOfPorts);
                foreach (UsbNodeConnectionInformation NodeConnectionInfo in NodeConnectionInfoCollection)
                {   // 增加端口节点
                    TreeViewUsbItem PortNode = new TreeViewUsbItem();

                    PortNode.Icon = ImageDevice;
                    PortNode.Name = "[Port" + NodeConnectionInfo.ConnectionIndex + "]" + NodeConnectionInfo.ConnectionStatus;
                    PortNode.Data = NodeConnectionInfo;
                    PortNode.Children = null;
                    if (NodeConnectionInfo.ConnectionStatus == USB_CONNECTION_STATUS.DeviceConnected)
                    {
                        // 设备连接
                        ConnectedDevices++; // 连接的USB设备数目
                        if (!String.IsNullOrEmpty(NodeConnectionInfo.DeviceDescriptor.Product))
                        {   // 产品名称
                            PortNode.Name = String.Concat(PortNode.Name, ": ", NodeConnectionInfo.DeviceDescriptor.Product);
                        }

                        if (NodeConnectionInfo.DeviceIsHub)
                        {
                            // 获取外部Hub设备路径
                            String ExternalHubPath = USB.GetExternalHubPath(NodeConnectionInfo.DevicePath, NodeConnectionInfo.ConnectionIndex);
                            UsbNodeInformation[] NodeInfoCollection = USB.GetUsbNodeInformation(ExternalHubPath);
                            if (NodeInfoCollection != null)
                            {
                                PortNode.Icon = ImageHub;
                                PortNode.Data = new ExternalHubInfo { NodeInfo = NodeInfoCollection[0], NodeConnectionInfo = NodeConnectionInfo };
                                if (NodeInfoCollection[0].NodeType == USB_HUB_NODE.UsbHub)
                                {
                                    PortNode.Children = AddPortNode(ExternalHubPath, NodeInfoCollection[0].NumberOfPorts);
                                }

                                if (String.IsNullOrEmpty(NodeConnectionInfo.DeviceDescriptor.Product))
                                {
                                    if (!String.IsNullOrEmpty(NodeInfoCollection[0].Name))
                                    {   // 产品名称
                                        PortNode.Name = String.Concat(PortNode.Name, ": ", NodeInfoCollection[0].Name);
                                    }
                                }
                            }

                            ConnectedHubs++;    // 连接的外部Hub数目
                        }
                    }

                    PortNodeCollection.Add(PortNode);
                }

                return PortNodeCollection;
            }

            return null;
        }
    }
}

USB设备枚举(六)生成ListView数据源

/* ----------------------------------------------------------
文件名称:ListViewUsbItem.cs

作者:秦建辉

MSN:[email protected]
QQ:36748897

博客:http://blog.csdn.net/jhqin

开发环境:
    Visual Studio V2010
    .NET Framework 4 Client Profile

版本历史:
    V1.0    2011年11月08日
            为USB设备枚举信息生成ListView数据源
------------------------------------------------------------ */
using System;
using System.Collections.Generic;
using Splash.IO.PORTS;

namespace WPFUsbView
{
    /// <summary>
    /// TreeView节点对象
    /// </summary>
    internal class ListViewUsbItem
    {
        /// <summary>
        /// USB属性名
        /// </summary>
        public String Name { get; set; }

        /// <summary>
        /// USB属性值
        /// </summary>
        public String Value { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="Name">USB属性名</param>
        /// <param name="Value">USB属性值</param>
        public ListViewUsbItem(String Name, String Value)
        {
            this.Name = Name;
            this.Value = Value;
        }

        /// <summary>
        /// 生成USB属性列表
        /// </summary>
        /// <param name="Data">用于生成列表的USB数据</param>
        /// <returns>属性列表</returns>
        public static List<ListViewUsbItem> UsbDetail(Object Data)
        {
            if (Data is String)
            {   // 机器名
                String Info = Data as String;
                if (!String.IsNullOrEmpty(Info))
                {
                    String[] Content = Info.Split(new Char[] { ‘:‘ });
                    if (Content.Length == 2)
                    {
                        return new List<ListViewUsbItem>(1) { new ListViewUsbItem(Content[0], Content[1]) };
                    }
                }
            }
            else if (Data is HostControllerInfo)
            {   // 主控制器信息
                HostControllerInfo Info = (HostControllerInfo)Data;
                return new List<ListViewUsbItem>(3)
                {
                    new ListViewUsbItem("Name", Info.Name),
                    new ListViewUsbItem("PNPDeviceID", Info.PNPDeviceID),
                    new ListViewUsbItem("HcdDriverKeyName", Info.HcdDriverKeyName)
                };
            }
            else if (Data is UsbNodeInformation)
            {   // USB节点信息
                UsbNodeInformation Info = (UsbNodeInformation)Data;

                List<ListViewUsbItem> Items = new List<ListViewUsbItem>();
                Add(ref Items, Info);
                return Items;
            }
            else if (Data is UsbNodeConnectionInformation)
            {   // USB节点连接信息
                UsbNodeConnectionInformation Info = (UsbNodeConnectionInformation)Data;
                if(Info.ConnectionStatus != USB_CONNECTION_STATUS.DeviceConnected)
                    return null;

                List<ListViewUsbItem> Items = new List<ListViewUsbItem>();
                Add(ref Items, Info);
                return Items;
            }
            else if (Data is ExternalHubInfo)
            {   // 外部Hub信息
                ExternalHubInfo Info = (ExternalHubInfo)Data;

                List<ListViewUsbItem> Items = new List<ListViewUsbItem>();

                // 加入USB节点信息
                Items.Add(new ListViewUsbItem("Node Information:", null));
                Add(ref Items, Info.NodeInfo);

                // 加入USB节点连接信息
                Items.Add(new ListViewUsbItem(null, null));
                Items.Add(new ListViewUsbItem("Node Connection Information:", null));
                Add(ref Items, Info.NodeConnectionInfo);

                return Items;
            }

            return null;
        }

        /// <summary>
        /// 增加USB节点信息
        /// </summary>
        /// <param name="Items">要增加的列表</param>
        /// <param name="Info">要增加的信息</param>
        private static void Add(ref List<ListViewUsbItem> Items, UsbNodeInformation Info)
        {
            if (Info.NodeType == USB_HUB_NODE.UsbHub)
            {
                Items.Add(new ListViewUsbItem("Name", Info.Name));
                Items.Add(new ListViewUsbItem("PNPDeviceID", Info.PNPDeviceID));
                Items.Add(new ListViewUsbItem("DevicePath", Info.DevicePath));
                Items.Add(new ListViewUsbItem("NodeType", Info.NodeType.ToString()));
                Items.Add(new ListViewUsbItem("HubIsBusPowered", Info.HubIsBusPowered.ToString()));
                Items.Add(new ListViewUsbItem("NumberOfPorts", Info.NumberOfPorts.ToString()));
                Items.Add(new ListViewUsbItem("HubCharacteristics", "0x" + Info.HubCharacteristics.ToString("X4")));
                Items.Add(new ListViewUsbItem("PowerOnToPowerGood", (Info.PowerOnToPowerGood * 2).ToString() + "ms"));
                Items.Add(new ListViewUsbItem("HubControlCurrent", Info.HubControlCurrent.ToString()));
            }
            else
            {
                Items.Add(new ListViewUsbItem("Name", Info.Name));
                Items.Add(new ListViewUsbItem("PNPDeviceID", Info.PNPDeviceID));
                Items.Add(new ListViewUsbItem("DevicePath", Info.DevicePath));
                Items.Add(new ListViewUsbItem("NodeType", Info.NodeType.ToString()));
                Items.Add(new ListViewUsbItem("NumberOfInterfaces", Info.NumberOfInterfaces.ToString()));
            }
        }

        /// <summary>
        /// 增加USB节点连接信息
        /// </summary>
        /// <param name="Items">要增加的列表</param>
        /// <param name="Info">要增加的信息</param>
        private static void Add(ref List<ListViewUsbItem> Items, UsbNodeConnectionInformation Info)
        {
            Items.Add(new ListViewUsbItem("DevicePath", Info.DevicePath));
            Items.Add(new ListViewUsbItem("ConnectionIndex", Info.ConnectionIndex.ToString()));
            Items.Add(new ListViewUsbItem("CurrentConfigurationValue", "0x" + Info.CurrentConfigurationValue.ToString("X2")));
            Items.Add(new ListViewUsbItem("Speed", ((USB_DEVICE_SPEED)Info.Speed).ToString()));
            Items.Add(new ListViewUsbItem("DeviceIsHub", Info.DeviceIsHub.ToString()));
            Items.Add(new ListViewUsbItem("DeviceAddress", Info.DeviceAddress.ToString()));
            Items.Add(new ListViewUsbItem("NumberOfOpenPipes", Info.NumberOfOpenPipes.ToString()));

            // 设备描述符
            Items.Add(new ListViewUsbItem(null, null));
            Items.Add(new ListViewUsbItem("Device Descriptor:", null));
            Items.Add(new ListViewUsbItem("DescriptorType", "0x" + Info.DeviceDescriptor.bDescriptorType.ToString("X2")));
            Items.Add(new ListViewUsbItem("UsbVersion", Info.DeviceDescriptor.UsbVersion));
            Items.Add(new ListViewUsbItem("DeviceClass", "0x" + Info.DeviceDescriptor.bDeviceClass.ToString("X2")));
            Items.Add(new ListViewUsbItem("DeviceSubClass", "0x" + Info.DeviceDescriptor.bDeviceSubClass.ToString("X2")));
            Items.Add(new ListViewUsbItem("DeviceProtocol", "0x" + Info.DeviceDescriptor.bDeviceProtocol.ToString("X2")));
            Items.Add(new ListViewUsbItem("MaxPacketSize0", Info.DeviceDescriptor.bMaxPacketSize0.ToString()));
            Items.Add(new ListViewUsbItem("idVendor", "0x" + Info.DeviceDescriptor.idVendor.ToString("X4")));
            Items.Add(new ListViewUsbItem("idProduct", "0x" + Info.DeviceDescriptor.idProduct.ToString("X4")));
            Items.Add(new ListViewUsbItem("DeviceVersion", Info.DeviceDescriptor.DeviceVersion));
            Items.Add(new ListViewUsbItem("Manufacturer", Info.DeviceDescriptor.Manufacturer));
            Items.Add(new ListViewUsbItem("Product", Info.DeviceDescriptor.Product));
            Items.Add(new ListViewUsbItem("SerialNumber", Info.DeviceDescriptor.SerialNumber));
            Items.Add(new ListViewUsbItem("NumConfigurations", Info.DeviceDescriptor.bNumConfigurations.ToString()));

            // 管道信息
            foreach (UsbPipeInfo Pipe in Info.PipeList)
            {
                Items.Add(new ListViewUsbItem(null, null));
                Items.Add(new ListViewUsbItem("Endpoint Descriptor:", null));
                Items.Add(new ListViewUsbItem("ScheduleOffset", Pipe.ScheduleOffset.ToString()));
                Items.Add(new ListViewUsbItem("DescriptorType", "0x" + Pipe.bDescriptorType.ToString("X2")));
                Items.Add(new ListViewUsbItem("EndpointAddress", "0x" + Pipe.bEndpointAddress.ToString("X2")));
                Items.Add(new ListViewUsbItem("bmAttributes", "0x" + Pipe.bmAttributes.ToString("X2")));
                Items.Add(new ListViewUsbItem("MaxPacketSize", Pipe.wMaxPacketSize.ToString()));
                Items.Add(new ListViewUsbItem("Interval", "0x" + Pipe.bInterval.ToString("X2")));
            }
        }
    }
}

USB设备枚举(七)WPF扩展方法

/* ----------------------------------------------------------
文件名称:WPFExtensions.cs

作者:秦建辉

MSN:[email protected]
QQ:36748897

博客:http://blog.csdn.net/jhqin

开发环境:
    Visual Studio V2010
    .NET Framework 4 Client Profile

版本历史:
    V1.1    2011年11月07日
            实现扩展方法:WPF中TreeView类的ExpandAll功能

    V1.0    2011年11月03日
            实现扩展方法:WPF中Button类的PerformClick功能
------------------------------------------------------------ */
using System.Windows.Controls;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;

namespace Splash.WPF
{
    /// <summary>
    /// 扩展方法
    /// </summary>
    public static partial class Extensions
    {
        /// <summary>
        /// 扩展方法:实现WPF中Button类的PerformClick功能
        /// </summary>
        /// <param name="button">Button实例</param>
        /// <remarks>
        /// 需要添加对UIAutomationProvider.dll的引用
        /// 参考网址:http://www.cnblogs.com/zhouyinhui/archive/2010/05/20/1740111.html
        /// </remarks>
        public static void PerformClick(this Button button)
        {
            ButtonAutomationPeer BAP = new ButtonAutomationPeer(button);
            IInvokeProvider IIP = BAP.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
            if (IIP != null)
            {
                IIP.Invoke();
            }
        }

        /// <summary>
        /// 扩展方法:实现WPF中TreeView类的ExpandAll功能
        /// </summary>
        /// <param name="treeView">要展开的TreeView实例</param>
        /// <remarks>
        /// 参考网址:http://www.cnblogs.com/sayo/archive/2008/07/23/1249804.html
        /// </remarks>
        public static void ExpandAll(this TreeView treeView)
        {
            ExpandSubItems(treeView as ItemsControl);
        }

        private static void ExpandSubItems(ItemsControl control)
        {
            if (control == null) return;
            foreach (object item in control.Items)
            {
                TreeViewItem treeItem = control.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
                if (treeItem != null && treeItem.HasItems)
                {
                    treeItem.IsExpanded = true;
                    ExpandSubItems(treeItem as ItemsControl);
                }
            }
        }
    }
}

(八)创建基于WPF的USB设备浏览器

软件界面:

下载地址(包含产品及源代码):

微软SkyDrive下载链接:WPFUsbView.zip

CSDN下载页面:http://download.csdn.net/detail/jhqin/3773593

源代码:

MainWindow.xaml

<Window x:Class="WPFUsbView.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:usb="clr-namespace:WPFUsbView"
        Title="USB Device Viewer" Height="600" Width="800" Icon="/WPFUsbView;component/images/usb.ico" WindowStyle="ThreeDBorderWindow" WindowStartupLocation="CenterScreen" Loaded="Window_Loaded" WindowState="Maximized">
    <Window.Resources>
        <Style TargetType="TreeViewItem">
            <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeViewItem}}}" />
        </Style>
    </Window.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>

        <Grid Grid.Row="0" Background="CadetBlue">
            <ToolBar Height="40" Width="Auto" HorizontalAlignment="Left" Background="CadetBlue">
                <Button Margin="4,0" Name="buttonRefresh" Click="buttonRefresh_Click">
                    <Image Source="/WPFUsbView;component/images/refresh.png"></Image>
                </Button>
                <Button Margin="4,0" Name="buttonOpenXML" Click="buttonOpenXML_Click">
                    <Image Source="/WPFUsbView;component/images/XML.png"></Image>
                </Button>
                <Button Margin="4,0" Name="buttonInfo" Click="buttonInfo_Click">
                    <Image Source="/WPFUsbView;component/images/Info.png"></Image>
                </Button>
            </ToolBar>
        </Grid>   

        <Grid Grid.Row="1" Name="gridDetail">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="4*"></ColumnDefinition>
                <ColumnDefinition Width="Auto"></ColumnDefinition>
                <ColumnDefinition Width="6*"></ColumnDefinition>
            </Grid.ColumnDefinitions>

            <TreeView Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top" Name="treeView1" FontSize="16" SelectedItemChanged="treeView1_SelectedItemChanged">
                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate DataType="{x:Type usb:TreeViewUsbItem}" ItemsSource="{Binding Path=Children}">
                        <StackPanel Orientation="Horizontal">
                            <Image VerticalAlignment="Center" Source="{Binding Icon}" Width="16" Height="16" Margin="0,0,2,2"></Image>
                            <TextBlock VerticalAlignment="Center" Text="{Binding Name}"></TextBlock>
                        </StackPanel>
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>
            </TreeView>

            <GridSplitter Grid.Column="1" Width="13" HorizontalAlignment="Center" VerticalAlignment="Stretch" LayoutUpdated="GridSplitter_LayoutUpdated">
                <GridSplitter.Background>
                    <ImageBrush ImageSource="/WPFUsbView;component/images/SplitLine.png" Stretch="UniformToFill" TileMode="Tile" Viewport="0,0,15,500" ViewportUnits="Absolute" />
                </GridSplitter.Background>
            </GridSplitter>

            <ListView Grid.Column="2" Name="listView1" FontSize="16">
                <ListView.ItemTemplate>
                    <DataTemplate DataType="{x:Type usb:ListViewUsbItem}">
                        <StackPanel Orientation="Horizontal" Margin="0,2">
                            <TextBlock Width="250" Text="{Binding Name}"></TextBlock>
                            <TextBlock Width="Auto" Text="{Binding Value}" Foreground="Blue"></TextBlock>
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Grid>

        <StatusBar Grid.Row="2" Height="32" Background="SteelBlue">
            <StatusBarItem>
                <Image Source="/WPFUsbView;component/images/usbdevice.png"></Image>
            </StatusBarItem>
            <StatusBarItem>
                <TextBlock FontSize="16" Foreground="Brown" Name="textBlockUsbDevice">0</TextBlock>
            </StatusBarItem>
            <StatusBarItem>
                <Image Source="/WPFUsbView;component/images/usb-hub.png"></Image>
            </StatusBarItem>
            <StatusBarItem>
                <TextBlock FontSize="16" Foreground="Brown" Name="textBlockUsbHub">0</TextBlock>
            </StatusBarItem>
        </StatusBar>
    </Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.IO;
using System.Windows;
using Splash.IO.PORTS;
using Splash.WPF;

namespace WPFUsbView
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        // 枚举设备信息并输出到XML文档
        private void buttonOpenXML_Click(object sender, RoutedEventArgs e)
        {
            String xmlFile = "UsbEnums.xml";
            try
            {   // 检测当前目录下是否可以创建文件
                using (StreamWriter sw = new StreamWriter(xmlFile))
                {
                    sw.Close();
                }
            }
            catch(Exception)
            {   // 当前目录无法创建文件,改到我的文档目录下
                xmlFile = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\" + xmlFile;
            }

            if (USB.EnumUsbToXML(xmlFile))
            {   // 判断文件是否存在
                if (System.IO.File.Exists(xmlFile))
                {   // 打开文件
                    Splash.Diagnostics.Extensions.ShellExecute(xmlFile);
                    return;
                }
            }

            MessageBox.Show("Failed!");
            return;
        }

        // 更新设备枚举信息
        private void buttonRefresh_Click(object sender, RoutedEventArgs e)
        {
            // 枚举USB设备信息
            treeView1.ItemsSource = TreeViewUsbItem.AllUsbDevices;

            // 展开所有分支
            treeView1.ExpandAll();  

            // 设备连接数
            textBlockUsbDevice.Text = TreeViewUsbItem.ConnectedDevices.ToString();

            // 外部Hub连接数
            textBlockUsbHub.Text = TreeViewUsbItem.ConnectedHubs.ToString();
        }

        // 显示软件版本信息
        private void buttonInfo_Click(object sender, RoutedEventArgs e)
        {
            About AboutWindow = new About();
            AboutWindow.Owner = this;
            AboutWindow.ShowDialog();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // 显示USB设备枚举信息
            buttonRefresh.PerformClick();
        }

        // 更新布局,调整各控件大小
        private void GridSplitter_LayoutUpdated(object sender, EventArgs e)
        {
            // 设置TreeView的宽度和高度
            treeView1.Width = gridDetail.ColumnDefinitions[0].ActualWidth;
            treeView1.Height = gridDetail.ActualHeight;
        }

        private void treeView1_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            TreeViewUsbItem Node = e.NewValue as TreeViewUsbItem;
            if (Node != null)
            {
                listView1.ItemsSource = ListViewUsbItem.UsbDetail(Node.Data);
            }
        }
    }
}
时间: 2024-10-06 00:15:58

C#:USB设备枚举 --转自CSDN作者:Splash的相关文章

C#USB设备枚举Kernel32的PInvoke

using System; using System.Runtime.InteropServices; using System.Security; namespace Splash { #region Kernel32 [SuppressUnmanagedCodeSecurity] internal static class Kernel32 { /// <summary> /// 无效的文件句柄 /// </summary> public static readonly Int

USB设备驱动之设备初始化(设备枚举)

USB设备从接入HUB到正常工作之前,都属于设备枚举阶段.所谓设备枚举,就是让host控制器认识USB设备,并为其准备资源,建立好主机与设备间的数据传递机制. 该阶段的工作,是USB通信协议规定的,所以属于ISO标准流程.设备枚举阶段也对应了USB设备的五种状态. 设备枚举阶段分为如下8个步骤: 获取设备描述符 复位 设置地址 再次获取设备描述符 获取配置描述符 获取接口,端点描述符 获取字符串描述符 选择设置配置 其中,步骤1与4都是获取设备描述符,两者有什么区别? 步骤1中只取得设备描述符的

USB协议-USB设备的枚举过程

USB主机在检测到USB设备插入后,就要对设备进行枚举了.为什么要枚举?枚举就是从设备读取各种描述符信息,这样主机就可以根据这些信息来加载合适的驱动程序,从而知道设备是什么样的设备,如何进行通信等. 枚举的过程: 1.  USB主机检测到USB设备插入之后,就会先对设备复位.USB设备在总线复位后其地址为0,这样主机就可以通过地址0和那些刚刚插入的设备通信.USB主机往地址为0的设备的端点0发送获取设备描述符的标准请求(这是一个控制传输的建立过程).设备收到该请求后,会按照主机请求的参数,在数据

浅析USB之设备枚举

当一个USB设备插入主机后,会有以下活动: 配上状态图

C#:基于WMI查询USB设备

来源:http://blog.csdn.net/jhqin/article/details/6734673 /* ---------------------------------------------------------- 文件名称:WMIUsbQuery.cs 作者:秦建辉 MSN:[email protected] QQ:36748897 博客:http://blog.csdn.net/jhqin 开发环境: Visual Studio V2010 .NET Framework 4

USB设备驱动开发之远程访问USB设备(一)

By Fanxiushu 2016 05-15  转载或引用本文,请注明原始作者. 使用过vmware的人都应该知道,vmware虚拟机有这样的一个功能, 当在宿主机上插入一个USB设备的时候,通过设置,可以在vmware的虚拟机系统里边能访问到这个USB设备, 而且访问这个USB设备,就跟真的把这个USB设备插入到这个虚拟系统中一样,跟真实的几乎没任何区别. 再看一种情况,假设有两台机器C和S,C 机器是你正在使用的机器, S机器在远端,你只能通过远程控制S. S机器的配置和功能都很强大,大部

USB设备驱动开发之远程访问USB设备(二 USB设备虚拟端)

By Fanxiushu 2016-05-22 转载或引用请注明原始作者 接上文, 在处理好USB数据采集端的问题之后,接下来进入核心的部分,虚拟USB设备端的开发工作. 上文简单介绍过,需要开发虚拟总线驱动来模拟USB设备. 所谓虚拟总线驱动,就是安装于System系统设备下的一个驱动,由PnP管理器创建出一个虚拟的总线PDO设备, 我们的虚拟总线驱动Attach到这个PDO上,形成一个FDO功能设备驱动, 然后在我们的驱动中,根据需要创建出若干个 Child PDO设备, 这些 Child

Bus Hound抓包分析,USB设备识别为HID(转)

Device:17.0  ——  表示ID为17的设备的0号端点 Phase:阶段列 Cmd.phase.ofs:命令数.阶段数.每个阶段中字节的偏移量 CTL:表示8字节的USB控制传输的Setup包 bmRequestType  ——  80:数据方向从USB到PC:标准的请求:USB设备接收 bRequest  ——  06:表示接下来发送的数据时GET_DESCRIPTOR(主控器读取USB描述符) wValue  ——  00 01:从偏移地址0开始读取设备描述符 wIndex  ——

Linux下 USB设备驱动分析(原创)

之前做过STM32的usb HID复合设备,闲来看看linux下USB设备驱动是怎么一回事, 参考资料基于韦东山JZ2440开发板,以下,有错误欢迎指出. 1.准备知识 1.1USB相关概念: USB枚举过程:https://blog.csdn.net/go_str/article/details/80802452 USB其它概念: (1)usb是主从结构,usb的传输都是主机发起: (2)usb右四种传输类型:控制.批量.中断.实时传输. (3)usb数据是通过端点进行通讯的,0端点既能输入也