Windows向HID设备通过控制端点发送数据的示例代码
时间: 2024-05-11 08:14:02 浏览: 92
以下是一个使用C#编写的示例代码,用于向HID设备发送数据:
```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace HIDTest
{
public partial class Form1 : Form
{
//定义常量
const int WM_DEVICECHANGE = 0x0219;
const int DBT_DEVICEARRIVAL = 0x8000;
const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
const int DBT_DEVTYP_DEVICEINTERFACE = 0x0005;
const int GENERIC_READ = 0x80000000;
const int GENERIC_WRITE = 0x40000000;
const int FILE_SHARE_READ = 0x00000001;
const int FILE_SHARE_WRITE = 0x00000002;
const int OPEN_EXISTING = 3;
const int IOCTL_HID_GET_FEATURE = 0x00000003;
const int IOCTL_HID_SET_FEATURE = 0x00000004;
const int IOCTL_HID_GET_INPUT_REPORT = 0x00000001;
const int IOCTL_HID_SET_OUTPUT_REPORT = 0x00000002;
const int IOCTL_HID_GET_REPORT_DESCRIPTOR = 0x00000006;
const int IOCTL_HID_GET_DEVICE_ATTRIBUTES = 0x00000007;
//定义结构体
[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DATA
{
public int cbSize;
public Guid interfaceClassGuid;
public int flags;
public int reserved;
}
[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
public int cbSize;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string devicePath;
}
[StructLayout(LayoutKind.Sequential)]
public struct HIDD_ATTRIBUTES
{
public int Size;
public ushort VendorID;
public ushort ProductID;
public ushort VersionNumber;
}
[StructLayout(LayoutKind.Sequential)]
public struct HIDP_CAPS
{
public short Usage;
public short UsagePage;
public short InputReportByteLength;
public short OutputReportByteLength;
public short FeatureReportByteLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
public short[] Reserved;
public short NumberLinkCollectionNodes;
public short NumberInputButtonCaps;
public short NumberInputValueCaps;
public short NumberInputDataIndices;
public short NumberOutputButtonCaps;
public short NumberOutputValueCaps;
public short NumberOutputDataIndices;
public short NumberFeatureButtonCaps;
public short NumberFeatureValueCaps;
public short NumberFeatureDataIndices;
}
//定义API函数
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, IntPtr lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport("hid.dll", SetLastError = true)]
static extern bool HidD_GetAttributes(IntPtr HidDeviceObject, ref HIDD_ATTRIBUTES Attributes);
[DllImport("hid.dll")]
static extern bool HidD_GetPreparsedData(IntPtr HidDeviceObject, ref IntPtr PreparsedData);
[DllImport("hid.dll", SetLastError = true)]
static extern bool HidD_FreePreparsedData(IntPtr PreparsedData);
[DllImport("hid.dll", SetLastError = true)]
static extern int HidP_GetCaps(IntPtr PreparsedData, ref HIDP_CAPS Capabilities);
[DllImport("hid.dll", SetLastError = true)]
static extern bool HidD_GetSerialNumberString(IntPtr HidDeviceObject, IntPtr Buffer, int BufferLength);
[DllImport("hid.dll", SetLastError = true)]
static extern bool HidD_SetFeature(IntPtr HidDeviceObject, byte[] ReportBuffer, int ReportBufferLength);
[DllImport("hid.dll", SetLastError = true)]
static extern bool HidD_GetFeature(IntPtr HidDeviceObject, byte[] ReportBuffer, int ReportBufferLength);
[DllImport("setupapi.dll", SetLastError = true)]
static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, IntPtr Enumerator, IntPtr hwndParent, int Flags);
[DllImport("setupapi.dll", SetLastError = true)]
static extern bool SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref Guid InterfaceClassGuid, int MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
[DllImport("setupapi.dll", SetLastError = true)]
static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, int DeviceInterfaceDetailDataSize, ref int RequiredSize, IntPtr DeviceInfoData);
[DllImport("setupapi.dll", SetLastError = true)]
static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
//定义变量
IntPtr hidHandle;
HIDD_ATTRIBUTES attributes;
HIDP_CAPS capabilities;
IntPtr preparsedData;
byte[] outputReportBuffer = new byte[9];
byte[] inputReportBuffer = new byte[9];
byte[] featureReportBuffer = new byte[9];
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//获取HID设备的信息
Guid hidGuid = Guid.Empty;
HidD_GetHidGuid(ref hidGuid);
IntPtr deviceInfoSet = SetupDiGetClassDevs(ref hidGuid, IntPtr.Zero, IntPtr.Zero, 0x12);
SP_DEVICE_INTERFACE_DATA interfaceData = new SP_DEVICE_INTERFACE_DATA();
interfaceData.cbSize = Marshal.SizeOf(interfaceData);
int index = 0;
while (SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref hidGuid, index, ref interfaceData))
{
int requiredSize = 0;
SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref interfaceData, IntPtr.Zero, 0, ref requiredSize, IntPtr.Zero);
SP_DEVICE_INTERFACE_DETAIL_DATA detailData = new SP_DEVICE_INTERFACE_DETAIL_DATA();
detailData.cbSize = Marshal.SizeOf(detailData);
IntPtr detailDataBuffer = Marshal.AllocHGlobal(requiredSize);
Marshal.StructureToPtr(detailData, detailDataBuffer, false);
if (SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref interfaceData, detailDataBuffer, requiredSize, ref requiredSize, IntPtr.Zero))
{
string devicePath = Marshal.PtrToStringAuto(new IntPtr(detailDataBuffer.ToInt64() + 4));
hidHandle = CreateFile(devicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if (hidHandle.ToInt32() != -1)
{
attributes.Size = Marshal.SizeOf(attributes);
HidD_GetAttributes(hidHandle, ref attributes);
HidD_GetPreparsedData(hidHandle, ref preparsedData);
HidP_GetCaps(preparsedData, ref capabilities);
HidD_FreePreparsedData(preparsedData);
//获取设备的序列号
IntPtr serialNumberBuffer = Marshal.AllocHGlobal(256);
HidD_GetSerialNumberString(hidHandle, serialNumberBuffer, 256);
string serialNumber = Marshal.PtrToStringAuto(serialNumberBuffer);
Marshal.FreeHGlobal(serialNumberBuffer);
//输出设备的信息
textBox1.AppendText("Device Found:\r\n");
textBox1.AppendText("Vendor ID: " + attributes.VendorID.ToString("X4") + "\r\n");
textBox1.AppendText("Product ID: " + attributes.ProductID.ToString("X4") + "\r\n");
textBox1.AppendText("Version Number: " + attributes.VersionNumber.ToString("X4") + "\r\n");
textBox1.AppendText("Serial Number: " + serialNumber + "\r\n");
textBox1.AppendText("Usage: " + capabilities.Usage.ToString("X4") + "\r\n");
textBox1.AppendText("Usage Page: " + capabilities.UsagePage.ToString("X4") + "\r\n");
textBox1.AppendText("Input Report Byte Length: " + capabilities.InputReportByteLength.ToString() + "\r\n");
textBox1.AppendText("Output Report Byte Length: " + capabilities.OutputReportByteLength.ToString() + "\r\n");
textBox1.AppendText("Feature Report Byte Length: " + capabilities.FeatureReportByteLength.ToString() + "\r\n");
}
}
Marshal.FreeHGlobal(detailDataBuffer);
index++;
}
SetupDiDestroyDeviceInfoList(deviceInfoSet);
}
private void button1_Click(object sender, EventArgs e)
{
//向设备发送数据
outputReportBuffer[0] = 0x00; //Report ID
outputReportBuffer[1] = 0x01; //Data
outputReportBuffer[2] = 0x02; //Data
outputReportBuffer[3] = 0x03; //Data
outputReportBuffer[4] = 0x04; //Data
outputReportBuffer[5] = 0x05; //Data
outputReportBuffer[6] = 0x06; //Data
outputReportBuffer[7] = 0x07; //Data
outputReportBuffer[8] = 0x08; //Data
HidD_SetFeature(hidHandle, outputReportBuffer, 9);
}
private void button2_Click(object sender, EventArgs e)
{
//从设备读取数据
inputReportBuffer[0] = 0x00; //Report ID
HidD_GetFeature(hidHandle, inputReportBuffer, 9);
textBox1.AppendText("Input Report Data: ");
for (int i = 1; i < 9; i++)
{
textBox1.AppendText(inputReportBuffer[i].ToString("X2") + " ");
}
textBox1.AppendText("\r\n");
}
}
}
```
阅读全文