using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
using System.Collections;
using System.IO;

namespace GameControl
{
    class Class1
    {
        //以下是调用windows的API的函数
        //获得GUID
        [DllImport("hid.dll")]
        public static extern void HidD_GetHidGuid(ref Guid HidGuid);
        Guid guidHID = Guid.Empty;
        //过滤设备,获取需要的设备
        [DllImport("setupapi.dll", SetLastError = true)]
        public static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, uint Enumerator, IntPtr HwndParent, DIGCF Flags);
        IntPtr hDevInfo;
        //获取设备,true获取到
        [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern Boolean SetupDiEnumDeviceInterfaces(IntPtr hDevInfo, IntPtr devInfo, ref Guid interfaceClassGuid, UInt32 memberIndex, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData);
        public struct SP_DEVICE_INTERFACE_DATA
        {
            public int cbSize;
            public Guid interfaceClassGuid;
            public int flags;
            public int reserved;
        }

// 获取接口的详细信息 必须调用两次 第1次返回长度 第2次获取数据
        [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr deviceInfoSet, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, IntPtr deviceInterfaceDetailData,
            int deviceInterfaceDetailDataSize, ref int requiredSize, SP_DEVINFO_DATA deviceInfoData);
        [StructLayout(LayoutKind.Sequential)]
        public class SP_DEVINFO_DATA
        {
            public int cbSize = Marshal.SizeOf(typeof(SP_DEVINFO_DATA));
            public Guid classGuid = Guid.Empty; // temp
            public int devInst = 0; // dumy
            public int reserved = 0;
        }

[StructLayout(LayoutKind.Sequential, Pack = 2)]
        internal struct SP_DEVICE_INTERFACE_DETAIL_DATA
        {
            internal int cbSize;
            internal short devicePath;
        }

public enum DIGCF
        {
            DIGCF_DEFAULT = 0x1,
            DIGCF_PRESENT = 0x2,
            DIGCF_ALLCLASSES = 0x4,
            DIGCF_PROFILE = 0x8,
            DIGCF_DEVICEINTERFACE = 0x10
        }

//获取设备文件
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern int CreateFile(
            string lpFileName,                            // file name
            uint dwDesiredAccess,                        // access mode
            uint dwShareMode,                            // share mode
            uint lpSecurityAttributes,                    // SD
            uint dwCreationDisposition,                    // how to create
            uint dwFlagsAndAttributes,                    // file attributes
            uint hTemplateFile                            // handle to template file
            );
        //读取设备文件
        [DllImport("Kernel32.dll", SetLastError = true)]
        private static extern bool ReadFile
            (
                IntPtr hFile,
                byte[] lpBuffer,
                uint nNumberOfBytesToRead,
                ref uint lpNumberOfBytesRead,
                IntPtr lpOverlapped
            );

//释放设备
        [DllImport("hid.dll")]
        static public extern bool HidD_FreePreparsedData(ref IntPtr PreparsedData);
        //关闭访问设备句柄,结束进程的时候把这个加上保险点
        [DllImport("kernel32.dll")]
        static public extern int CloseHandle(int hObject);

int HidHandle = -1;
        public const uint GENERIC_READ = 0x80000000;
        public const uint GENERIC_WRITE = 0x40000000;
        public const uint FILE_SHARE_READ = 0x00000001;
        public const uint FILE_SHARE_WRITE = 0x00000002;
        public const int OPEN_EXISTING = 3;

public void UsBMethod(int index)
        {
            HidD_GetHidGuid(ref guidHID);
            hDevInfo = SetupDiGetClassDevs(ref guidHID, 0, IntPtr.Zero, DIGCF.DIGCF_PRESENT | DIGCF.DIGCF_DEVICEINTERFACE);
            int bufferSize = 0;
            ArrayList HIDUSBAddress = new ArrayList();

string devicePathName = "";
            while (true)
            {
                //获取设备,true获取到
                SP_DEVICE_INTERFACE_DATA DeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA();
                DeviceInterfaceData.cbSize = Marshal.SizeOf(DeviceInterfaceData);
                bool result = false;
                for (int i = 0; i < 3; i++)
                {
                    result = SetupDiEnumDeviceInterfaces(hDevInfo, IntPtr.Zero, ref guidHID, (UInt32)index, ref DeviceInterfaceData);
                }
                //第一次调用出错,但可以返回正确的Size
                SP_DEVINFO_DATA strtInterfaceData = new SP_DEVINFO_DATA();
                result = SetupDiGetDeviceInterfaceDetail(hDevInfo, ref DeviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, strtInterfaceData);
                //第二次调用传递返回值,调用即可成功
                IntPtr detailDataBuffer = Marshal.AllocHGlobal(bufferSize);
                SP_DEVICE_INTERFACE_DETAIL_DATA detailData = new SP_DEVICE_INTERFACE_DETAIL_DATA();
                detailData.cbSize = Marshal.SizeOf(typeof(SP_DEVICE_INTERFACE_DETAIL_DATA));
                Marshal.StructureToPtr(detailData, detailDataBuffer, false);
                result = SetupDiGetDeviceInterfaceDetail(hDevInfo, ref DeviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, strtInterfaceData);
                if (result == false)
                {
                    break;
                }
                //获取设备路径访
                IntPtr pdevicePathName = (IntPtr)((int)detailDataBuffer + 4);
                devicePathName = Marshal.PtrToStringAuto(pdevicePathName);
                HIDUSBAddress.Add(devicePathName);
                index++;
                break;
            }

//连接设备文件
            int aa = CT_CreateFile(devicePathName);
            bool bb = USBDataRead(HidHandle);
        }

//建立和设备的连接
        public int CT_CreateFile(string DeviceName)
        {
            HidHandle = CreateFile(
                DeviceName,
                GENERIC_READ,// | GENERIC_WRITE,//读写,或者一起
                FILE_SHARE_READ,// | FILE_SHARE_WRITE,//共享读写,或者一起
                0,
                OPEN_EXISTING,
                0,
                0);
            if (HidHandle == -1)
            {
                return 0;
            }
            else
            {
                return 1;
            }
        }

//根据CreateFile拿到的设备handle访问文件,并返回数据
        public bool USBDataRead(int handle)
        {
            while (true)
            {
                uint read = 0;
                //注意字节的长度,我这里写的是8位,其实可以通过API获取具体的长度,这样安全点,
                //具体方法我知道,但是没有写,过几天整理完代码,一起给出来
                Byte[] m_rd_data = new Byte[8];
                bool isread = ReadFile((IntPtr)handle, m_rd_data, (uint)8, ref read, IntPtr.Zero);
                //这里已经是拿到的数据了
                Byte[] m_rd_dataout = new Byte[read];
                Array.Copy(m_rd_data, m_rd_dataout, read);
            }
        }

}
}

