同系列文章:
EZUSB核心源代码出售:
价格:壹仟圆人民币
微信:splashcn
演示程序功能说明:
C#语言实现的Usbview.exe,让你浏览电脑上所有的USB控制器和其连接的USB设备,并可导出xml文件。
演示程序下载:
源代码:
TreeViewUsbItem.cs
/* ---------------------------------------------------------- * 文件名称:TreeViewUsbItem.cs * * 作者:秦建辉 * * 微信:splashcn * * 博客: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 Com.FirstSolver.USB; using System; using System.Collections.Generic; using System.Windows.Media; using System.Windows.Media.Imaging; 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 int ConnectedHubs = 0; /// <summary> /// 连接的USB设备数目 /// </summary> public static int 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 = EZUSB.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 = EZUSB.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 = EZUSB.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, int NumberOfPorts) { // 深度遍历端口 UsbNodeConnectionInformation[] NodeConnectionInfoCollection = EZUSB.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 = EZUSB.GetExternalHubPath(NodeConnectionInfo.DevicePath, NodeConnectionInfo.ConnectionIndex); UsbNodeInformation[] NodeInfoCollection = EZUSB.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; } } }
ListViewUsbItem.cs
/* ---------------------------------------------------------- * 文件名称:ListViewUsbItem.cs * * 作者:秦建辉 * 微信:splashcn * * 博客:http://www.firstsolver.com/wordpress/ * * 开发环境: * Visual Studio V2010 * .NET Framework 4 Client Profile * * 版本历史: * V1.0 2011年11月08日 * 为USB设备枚举信息生成ListView数据源 * ------------------------------------------------------------ */ using Com.FirstSolver.USB; using System; using System.Collections.Generic; 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"))); } } } }
MainWindow.xaml.cs
using Com.FirstSolver.USB; using Splash.WPF; using System; using System.IO; using System.Windows; 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 = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments) + "\\" + xmlFile; } if (EZUSB.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); } } } }
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>