标签:
原文:C#与USB HID间的通信
			
C#与USBHID接口的通讯相对于与串口间的通讯较为复杂,其中需要多次调用到Windows的一些API。其原理编者尚未全部理清,以下提供简单的USBHID通讯流程。(参考网友资料)
一、获取所有连接HID的设备信息。
1.通过一个空的GUID来获取HID的全局GUID。
Guid 
HIDGuid = Guid.Empty;
       
///
       
/// The
HidD_GetHidGuid routine returns the device interface GUID for
HIDClass devices.
       
///
       
/// a
caller-allocated GUID buffer that the routine uses to return the
device interface GUID for HIDClass devices.
       
[DllImport("hid.dll")]
       
private static extern
void HidD_GetHidGuid(ref Guid
HidGuid);
 
2.通过获取到的HID全局GUID来获取包含所有HID接口信息集合的句柄。
IntPtr 
HIDInfoSet= SetupDiGetClassDevs(ref HIDGuid,0,IntPtr.Zero,DIGCF.DIGCF_PRESENT|DIGCF.DIGCF_DEVICEINTERFACE);
 
       
///
       
/// The
SetupDiGetClassDevs function returns a handle to a device
information set that contains requested device information elements
for a local machine.
       
///
       
/// GUID
for a device setup class or a device interface
class.
       
/// A
pointer to a NULL-terminated string that supplies the name of a PnP
enumerator or a PnP device instance identifier.
       
/// A
handle of the top-level window to be used for a user
interface
       
/// A
variable  that specifies control options that
filter the device information elements that are added to the device
information set.
       
///
       
/// a
handle to a device information set
       
[DllImport("setupapi.dll", SetLastError = true)]
       
private static extern
IntPtr
SetupDiGetClassDevs(ref
Guid ClassGuid, uint Enumerator, IntPtr HwndParent, USBHIDEnum.DIGCF Flags);
相关枚举:
       
public enum DIGCF
       
{
           
DIGCF_DEFAULT = 0x00000001,             
           
DIGCF_PRESENT = 0x00000002,
           
DIGCF_ALLCLASSES = 0x00000004,
           
DIGCF_PROFILE = 0x00000008,
           
DIGCF_DEVICEINTERFACE = 0x00000010
       
}
 
3.获取接口信息。
       
///
       
/// The
SetupDiEnumDeviceInterfaces function enumerates the device
interfaces that are contained in a device information
set.
       
///
       
/// A
pointer to a device information set that contains the device
interfaces for which to return information
       
/// A
pointer to an SP_DEVINFO_DATA structure that specifies a device
information element in DeviceInfoSet
       
/// a
GUID that specifies the device interface class for the requested
interface
       
/// A
zero-based index into the list of interfaces in the device
information set
       
/// a
caller-allocated buffer that contains a completed
SP_DEVICE_INTERFACE_DATA structure that identifies an interface
that meets the search parameters
       
///
       
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
       
private static extern
Boolean
SetupDiEnumDeviceInterfaces(IntPtr deviceInfoSet, IntPtr deviceInfoData, ref Guid
interfaceClassGuid, UInt32
memberIndex, ref DEVICE_INTERFACE_DATA
deviceInterfaceData);
接口信息定义为:
       
public struct DEVICE_INTERFACE_DATA
       
{
           
public int cbSize;
           
public Guid interfaceClassGuid;
           
public int flags;
           
public int reserved;
       
}
 
4.获取接口详细信息,在第一次主要是读取缓存信息
int 
requiredSize =0;
 
       
///
       
/// The
SetupDiGetDeviceInterfaceDetail function returns details about a
device interface.
       
///
       
/// A
pointer to the device information set that contains the interface
for which to retrieve details
       
/// A
pointer to an SP_DEVICE_INTERFACE_DATA structure that specifies the
interface in DeviceInfoSet for which to retrieve
details
       
/// A
pointer to an SP_DEVICE_INTERFACE_DETAIL_DATA structure to receive
information about the specified interface
       
/// The
size of the DeviceInterfaceDetailData buffer
       
/// A
pointer to a variable that receives the required size of the
DeviceInterfaceDetailData buffer
       
/// A
pointer buffer to receive information about the device that
supports the requested interface
       
///
       
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
       
private static extern
bool
SetupDiGetDeviceInterfaceDetail(IntPtr deviceInfoSet, ref DEVICE_INTERFACE_DATA deviceInterfaceData,
IntPtr
deviceInterfaceDetailData, int
deviceInterfaceDetailDataSize, ref
int requiredSize, DEVINFO_DATA deviceInfoData);
接口信息定义:
       
[StructLayout(LayoutKind.Sequential)]
       
public class DEVINFO_DATA
       
