我一直在使用USB设备(HID自定义设备),我写了一些用于测试设备的代码,简单的事情:连接设备的检测和Write-then-Read循环,写入的任务/读取周期是在第一个字节中发送一个64字节的块,命令在第一个字节中发回一个64字节的块,在第一个字节中使用相同的命令,在接下来的六个字节中从1到6的数字,其余的是未初始化的垃圾,然后该块被传递到富文本框以显示。
程序检测到设备并且第一次调用它/写入读取周期它没有问题但是只有第一次,subsecuents调用可能结果正常o或许不是,在没有读取值的情况下是垃圾并且在某些情况下会发生某些事情并且vshost.exe停止工作并关闭我的程序......
这是读取文件的代码:
public bool ReadUSB18F(ref byte[] InBuffer)
{
int Bsize = 65;
InBuffer = new byte[Bsize];
IntPtr UnManagedBuffer = Marshal.AllocHGlobal(Bsize);
IntPtr UnManagedOverlapStruct = Marshal.AllocHGlobal(Marshal.SizeOf(Overlappedbuffer));
Marshal.StructureToPtr(Overlappedbuffer, UnManagedOverlapStruct, false);
if (ReadFile(USBDeviceInfo.ReadHandle, UnManagedBuffer, Bsize, IntPtr.Zero, UnManagedOverlapStruct) == false)
{
if (Marshal.GetLastWin32Error().ToString() == ERROR_IO_PENDING)
{
long bytesreadcount = 0;
bool final = GetOverlappedResult(USBDeviceInfo.ReadHandle, ref Overlappedbuffer, ref bytesreadcount, true);
MessageBox.Show("GetOverlappedResult:"+ final.ToString()+", GetLastWin32Error: " + Marshal.GetLastWin32Error().ToString()+", Byte read count: " + bytesreadcount.ToString());
}
else
{
string error = Marshal.GetLastWin32Error().ToString();
if (error != "0")
{
return false;
}
}
}
Marshal.Copy(UnManagedBuffer, InBuffer, 0, Bsize);
Marshal.FreeHGlobal(UnManagedBuffer);
Marshal.FreeHGlobal(UnManagedOverlapStruct);
return true;
}
我使用两个句柄一个用于读取,另一个用于写入。做一些调试我发现GetOverlappingResult给了一个true和ERROR_IO_PENDING,但是bWait是真的,GetOverlappingResult必须等到读取完成时至少在理论上。
在拼命寻找解决方案的过程中,我放了一个显示GetOverlappingResult结果的消息框,调用函数的错误和读取的字节数,然后发生了一些事情,每当出现错误并出现消息框时(显示有效)在我单击OK的那一刻,GetOverlappingResult给出了true和ERROR_IO_PENDING),所有数据都显示在富文本框中,就像读取操作正确一样,就像魔术一样,我想消息框等待click事件继续给出必要的时间完成读取,但是等待是由GetOverlappingResult完成的,就像GetOverlappingResult不做他们的工作或我做错了。
这些是我对CreateFile,ReadFile,GetOverlappingResult的声明:
[DllImport("kernel32.dll", SetLastError = true)]
public static extern SafeFileHandle CreateFile(
[MarshalAs(UnmanagedType.LPStr)]
string strName,
uint nAccess,
uint nShareMode,
IntPtr lpSecurity,
uint nCreationFlags,
uint nAttributes,
IntPtr lpTemplate
);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool ReadFile
(
SafeFileHandle hFile, // SafeFileHandle to file
IntPtr pBuffer, // data buffer
int NumberOfBytesToRead, // number of bytes to read
IntPtr pNumberOfBytesRead, // number of bytes read
IntPtr OverlappedBuffer
//IntPtr OverlappedBuffer // overlapped buffer
);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetOverlappedResult(
SafeFileHandle hFile,
[In] ref Overlapped lpOverlapped,
ref long lpNumberofBytesTransferred,
bool bWait
);
读写句柄的声明:
USBDeviceInfo.ReadHandle = CreateFile(USBDeviceInfo.DevicePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, IntPtr.Zero);
USBDeviceInfo.WriteHandle = CreateFile(USBDeviceInfo.DevicePath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);
请帮助我们,我已经坚持了一个星期。