C#与USB HID间的通信-阿里云开发者社区

开发者社区> 杰克.陈> 正文

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

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
jQuery中的cache : false到底有什么用?
jQuery中的cache : false到底有什么用?
4 0
使用ehcache缓存页面、ExpiresFilter添加Expires头,大幅提升网站性能
使用ehcache缓存页面、ExpiresFilter添加Expires头,大幅提升网站性能
6 0
Gin 框架:启动多个端口
本文介绍如何通过 rk-boot 在一个进程里启动多个 Gin 端口。
6 0
SAP WebIDE:how to enable context API reference
SAP WebIDE:how to enable context API reference
3 0
Angular 项目中的可摇树依赖 - Tree-shakable dependencies
Angular 项目中的可摇树依赖 - Tree-shakable dependencies
5 0
高效能程序员的修炼札记:安全基础,保护用户数据
高效能程序员的修炼札记:安全基础,保护用户数据
4 0
一个好用的Visual Studio Code扩展 - Live Server,适用于前端小工具开发
一个好用的Visual Studio Code扩展 - Live Server,适用于前端小工具开发
6 0
重学Java(五):操作符
重学Java(五):操作符
8 0
Linux中的“快捷方式”:ln
如Windows中快捷方式的用途一样,为了方便对系统文件|文件夹修改,创建一个链接,并使这个链接指向另一个文件或者文件夹,使其用户在操作链接时等同于操作指向的文件|文件夹。
9 0
JEECG快速开发平台入坑报错解决第一波——pom.xml中jeecg的依赖jar包没导入成功
JEECG快速开发平台入坑报错解决第一波——pom.xml中jeecg的依赖jar包没导入成功
7 0
+关注
杰克.陈
一个安静的程序猿~
9798
文章
2
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载