{
           
public int cbSize = Marshal.SizeOf(typeof(DEVINFO_DATA));
           
public Guid classGuid = Guid.Empty;           
public 
int devInst = 0;
           
public int reserved = 0;
       
}
5.第二次获取详细信息,与第一相同。
若Windows
API SetupDiGetDeviceInterfaceDetail返回数值为true则添加设备信息
ListdeviceList=new List();
deviceList.Add(Marshal.PtrToStringAuto((IntPtr)((int)pDetail + 4)));
 
6.删除设备信息并释放内存。
       
///
       
/// The
SetupDiDestroyDeviceInfoList function deletes a device information
set and frees all associated memory.
       
///
       
/// A
handle to the device information set to delete.
       
/// returns TRUE if it is successful. Otherwise, it
returns FALSE
       
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
       
private static extern
Boolean
SetupDiDestroyDeviceInfoList(IntPtr HIDInfoSet);
到此便获取到所有的设备。
 
二、通过获取到的设备信息打开指定的HID设备。
1.创建,打开设备信息。
       
///
       
/// This
function creates, opens, or truncates a file, COM port, device,
service, or console.
       
///
       
/// a
null-terminated string that specifies the name of the
object
       
/// Type
of access to the object
       
/// Share
mode for object
       
/// Ignored; set to NULL
       
/// Action to take on files that exist, and which action
to take when files do not exist
       
/// File
attributes and flags for the file
       
/// Ignored
       
/// An
open handle to the specified file indicates
success
       
[DllImport("kernel32.dll", SetLastError = true)]
       
//private static extern IntPtr
CreateFile(string fileName, uint desiredAccess, uint shareMode,
uint securityAttributes, uint creationDisposition, uint
flagsAndAttributes, uint templateFile);
       
static extern IntPtr CreateFile(
      
string
FileName,               
// 
文件名
      
uint
DesiredAccess,            
// 
访问模式
      
uint
ShareMode,                
// 
共享模式
      
uint
SecurityAttributes,       
// 
安全属性
      
uint
CreationDisposition,      
// 
如何创建
      
uint
FlagsAndAttributes,       
// 
文件属性
      
int
hTemplateFile              
// 
模板文件的句柄
      
);
其中文件名为相对应的设备名deviceList[index]
2.获取设备属性
       
///
       
/// The
HidD_GetAttributes routine returns the attributes of a specified
top-level collection.
       
///
       
/// Specifies an open handle to a top-level
collection
       
/// a
caller-allocated HIDD_ATTRIBUTES structure that returns the
attributes of the collection specified by
HidDeviceObject
       
///
       
[DllImport("hid.dll")]
       
private static extern
Boolean
HidD_GetAttributes(IntPtr
hidDevice, out HID_ATTRIBUTES attributes);
相关HID属性:
    public struct
HID_ATTRIBUTES
    {
       
public int Size;
       
public ushort VendorID;
       
public ushort ProductID;
       
public ushort VersionNumber;
    }
3.Get PreparsedData
       
///
       
/// The
HidD_GetPreparsedData routine returns a top-level collection‘s
preparsed data.
       
///
       
/// Specifies an open handle to a top-level
collection.
       
/// Pointer to the address of a routine-allocated buffer
that contains a collection‘s preparsed data in a
_HIDP_PREPARSED_DATA structure.
       
/// HidD_GetPreparsedData returns TRUE if it succeeds;
otherwise, it returns FALSE.
       
[DllImport("hid.dll")]
       
private static extern
Boolean
HidD_GetPreparsedData(IntPtr
hidDeviceObject, out IntPtr PreparsedData);
4. GetCaps
       
[DllImport("hid.dll")]
       
private static extern
uint HidP_GetCaps(IntPtr PreparsedData, out HIDP_CAPS Capabilities);
5. FreePreparsedData
       
[DllImport("hid.dll")]
       
private static extern
Boolean
HidD_FreePreparsedData(IntPtr
PreparsedData);
6.获取长度:
           
outputReportLength = caps.OutputReportByteLength;
           
inputReportLength = caps.InputReportByteLength;
7.最终得到相应的设备
hidDevice = new FileStream(new SafeFileHandle(device, false), FileAccess.ReadWrite, inputReportLength,
true);
三、设备读取,写入
通过最终获取到的设备可对设备进行读取和写入。
BeginRead,Read,Write,BeginWrite等。
 
以上便能实现对想要的USBHID设备进行简单的操作。
简单串口例子: http://blog.sina.com.cn/s/blog_6267db160102v53m.html
示例代码下载地址:http://download.csdn.net/detail/zhezizhang/8155795
C#与USB HID间的通信
标签:
原文地址:http://www.cnblogs.com/lonelyxmas/p/5387916.html