参考

https://github.com/allanpk716/USB4ScanGun

C# 如何捕获一个USB设备发送到PC的数据的更多相关文章

  1. 基于libUSB的USB设备固件更新程序(下载数据)(转)

    源:基于libUSB的USB设备固件更新程序(下载数据) 本文紧接上一篇日志:基于libUSB-Win32的USB设备固件更新程序(前言),相关背景以及起因等,此处不再赘述,如感兴趣请移步. libU ...

  2. 向USB设备发送SCSI命令

    http://bbs3.driverdevelop.com/simple/?t84347.html { BOOL status = ; DWORD accessMode = , shareMode = ...

  3. USB设备在连接PC时的reset从何而来?

    近期在做烧写工具的优化工作,有一些关于USB的内容须要总结一下当中包含设备的初始化过程和枚举过程. 在枚举的过程中,设备会一直等PC端的状态,当等到reset命令时会对设备进行又一次枚举.可是这个re ...

  4. STM32 使用Cubemx 建一个USB(HID)设备下位机,实现数据收发

    这里我主要说一下如何做一个USB下位机,这里主要分3部分:1.建立工程:2.添加报文描述符:3.数据的传输.这里就不讲USB的理论知识了,有想要了解的自行百度一下就可以了. 建立工程:工程建立参考:h ...

  5. 转载 STM32 使用Cubemx 建一个USB(HID)设备下位机,实现数据收发

    STM32 使用Cubemx 建一个USB(HID)设备下位机,实现数据收发  本文转载自 https://www.cnblogs.com/xingboy/p/9913963.html 这里我主要说一 ...

  6. USB设备---URB请求块

    1.urb 结构体 USB 请求块(USB request block,urb)是USB 设备驱动中用来描述与USB 设备通信所用的基本载体和核心数据结构,非常类似于网络设备驱动中的sk_buff 结 ...

  7. usb设备驱动描述,王明学learn

    usb设备驱动 本章主要内容包含以下:USB总线介绍,USB协议分析,USB系统架构 一.USB总线介绍 1.1USB发展史 USB(Universal Serial Bus)通用串行总线,是一种外部 ...

  8. USB设备的基本概念

    在终端用户看来,USB设备为主机提供了多种多样的附加功能,如文件传输,声音播放等,但对USB主机来说,它与所有USB设备的接口都是一致的.一个USB设备由3个功能模块组成:USB总线接口.USB逻辑设 ...

  9. USB设备---URB请求快

    1.urb 结构体USB 请求块(USB request block,urb)是USB 设备驱动中用来描述与USB 设备通信所用的基本载体和核心数据结构,非常类似于网络设备驱动中的sk_buff 结构 ...

