C#与USB HID间的通信

简介: 原文:C#与USB HID间的通信 C#与USBHID接口的通讯相对于与串口间的通讯较为复杂,其中需要多次调用到Windows的一些API。其原理编者尚未全部理清,以下提供简单的USBHID通讯流程。
原文: 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);

三、设备读取,写入

通过最终获取到的设备可对设备进行读取和写入。

BeginReadReadWriteBeginWrite等。

 

以上便能实现对想要的USBHID设备进行简单的操作。

简单串口例子: http://blog.sina.com.cn/s/blog_6267db160102v53m.html

示例代码下载地址:http://download.csdn.net/detail/zhezizhang/8155795

目录
相关文章
|
1月前
|
数据处理 C# C++
如何使用C#和C++结构体实现Socket通信
如何使用C#和C++结构体实现Socket通信
|
4月前
|
C#
C# | 极简代码实现串口通信,功能超丰富 (使用BytesIO通信库)
C# 极简代码实现串口通信,功能超丰富 安装NuGet库 程序截图 事件监听 设计及实现 界面 代码 源码下载
62 0
C# | 极简代码实现串口通信,功能超丰富 (使用BytesIO通信库)
|
4月前
|
传感器 监控 网络协议
C# | 上位机开发新手指南(二)上位机通信
在上位机开发中,串口通信和TCP通信是两种常见的通信方式。串口通信是指通过串口将数据发送和接收到控制器或其他外设中,TCP通信则是通过网络将数据传输到远程设备中。下面介绍一下为什么学习串口通信和TCP通信在上位机开发中是很重要的。
163 0
C# | 上位机开发新手指南(二)上位机通信
|
4月前
|
C#
C# | 使用AutoResetEvent和ManualResetEvent进行线程同步和通信
在多线程编程中,AutoResetEvent 和 ManualResetEvent 是两个常用的同步原语。它们用于线程间的通信和协调,以确保线程按照特定的顺序执行。本篇博客将介绍这两种同步原语的概念、用法和区别。
46 0
C# | 使用AutoResetEvent和ManualResetEvent进行线程同步和通信
|
8月前
|
C# 开发者
C# 开发者技术:进程间数据共享之管道(Pipes)-异步通信版
主要类 1.NamedPipeClientStream 2.NamedPipeServerStream 解释:命名管道是一种进程间通信的方式,它允许不同进程之间在同一台机器上进行通信
446 2
C# 开发者技术:进程间数据共享之管道(Pipes)-异步通信版
|
10月前
|
前端开发 JavaScript C#
【C#编程最佳实践 十】控件使用及Ajax通信
【C#编程最佳实践 十】控件使用及Ajax通信
56 0
|
C# 网络协议 消息中间件
c# IPC实现本机进程之间的通信
原文:c# IPC实现本机进程之间的通信   IPC可以实现本地进程之间通信。这种用法不是太常见,常见的替代方案是使用wcf,remoting,web service,socket(tcp/pipe/...)等其他分布式部署方案来替代进程之间的通信。
2470 0