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

时间:2022-05-23 05:13:28

(一)DeviceIoControl的PInvoke

/* ----------------------------------------------------------
文件名称:DeviceIoControl.cs 作者:秦建辉 MSN:splashcn@msn.com
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 = ;
internal const Int32 USB_STRING_DESCRIPTOR_TYPE = ; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct USB_HCD_DRIVERKEY_NAME
{
public Int32 ActualLength;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
public String Name;
} #region USB_NODE_INFORMATION
[StructLayout(LayoutKind.Sequential, Pack = )]
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 = )]
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()]
public USB_HUB_INFORMATION HubInformation;
[FieldOffset()]
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 = )]
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 = )]
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 = )]
internal struct USB_PIPE_INFO
{
public USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
public UInt32 ScheduleOffset;
} [StructLayout(LayoutKind.Sequential, Pack = )]
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 = )]
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:splashcn@msn.com
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 == ) 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,
,
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 == ) 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,
,
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(, 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(, 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[] { 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 = ; 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 != )
{
if (Buffer.DeviceDescriptor.iSerialNumber != )
{ // 序列号
Node.DeviceDescriptor.SerialNumber = GetStringDescriptor(hHubDevice,
Buffer.ConnectionIndex,
Buffer.DeviceDescriptor.iSerialNumber,
LanguageID);
} if (Buffer.DeviceDescriptor.iManufacturer != )
{ // 制造商名称
Node.DeviceDescriptor.Manufacturer = GetStringDescriptor(hHubDevice,
Buffer.ConnectionIndex,
Buffer.DeviceDescriptor.iManufacturer,
LanguageID);
} if (Buffer.DeviceDescriptor.iProduct != )
{ // 产品名称
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 = ; 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 == )
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 << ) | 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, , );
if(String.IsNullOrEmpty(SupportedLanguagesString))return ; UInt16 UserDefaultUILanguage = Splash.Environment.UserDefaultUILanguage;
if(SupportedLanguagesString.IndexOf(Convert.ToChar(UserDefaultUILanguage)) != -)
{ // 用户缺省界面语言
return UserDefaultUILanguage;
}
else if(SupportedLanguagesString.IndexOf(Convert.ToChar(0x0409)) != -)
{ // 美国英语 0x0409
return 0x0409;
}
else
{ // 第一个可选择的LANGID
return Convert.ToUInt16(SupportedLanguagesString[]);
}
}
#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 <= ) 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(); // 主版本号
Int32 BIT4 = (bcd >> ) & 0x0F;
if (BIT4 != ) sb.Append(BIT4.ToString()); BIT4 = (bcd >> ) & 0x0F;
sb.Append(BIT4.ToString()); sb.Append("."); // 子版本号
BIT4 = (bcd >> ) & 0x0F;
sb.Append(BIT4.ToString()); BIT4 = bcd & 0x0F;
if (BIT4 != ) sb.Append(BIT4.ToString()); return sb.ToString();
}
#endregion
}
}

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

/* ----------------------------------------------------------
文件名称:UsbEnumXML.cs 作者:秦建辉 MSN:splashcn@msn.com
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 = ;
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[].NodeType;
XElement HubNode = new XElement(HubNodeName,
new XAttribute("Name", NodeInfoCollection[].Name),
new XAttribute("PNPDeviceID", NodeInfoCollection[].PNPDeviceID),
new XAttribute("Path", NodeInfoCollection[].DevicePath),
new XAttribute("NodeType", NodeType)
); if (NodeType == USB_HUB_NODE.UsbHub)
{
Int32 NumberOfPorts = NodeInfoCollection[].NumberOfPorts;
HubNode.Add(new XAttribute("NumberOfPorts", NumberOfPorts),
new XAttribute("HubIsBusPowered", NodeInfoCollection[].HubIsBusPowered),
new XAttribute("HubCharacteristics", "0x" + NodeInfoCollection[].HubCharacteristics.ToString("X4")),
new XAttribute("PowerOnToPowerGood", NodeInfoCollection[].PowerOnToPowerGood),
new XAttribute("HubControlCurrent", NodeInfoCollection[].HubControlCurrent)
); // 深度遍历端口
UsbNodeConnectionInformation[] NodeConnectionInfoCollection = USB.GetUsbNodeConnectionInformation(HubPath, NumberOfPorts);
if (NodeConnectionInfoCollection != null)
{
foreach (UsbNodeConnectionInformation NodeConnectionInfo in NodeConnectionInfoCollection)
{ // 增加端口节点
AddPortNode(HubNode, NodeConnectionInfo);
}
}
}
else
{
HubNode.Add("NumberOfInterfaces", NodeInfoCollection[].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 != )
{
DeviceDescriptorNode.Add(new XAttribute("idVendor", "0x" + DeviceDescriptor.idVendor.ToString("X4")));
} if (DeviceDescriptor.idProduct != )
{
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 = ;
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:splashcn@msn.com
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(-); #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 = ,
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 =
} internal enum NativeFileMode : uint
{
CREATE_NEW = ,
CREATE_ALWAYS = ,
OPEN_EXISTING = ,
OPEN_ALWAYS = ,
TRUNCATE_EXISTING = ,
} [Flags]
internal enum NativeFileShare : uint
{
NONE = ,
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 = ; /// <summary>
/// 连接的USB设备数目
/// </summary>
public static Int32 ConnectedDevices = ; /// <summary>
/// 静态根节点
/// </summary>
public static List<TreeViewUsbItem> AllUsbDevices
{
get
{
// 初始化
ConnectedHubs = ; // 连接的外部Hub数目
ConnectedDevices = ; // 连接的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>() { 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[].Name))
{
HubNode.Name = HubNodeName;
}
else
{
HubNode.Name = NodeInfoCollection[].Name;
}
HubNode.Data = NodeInfoCollection[]; if (NodeInfoCollection[].NodeType == USB_HUB_NODE.UsbHub)
{
HubNode.Children = AddPortNode(HubPath, NodeInfoCollection[].NumberOfPorts);
}
else
{
HubNode.Children = null;
} return new List<TreeViewUsbItem>() { 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[], NodeConnectionInfo = NodeConnectionInfo };
if (NodeInfoCollection[].NodeType == USB_HUB_NODE.UsbHub)
{
PortNode.Children = AddPortNode(ExternalHubPath, NodeInfoCollection[].NumberOfPorts);
} if (String.IsNullOrEmpty(NodeConnectionInfo.DeviceDescriptor.Product))
{
if (!String.IsNullOrEmpty(NodeInfoCollection[].Name))
{ // 产品名称
PortNode.Name = String.Concat(PortNode.Name, ": ", NodeInfoCollection[].Name);
}
}
} ConnectedHubs++; // 连接的外部Hub数目
}
} PortNodeCollection.Add(PortNode);
} return PortNodeCollection;
} return null;
}
}
}

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

/* ----------------------------------------------------------
文件名称:ListViewUsbItem.cs 作者:秦建辉 MSN:splashcn@msn.com
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 == )
{
return new List<ListViewUsbItem>() { new ListViewUsbItem(Content[], Content[]) };
}
}
}
else if (Data is HostControllerInfo)
{ // 主控制器信息
HostControllerInfo Info = (HostControllerInfo)Data;
return new List<ListViewUsbItem>()
{
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 * ).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:splashcn@msn.com
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设备浏览器

软件界面:

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

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

微软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="" Width="" 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="" Background="CadetBlue">
<ToolBar Height="" 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="" Name="gridDetail">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="6*"></ColumnDefinition>
</Grid.ColumnDefinitions> <TreeView Grid.Column="" HorizontalAlignment="Left" VerticalAlignment="Top" Name="treeView1" FontSize="" 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="" Height="" Margin="0,0,2,2"></Image>
<TextBlock VerticalAlignment="Center" Text="{Binding Name}"></TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView> <GridSplitter Grid.Column="" Width="" 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="" Name="listView1" FontSize="">
<ListView.ItemTemplate>
<DataTemplate DataType="{x:Type usb:ListViewUsbItem}">
<StackPanel Orientation="Horizontal" Margin="0,2">
<TextBlock Width="" Text="{Binding Name}"></TextBlock>
<TextBlock Width="Auto" Text="{Binding Value}" Foreground="Blue"></TextBlock>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid> <StatusBar Grid.Row="" Height="" Background="SteelBlue">
<StatusBarItem>
<Image Source="/WPFUsbView;component/images/usbdevice.png"></Image>
</StatusBarItem>
<StatusBarItem>
<TextBlock FontSize="" Foreground="Brown" Name="textBlockUsbDevice"></TextBlock>
</StatusBarItem>
<StatusBarItem>
<Image Source="/WPFUsbView;component/images/usb-hub.png"></Image>
</StatusBarItem>
<StatusBarItem>
<TextBlock FontSize="" Foreground="Brown" Name="textBlockUsbHub"></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[].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);
}
}
}
}