随机推荐

  1. 彻底搞懂JavaScript中的继承

    你应该知道,JavaScript是一门基于原型链的语言,而我们今天的主题 -- "继承"就和"原型链"这一概念息息相关.甚至可以说,所谓的"原型链&q ...

  2. 【前端】特效-Javascript实现购物页面图片放大效果

    实现效果 实现代码: <!DOCTYPE html> <html> <head> <title>购物图片放大</title> <met ...

  3. JQuery Ajax jsonp

    JQuery ajax jsonp $.ajax({ method:"POST", url:"http://localhost:8081/ChenLei/PeopleSe ...

  4. 第二章 第二个spring-boot程序

    上一节的代码是spring-boot的入门程序,也是官方文档上的一个程序.这一节会引入spring-boot官方文档推荐的方式来开发代码,并引入我们在spring开发中service层等的调用. 1. ...

  5. Redis之List 列表

    Redis List 列表 Redis列表是简单的字符串列表,按照插入顺序排序.你可以添加一个元素导列表的头部(左边)或者尾部(右边) 一个列表最多可以包含 232 - 1 个元素 (42949672 ...

  6. POJ 2762 Going from u to v or from v to u? (判断单连通)

    http://poj.org/problem?id=2762 题意:给出有向图,判断任意两个点u和v,是否可以从u到v或者从v到u. 思路: 判断图是否是单连通的. 首先来一遍强连通缩点,重新建立新图 ...

  7. python 计算阶乘

    # 用for循环计算 n! sum = n=int(input('请输入n=')) ,n+): ,-): sum *= j # sum=sum*j print('%d!=%3d' %(i,sum)) ...

  8. redis优缺点

    redis主要是一个内存数据库.很多时候是被作为缓存来使用.redis的优势主要体现在和其他缓存方案进行比较,redis的不足主要是和其他数据库进行比较时体现的. 优点: 读写性能优异 支持数据持久化 ...

  9. 装完RHEL之后,活用CentOS的Repository

    RHEL的Repository好像要帐号. 所以yum几乎就不能用了. 在 /etc/yum.repos.d 里新建个文件,就可以用CentOS的Repository了 [CentOS6] name= ...

  10. [oracle]创建查看 LOCAL INDEX

    create index IDX_T_GPS_CPH_local on T_GPS (CPH) local; create index IDX_T_GPS_SJ_local on T_GPS (SJ) ...