




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、串口通信中接收数据时延迟处理与缓存处理的解决方案(C#)利用串口进行通信,当发送方(A)将数据写入串口后,通过无线或有线方式将数据传送给接收方(B),B 通过调用串口读方法 comm.read(参数)即可将数据读出。原理十分简单,但最近在利用串口处理 SM-42 无线传输时,数据总是一段一段的传到 B,并不能在 comm_DataReceived 方法中单纯使用 read 方法将数据接收完全。我知道用缓存机制,但由于经验少(正在实习),到网上找了找大牛们的方法,并结合自己的理解,发现有两种方法可以处理。方法一:comm_DataReceived(Comm 控件的数据接收方法,当有数据来临时会触
2、发)会创建一个线程(,因为之前不知道它另辟线程,所以自己编写了一个线程处理函数),因此当串口在等待数据时,不影响主窗体或主线程的操作。所以当数据到来时,可以通过 Thread.Sleep(100)让接收函数休息 100 毫秒,这 100 毫秒做什么用呢?就是让所有的数据都到达 B 时再,这样就逃避了分批到达。很明显,这是在糊弄。因为万一 100毫秒都不够呢?所以,方法二更合适。代码1 private void comm_DataReceived(objecder, EventArgs e) 2 Thread.Sleep(100); /等待 100 毫秒nReviceBytesNum =comm
3、.BytesToRead; /收到的字节数。byte ReadBuf = new bytenReviceBytesNum; /定义接收字节数组comm.Read(ReadBuf, 0, nReviceBytesNum); /接收数据 7 方法二:使用缓存机制完成。首先通过定义一个成员变量 List buffer = new List(4096);用来存放所有的数据,在接收函数里,通过 buffer.AddRange()方法不断地将接收到的数据加入到 buffer 中,并同时对 buffer 中的数据进行检验,如果达到一定的长度并且校验结果正确(校验方法在发送方和接收方一致),再进行处理。具体代
4、码如下:代码privaist buffer = new List(4096);private void sp_DataReceived(objecder, EventArgs e) /sp 是串口控件n = sp.BytesToRead; byte buf = new byten; sp.Read(buf, 0, n);/1.缓存数据 buffer.AddRange(buf);/2.完整性判断while (buffer.Count = 4)/至少包含帧头(2 字节)、长度(1 字节)、校验位(1 字节);根据设计不同而不同/2.1 查找数据头if (buffer0 = 0 x01) /传输数据
5、有帧头,用于判断len = buffer2;if (buffer.Count len + 4) /数据区尚未接收完整break;跨线程及修改控件属性的解决方案在上一篇文章中,写了一些串口通信时数据接收的内容,其中有一行代码有个提问:在数据接收线程中,当接收到数据并且校验正确后,我怎么显示这些数据到窗体中呢?要显示数据,必须要 主线程(A)的各种控件,而数据接收是另一个线程(B)。有两种方案可以解决这个问题,和上文一样,也是第二个较好。方法一:取消跨线程操作检查当线程 B 在线程 A 创建的控件时,线程 A 会对控件的线程锁进行检验,当多个线程同时对控件进行写操作时,必然产生,因此此时的程序会非
6、常不稳定,经常突然就退出,Debug 显示原因是跨线程操作控件了。既然如此,那就让线程 A 不去检验其他线程了,在 Form_Load 函数里加一句:System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;就万事大吉了。很显然,这种方法不使用。方法二:使用机制原理:有一个D,他负责沟通主线程 A 和其他线程 B,当是主线程操作控件时,正常执行;当是其他线程 B操作控件时,通知D,之后D 唤醒主线程 A,告诉主线程 A 去更改控件的一些属性,显然,这样一来,就不存在跨线程操作了,所有的任务由D 来完成。示例代码如下
7、:使用 delegate 定义一个delShow。在其他线程中控件 textbox1 时,直接调用 showData(其他线程);就可以了,showData 函数能自动区分是否是主线程。delegate void delShow(); /将对控件的操作写到一个函数中/得到完整的数据,到ReceiveBytes 中进行校验 buffer.CopyTo(0, ReceiveBytes, 0, len + 4); byte jiaoyan; /开始校验jiaoyan = this.JY(ReceiveBytes); if (jiaoyan != ReceiveByteslen+3)/校验失败,最后一
8、个字节是校验位buffer.RemoveRange(0, len + 4); MessageBox.Show(数据包不正确!); continue;buffer.RemoveRange(0, len + 4);/执行其他代码,对数据进行处理。else /帧头不正确时,记得清除buffer.RemoveAt(0);在方法二中,有一句“执行其他代码,对数据进行处理”,如果这些代码涉及到主线程的控件比如 Label,TextBox,就要涉及跨线程控件。(串口的 DataReceived 方创建新线程,这在本文开始时已经说明)对于 跨线程及更改控件属性,也有两种方法,下一篇文章再介绍。12345678
9、910111213delegate void delShow(string key);private void showData(String para)if (!InvokeRequired)textBox1.Text = para;elsethis.Invoke(new delShow(showData), para);.NET 提供了 SerialPort 类进行串口通信,使用很简单,连我这个.NET 新手也能很快上手.以下是从网上找到并自己修改后的参考代码:using System;using System.Collections.Generic;using System.Linq;C
10、#中使用 SerialPort 类实现简单串口编程给你改了改,这样看起来好一点private void showData(String para) if (!textbox1.InvokeRequired) /不需要唤醒,就是创建控件的线程/如果是创建控件的线程,直接正常操作textbox1.Text = para;else /非创建线程,用进行操作delShow ds = new delShow(showData);/唤醒主线程,可以传递参数,也可以为null,即不传参数 Invoke(ds, new objectpara);/其他线程使用,具体线程的建立自己去查看相关书籍 showData
11、(其他线程);#3 楼 2011-01-21 17:15 单程列车?45678910111213141516171819202122232425262728293031323334353637383940using using using using using using using using using usingusingSystem.Text; System.Windows; System.Windows.Controls;System.Windows.Data;System.Windows.System.Windows.Input; System.Windows.Media;s;S
12、ystem.Windows.Media.Imaging;System.Windows.Navigation;System.Windows.ShSystem.IO.Ports;s;namespacem/ Window1.xaml 的交互逻辑public partial class Window1 : Windowpublic Window1()InitializeComponent();/定义 SerialPort 对象SerialPort port1;/初始化SerialPort 对象方法.PortName 为COM 口名称,例如COM1,COM2等,注意是string 类型public vo
13、id InitCOM(string PortName)port1 = new SerialPort(PortName);port1.BaudRate = 9600;/波特率 port1.Parity = Parity.None;/无奇偶校验位its = Stits.Two;/两个停止位port1.Stport1.Handshake = Handshake.RequestToSend;/控制协议port1.ReceivedBytesThreshold = 4;/设置 DataReceived 事件发生前输入缓冲区中的字节数port1.DataReceived += new SerialDataR
14、eceivedEvenndlort1_DataReceived);/DataReceived 事件委托4142434445464748/DataReceived 事件委托方法private void port1_DataReceived(objectryder, SerialDataReceivedEventArgs e)StringBuilder currentline = new StringBuilder();495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
15、94/循环接收数据while (port1.BytesToRead 0)char ch = (char)port1.ReadByte(); currentline.Append(ch);/在这里对接收到的数据进行处理/currentline= new StringBuilder();catch(ExceptionConsole.Wriex)ine(ex.Message.ToString();/打开串口的方法public void OpenPort()tryport1.Open();catch if (port1.IsOpen)Console.WrielseConsole.Wriine(the
16、port is opened!);ine(failure to open the port!);/关闭串口的方法public void ClosePort()port1.Close();if (!port1.IsOpen)Console.Wriine(the port is already closed!);/向串口发送数据C#的 usb 通讯编程using System;using System.Collections.Generic;usingponentM;using System.Data; using System.Drawing;using System.Text;95public
17、 voidmand(stringdString) 96byte WriteBuffer = Encoding.ASCII.GetBytes(dString);port1.Write(WriteBuffer, 0, WriteBuffer.Length); 99100/调用实例private void btnOpen_Click(objecder, RoutedEventArgs e)103/我现在用的COM1 端口,按需要可改成COM2,COM3InitCOM(COM1);OpenPort();107108109 值得注意的是:port1.ReceivedBytesThreshold = 4;
18、 ReceivedBytesThreshold 属性设置触发一次 DataReceived 事件时将接收到的数据字节数.由于硬件是一次发上来 4 个字节估设置为 4.如果不能正确设置这个属性的话,在 SerialPort 对象第一次触发 DataReceived 事件时还是正确的(4 个字节),但是从第二次触发之后都是一个字节触发一次 DataReceived 事件.为什么这样搞不清楚.如果在 DataReceived 委托事件中使用了不是 DataReceived 委托事件所程创建的 UI 控件,函数等,需要使用到 Dispatcher 类来达到线程安全,不然会报错.以下是 MSDN 中 D
19、ispatcher 类的例子(XAML),简单明了:1 private delegate void AddTextDelegate(Panel p, String text); 23 private void AddText(Panel p, String text) 4 p.Children.Clear();p.Children.Add(new TextBlock Text = text ); 7 89 private void TestBeginInvokeWithParameters(Panel p) 10 if (p.Dispatcher.CheckAcs() AddText(p, A
20、dded directly.);else p.Dispatcher.BeginInvoke(new AddTextDelegate(AddText), p, Added by Dispatcher.); 14 using System.Windows.Forms;using System.IO;namespace U 盘更新public partial class Form1 : Formpublic const public const public const public const public const public const public const public const
21、public const public const public const public constpublic constWM_DEVICECHANGE = 0 x219; DBT_DEVICEARRIVAL = 0 x8000; DBT_CONFIGCHANGECANCELED = 0 x0019; DBT_CONFIGCHANGED = 0 x0018; DBT_CUSTOMEVENT = 0 x8006; DBT_DEVICEQUERYREMOVE = 0 x8001; DBT_DEVICEQUERYREMOVEFAILED = 0 x8002; DBT_DEVICEREMOVECO
22、MPLETE = 0 x8004; DBT_DEVICEREMOVEPENDING = 0 x8003; DBT_DEVICETYPESPECIFIC = 0 x8005; DBT_DEVNODES_CHANGED = 0 x0007;DBT_QUERYCHANGECONFIG = 0 x0017;DBT_USERDEFINED = 0 xF;public Form1()InitializeComponent();private void Form1_Load(objecder, EventArgs e)protected override void WndProc(ref Message m
23、)tryif (m.Msg = WM_DEVICECHANGE)switch (m.ram.To32()case WM_DEVICECHANGE:break;case DBT_DEVICEARRIVAL:/U 盘 DriveInfo s = DriveInfo.GetDrives(); foreach (DriveInfo drive in s)if (drive.DriveType = DriveType.Removable)listBox1.Items.Add(U 盘已break;,盘符为: + drive.Name.ToString();break;case DBT_CONFIGCHAN
24、GECANCELED:break;case DBT_CONFIGCHANGED:break;case DBT_CUSTOMEVENT:break;case DBT_DEVICEQUERYREMOVE:break;case DBT_DEVICEQUERYREMOVEFAILED:break;case DBT_DEVICEREMOVECOMPLETE: /U 盘卸载break;case DBT_DEVICEREMOVEPENDING:break;case DBT_DEVICETYPESPECIFIC:break;case DBT_DEVNODES_CHANGED:break;case DBT_QU
25、ERYCHANGECONFIG:break;case DBT_USERDEFINED:break; default:break;catch (Exception ex)MessageBox.Show(ex.Message);base.WndProc(ref m);) ;9( 转串口突然拔出检测解决方案最近做虚拟串口通讯程序(IRDA-USB-串口),由于是 USB 设备所以在通讯过程中有可能把串口拔出,程序需要实时检测到串口拔出。并把正在执行的任务结束关闭串口,给出提示。由于程序是 C#做的,C#在操作底层比较不方便,需要调用较多的 API 函数。开始的方法是先捕获 USB 设备的拔出,再查找
26、HKEY_LOCAL_MACHINE/HAEDWARE/D中的串口是否已经不存在。后来发现这种办法不可行.后来查找表的HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/DeviceClasses/a5dcbf10-6530-11d2-901f-00c04 fb951ed 中的相应项看是否 LInked 等于零,如果是就是你的 usb 设备拔出了。而且你还要检测是不是你的那个串口,这样算是可以解决问题.。之后我有想用异常的方法来解决这个问题,首先还是捕获 USB 设备的拔出消息,由于.NET 并不知道串口的拔出,要是该串口正在使用,这是对串口
27、的是最好有方便的。代码如下:将会产生异常,所以通过捕获异常来处理protected override void WndProc(ref Message m)if (m.Msg = 0 x0219)/设备被拔出if (m.ram.To32() = 0 x8004)/usb 串口if (对串口进行操作)/产生异常关闭串口base.WndProc(ref m);当设备入/拔出的时候,WINDOWS 会向每个窗体发送 WM_DEVICECHANGE消息,当消息的ram 值ram 值等于等于 DBT_DEVICEARRIVAL 时,表示 Media 设备入并且已经可用;如果DPLETE,表示 Media
28、 设备已经被移出。它们的 lParam 都指向一个 DEV_BROADCAST_HDR 结构体,其如下:1 typedef struct _DEV_BROADCAST_HDR2 3DWORD dbch_size;45DWORD dbch_devicetype;DWORD dbch_;6 DEV_BROADCAST_HDR, *PDEV_BROADCAST_HDR;这个结构体仅仅是一个“头”(HDR),其后还有附加数据,dbch_size 表示结构体实例的字节数,当其中的dbch_devicetype 字等于 DBT_DEVTYP_VOLUME 时,表示当前设备是逻辑驱动器,且 lParam 实
29、际上指向的应该是 DEV_BROADCAST_VOLUME 结构体实例(真佩服这种逻辑),DEV_BROADCAST_VOLUME 结构体如下:1 typedef struct _DEV_BROADCAST_VOLUME 23456DWORD dbcv_size;DWORD dbcv_devicetype;DWORD dbcv_;DWORD dbcv_unitmask;WORD dbcv_flags;7 DEV_BROADCAST_VOLUME, *PDEV_BROADCAST_VOLUME;其中 dbcv_unitmask 字段表示当前改变的驱动器掩码,第一位表示驱动器号 A,第二位表示驱动
30、器号 B,第三位表示驱动器号 C,以此类推 dbcv_flags 表示驱动器的类别,如果等于 1,则是光盘驱动器;如果是 2,则是网络驱动器;如果是硬盘、U 盘则都等于 0所以,我只需要在程序中捕捉 WM_DEVICECHANGE代码:消息,然后根据具体情况去处理即可,下面是测试using System;using System.Runtime.eropServi using System.Collections.Generic;usingponentM;using System.Data; using System.Drawing; using System.Text;using Syste
31、m.Windows.Forms;namespace UDiskDetectpublic partial class Form1 : Formpublic Form1()ponent();private void Form1_Load(objecder, EventArgs e)StructLayout(LayoutKind.Sequential) struct DEV_BROADCAST_HDRpublic U public Upublic U32 dbch_size;32 dbch_devicetype;32 dbch_;StructLayout(LayoutKind.Sequential)
32、 struct DEV_BROADCAST_VOLUMEpublic U public U public U public Upublic U32 dbcv_size;32 dbcv_devicetype;32 dbcv_;32 dbcv_unitmask;16 dbcv_flags;protected override void DefWndProc(ref Message m)if (m.Msg = 0 x0219)/WM_DEVICECHANGEswitch (m.ram.To32()case 0 x8000:/DBT_DEVICEARRIVALDEV_BROADCAST_HDR dbh
33、dr = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(m.LPara m, typeof(DEV_BROADCAST_HDR);if (dbhdr.dbch_devicetype = 0 x00000002)/DBT_DEVTYP_VOLUMEDEV_BROADCAST_VOLUME dbv = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_VOLUME);if (dbv.dbcv_flags = 0) AddVolumes(GetVolumes(d
34、bv.dbcv_unitmask);break;case 0 x8004:/DPLETEDEV_BROADCAST_HDR dbhdr = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_HDR);if (dbhdr.dbch_devicetype = 0 x00000002)/DBT_DEVTYP_VOLUMEDEV_BROADCAST_VOLUME dbv = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(m.LParam, typeof(DEV_B
35、ROADCAST_VOLUME);if (dbv.dbcv_flags = 0) RemoveVolumes(GetVolumes(dbv.dbcv_unitmask);break;base.DefWndProc(ref m);/ / 根据驱动器掩码返回驱动器号数组/ / 掩码/ 返回驱动器号数组 public sic char GetVolumes(U32 Mask)List Volumes = new List();C#实现 USB 接口的程序代码C#实现 USB 接口的程序代码.namespace ConsoleApplication1class Programsic void Main
36、(string args)USB usb;for (i = 0; i 32; i+)up = (u)Math.(2, i); if (p | Mask) = p)Volumes.Add(char)(A + i);return Volumes.ToArray();public void AddVolumes(char Volumes)foreach (char volume in Volumes) listBox1.Items.Add(volume);public void RemoveVolumes(char Volumes)foreach (char volume in Volumes) l
37、istBox1.Items.Remove(volume);usb = new UDisk();/U 盘usb.OutputFile();/从U 盘读出文件usb.InputFile();/往U 盘写入文件usb.Dise();/拔出U 盘Console.Wriine();usb = new MDisk();/移动硬盘usb.OutputFile();/从移动硬盘读出文件usb.InputFile();/往移动硬盘写入文件usb.Dise();/拔出移动硬盘Console.Wriine();usb = new MP4();/MP4usb.OutputFile();/从MP4 读出文件usb.In
38、putFile();/往 MP4 写入文件usb.Dise();/拔出MP4Console.ReadKey();/USB 接口publicerface USB : IDisvoid OutputFile();/读出文件 void InputFile();/写入文件able/U 盘public class UDisk : USBpublic UDisk()Console.Wriine(U 盘准备就绪.);public void OutputFile()Console.Wriine(从U 盘读出文件);public void InputFile()Console.Wriine(往U 盘写入文件);
39、public void DisConsole.Wrie()ine(U 盘已被拔出);/移动硬盘public class MDisk : USBpublic MDisk()Console.Wriine(移动硬盘准备就绪.);public void OutputFile()Console.Wriine(从移动硬盘读出文件);public void InputFile()Console.Wriine(往移动硬盘写入文件);public void DisConsole.Wrie()ine(移动硬盘已被拔出);/MP4public class MP4 :public MP4()Console.WriUS
40、Bine(MP4 准备就绪.);public void OutputFile()Console.Wriine(从MP4 读出文件);public void InputFile()Console.Wriine(往MP4 写入文件);public void Dise()C#:USB 设备枚举(一)DeviceIoControl 的 PInvoke开发环境:Visual Studio V2010.NET Framework 4 Cnt Profile版本历史:V1.02011 年 10 月 10 日实现对 DeviceIoControl 接口的 PInvoke参考资料:*/using System;
41、using System.Runtime.eropServi;namespaplash.IO.PORTS#region ENUMpublic enum USB_HUB_NODE : uUsbHub,UsbMIParentpublic enum USB_CONNECTION_SUSNoDeviceConnected,DeviceConnected,Console.Wriine(MP4 已被拔出);DeviceFailedEnumeration,DeviceGeneralFailure,DeviceCausedOvercurrent,DeviceNotEnougher,DeviceNotEnoug
42、hBandwidth,DeviceHubNestedTooDeeply,DeviceInLegacyHubpublic enum USB_DEVICE_SPEED : byteUsbLowSpeed,/ 低速 USB 1.1UsbFullSpeed,/全速 USB1.1UsbHighSpeed,/高速 USB2.0UsbSuperSpeed/极速 USB3.0#endregionpublicpartial claSBernalconst32IOCTL_GET_HCD_DRIVERKEY_NAME = 0 x220424;ernalconst32IOCTL_USB_GET_ROOT_HUB_NA
43、ME = 0 x220408;ernalconst32IOCTL_USB_GET_NODE_CONNECTION_NAME = 0 x220414;ernalconst32IOCTL_USB_GET_NODE_INFORMATION = 0 x220408;ernalconst32 IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX = 0 x220448;ernal const32 IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION = 0 x220410;ernal const32UM_USB_STRING_LE
44、NGTH = 255;ernal const32 USB_STRING_DESCRIPTOR_TYPE = 3;StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)ernal struct USB_HCD_DRIVERKEY_NAMEpublic32 ActualLength;MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)public String Name;#region USB_NODE_INFORMATIONStructLayout(LayoutKind.Sequen
45、tial, Pack= 1)ernal struct USB_HUB_DESCRIPTORpublicBytebDescriptorLength;publicBytebDescriptorType;/ 描述符类型:0 x29publicBytebNumberOfPorts;/ 支持的下游端口数目public16 wHubCharacteristics;/ 特征描述publicByte berOnToerGood;/ 从端口加电到端口正常工作的时间间隔(以 2ms 为)public Byte bHubControlCurrent;/ 设备所需最大电流MarshalAs(UnmanagedType
46、.ByValArray,SizeConst = 64)public Byte bRemoveAnderMask;/ 指示连接在集线器端口的设备是否可移走StructLayout(LayoutKind.Sequential)ernal struct USB_HUB_INFORMATIONpublic USB_HUB_DESCRIPTOR HubDescriptor;public Byte HubIsBusered;StructLayout(LayoutKind.Sequential)ernal struct USB_MI_PARENT_INFORMATIONpublic32 NumberOfer
47、fa;StructLayout(LayoutKind.Explicit)ernal struct UsbNodeUnionFieldOffset(0)public USB_HUB_INFORMATION HubInformation;FieldOffset(0)public USB_MI_PARENT_INFORMATION MiParentInformation;StructLayout(LayoutKind.Sequential)ernal struct USB_NODE_INFORMATIONpublic USB_HUB_NODE NodeType;public UsbNodeUnion
48、 u;#endregion#region USB_NODE_CONNECTION_INFORMATIONStructLayout(LayoutKind.Sequential, Pack=1)ernal struct USB_DEVICE_DESCRIPTORpublicByte bLength;publicByte bDescriptorType;publicU16 bcdUSB;publicBytebDeviceClass;publicBytebDeviubClass;publicBytebDeviceProtocol;publicBytebMaxPacketSize0;publicU16i
49、dVendor;publicU16idProduct;publicU16bcdDevice;publicByteiManufacturer;publicByteiProduct;publicByteiSerialNumber;publicBytebNumConfigurations;StructLayout(LayoutKind.Sequential, Pack=1)ernal struct USB_ENDPO_DESCRIPTORpublicBytebLength;publicBytebDescriptorType;publicBytebEndpoAddress;publicBytebmAt
50、tributes;publicU16 wMaxPacketSize;publicByte berval;StructLayout(LayoutKind.Sequential, Pack=1)ernal struct USB_PIPE_INFOpublic USB_ENDPO_DESCRIPTOR EndpoDescriptor;public U32 ScheduleOffset;StructLayout(LayoutKind.Sequential, Pack = 1)ernal struct USB_NODE_CONNECTION_INFORMATION_EXpublic32 Connecti
51、onIndex;publicUSB_DEVICE_DESCRIPTOR DeviceDescriptor;publicByteCurrentConfigurationValue;publicByteSpeed;publicByteDeviceIsHub;public16 DeviceAddress;public32 NumberOfOpenPipes;publicUSB_CONNECTION_SUS ConnectionSus;MarshalAs(UnmanagedType.ByValArray, SizeConst= 32)public USB_PIPE_INFO PipeList;#end
52、region#region USB_DESCRIPTOR_REQUESTStructLayout(LayoutKind.Sequential)ernal struct USB_SETUP_PACKETpublicByte bmRequest;publicByte bRequest;publicU16wValue;publicU16wIndex;publicU16wLength;StructLayout(LayoutKind.Sequential, CharSet= CharSet.Auto)ernal struct USB_STRING_DESCRIPTORpublic Byte bLengt
53、h;public Byte bDescriptorType;MarshalAs(UnmanagedType.ByValTStr,SizeConst=UM_USB_STRING_LENGTH)public String bString;StructLayout(LayoutKind.Sequential)ernal struct USB_DESCRIPTOR_REQUESTpublic32 ConnectionIndex;publicUSB_SETUP_PACKET SetupPacket;publicUSB_STRING_DESCRIPTOR Data;#endregion#region US
54、B_NODE_CONNECTION_DRIVERKEY_NAMEStructLayout(LayoutKind.Sequential, CharSet= CharSet.Auto)ernal structUSB_NODE_CONNECTION_DRIVERKEY_NAMEpublic32 ConnectionIndex;public32 ActualLength;MarshalAs(UnmanagedType.ByValTStr, SizeConst =UM_USB_STRING_LENGTH)public String DriverKeyName;#endregion#region Devi
55、ceIoControlDllImport(kernel32.dll, CharSet = CharSet.Ansi,SetLastError=true)ernal sic externDeviceIoControl(Ptr hFile,32 dwIoControlCode,Ptr lpInBuffer,32 nInBufferSize,ref USB_HCD_DRIVERKEY_NAME lpOutBuffer,32 nOutBufferSize,out32 nBytesReturned,Ptr lpOverlapped);DllImport(kernel32.dll, CharSet = C
56、harSet.Ansi,SetLastError=true)ernal sic externDeviceIoControl(Ptr hFile,32 dwIoControlCode,ref USB_NODE_INFORMATION lpInBuffer,32 nInBufferSize,ref USB_NODE_INFORMATION lpOutBuffer,32 nOutBufferSize,out32 lpBytesReturned,Ptr lpOverlapped);DllImport(kernel32.dll, CharSet = CharSet.Ansi, SetLastError=
57、true)ernal sic externDeviceIoControl(Ptr hFile,32 dwIoControlCode,ref USB_NODE_CONNECTION_INFORMATION_EX lpInBuffer,32 nInBufferSize,ref USB_NODE_CONNECTION_INFORMATION_EX lpOutBuffer,32 nOutBufferSize,out32 lpBytesReturned,Ptr lpOverlapped);DllImport(kernel32.dll, CharSet = CharSet.Ansi,SetLastErro
58、r=true)ernal sic externDeviceIoControl(Ptr hFile,32 dwIoControlCode,ref USB_DESCRIPTOR_REQUESTlpInBuffer,32 nInBufferSize,ref USB_DESCRIPTOR_REQUESTlpOutBuffer,32 nOutBufferSize,out32 lpBytesReturned,Ptr lpOverlapped);DllImport(kernel32.dll, CharSet= CharSet.Ansi,SetLastError=true)ernal sic externDe
59、viceIoControl(Ptr hFile,32 dwIoControlCode,ref USB_NODE_CONNECTION_DRIVERKEY_NAME lpInBuffer,32 nInBufferSize,ref USB_NODE_CONNECTION_DRIVERKEY_NAME lpOutBuffer,32 nOutBufferSize,out32 lpBytesReturned,Ptr lpOverlapped);#endregionC#:USB 设备枚举(二)设备枚举 API开发环境:Visual Studio V2010.NET Framework 4 Cnt Prof
60、ile版本历史:V1.02011 年 10 月 10 日基于 WDK 枚举 USB 设备*/usingSystem;usingSystem.Collections.Generic;usingSystem.Management;usingSystem.Runtime.eropServi;usingSystem.Text;namespaplash.IO.PORTS/USB 主控制器信息/public struct HostControllerInfopublic String PNPDeviceID;/ 设备 IDpublic String Name;/ 设备名称/ / USB Hub 信息/ p
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年床头末端装置合作协议书
- 四年级信息技术下册 装饰家园1教学实录 龙教版
- memset使用的注意事项
- 第10课《三峡》教学设计 2024-2025学年统编版语文八年级上册
- 水质提升与水生态修复计划
- 品牌社区建设的实践计划
- 幼儿园日常管理的实施细节计划
- 学校开放日活动安排计划
- 幼儿园学期教学目标探索计划
- 八年级物理上册 第二单元 第3节《我们怎样区分声音(续)》教学实录 (新版)粤教沪版
- 高考文言文阅读训练:《后汉书-严光传》(附答案解析与译文)
- 日本夏日祭活动鉴赏
- 中国教育史笔记全
- 某工业锅炉安装工程监理作业指导书
- 名校《强基计划》初升高衔接数学讲义(上)
- GB/T 41028-2021航空航天流体系统液压软管、管道和接头组件的脉冲试验要求
- GB/T 41-2000六角螺母C级
- GB/T 39391-2020女性卫生裤
- GB/T 11881-2006羽毛球
- 王建业院长-中文LUTS CHINA 调查结果课件
- (部编九下)-不求甚解-教研课公开课比赛课一等奖课件
评论
0/150
提交评论