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

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

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
7837 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
9562 0
使用SSH远程登录阿里云ECS服务器
远程连接服务器以及配置环境
2166 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
11216 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
4497 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
6428 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
3010 0
+关注
杰克.陈
一个安静的程序猿~
10427
文章
2
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载