MelbourneDeveloper / Device.Net

A C# cross platform connected device framework
MIT License
620 stars 119 forks source link

HidDevice.ReadAsync failed on .NET 6 #225

Open cupsos opened 2 years ago

cupsos commented 2 years ago

Describe the issue

IOException occurred when HidDevice.ReadAsync on TFM .NET 6

Could be related with #224

Your Code

var hidFactory = new FilterDeviceDefinition(vendorId, productId).CreateWindowsHidDeviceFactory();
var device = await hidFactory.GetFirstDeviceAsync();
await device.InitializeAsync();
await device.WriteAsync(command);
var readResult = await device.ReadAsync(); // <-- exception here
System.IO.IOException : An error occurred while attempting to read from the device
---- System.IO.IOException : The parameter is incorrect.

  Stack Trace: 
HidDevice.ReadReportAsync(CancellationToken cancellationToken) line 139
HidDevice.ReadAsync(CancellationToken cancellationToken) line 121
OneTrayDispenserClient.RequestSensorStatusAsync() line 70
TaskExtensions.DumpAsync[T](Task`1 task) line 27
CommandTest.SensorStatus() line 26
--- End of stack trace from previous location ---
----- Inner Stack Trace -----
BufferedFileStreamStrategy.ReadFromNonSeekableAsync(Memory`1 destination, CancellationToken cancellationToken)
WindowsHidHandler.ReadReportAsync(CancellationToken cancellationToken) line 174
HidDevice.ReadReportAsync(CancellationToken cancellationToken) line 129

Info

Avoid this issue on .NET 6

Option 1: specify an AppContext switch or an environment variable

https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/filestream-position-updates-after-readasync-writeasync-completion#recommended-action

Follow this link for how to do. also i think this related with issue But this could be effect to app performance..

Option 2: Use Read() than ReadAsync() in WindowsHidHandler.ReadReportAsync

https://github.com/MelbourneDeveloper/Device.Net/blob/5524cda62e9ac26d65dfec0ca94ca3142da87bb7/src/Hid.Net/Windows/WindowsHidHandler.cs#L165-L183

Option 3: FILE_FLAG_OVERLAPPED 0 in kernel32.CreateFile() on .NET 6

https://github.com/MelbourneDeveloper/Device.Net/blob/5524cda62e9ac26d65dfec0ca94ca3142da87bb7/src/Device.Net/Windows/ApiService.cs#L14-L20

Same approach as #223 but need to runtime check because preprocessor could not solve .net6(app) -> .netstandard2.0(user library) -> Hid.Net. I will make PR soon by option 3

MelbourneDeveloper commented 2 years ago

I've been meaning to do this for quite a while. This is the solution: https://github.com/MelbourneDeveloper/Device.Net/pull/228/files

Usage will be something like this: https://github.com/MelbourneDeveloper/Device.Net/blob/75ddd43f36f74c32dda129c636b25b335b3144c9/src/Device.Net.UnitTests/GetFactoryExtensions.cs#L30

@cupsos

johndcollins commented 2 years ago

Any update on this? I get a similar error when trying to use WriteAndReadAsync on .Net 6.0

The parameter is incorrect.

at Hid.Net.HidDevice.d20.MoveNext() in /_/src/Hid.Net/HidDevice.cs:line 139 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() at Hid.Net.HidDevice.<ReadAsync>d__19.MoveNext() in /_/src/Hid.Net/HidDevice.cs:line 121 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() at Device.Net.DeviceBase.d15.MoveNext() in /_/src/Device.Net/DeviceBase.cs:line 61 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()

Daimonion1980 commented 2 years ago

Same here.

First try to write to my HID Device and ran into this error.

System.IO.IOException: An error occurred while attempting to write to the device
 ---> System.IO.IOException: Falscher Parameter.
   at System.IO.Strategies.BufferedFileStreamStrategy.WriteToNonSeekableAsync(ReadOnlyMemory`1 source, CancellationToken cancellationToken)
   at Hid.Net.Windows.WindowsHidHandler.WriteReportAsync(Byte[] data, Byte reportId, CancellationToken cancellationToken) in /_/src/Hid.Net/Windows/WindowsHidHandler.cs:line 197
   at Hid.Net.HidDevice.WriteReportAsync(Byte[] data, Byte reportId, CancellationToken cancellationToken) in /_/src/Hid.Net/HidDevice.cs:line 175
   --- End of inner exception stack trace ---
   at Hid.Net.HidDevice.WriteReportAsync(Byte[] data, Byte reportId, CancellationToken cancellationToken) in /_/src/Hid.Net/HidDevice.cs:line 179
Hid.Net.HidDevice: Error: Read/Write Error DeviceId: {deviceId}

Working on a sample project who talks to my HID Device with nuget Package 4.3.0-beta

Platform: Windows 10 Device Type: Hid Version: 4.3.0 https://github.com/MelbourneDeveloper/Device.Net/commit/5524cda62e9ac26d65dfec0ca94ca3142da87bb7

Actually I'm not able to compile develop branch with my Visual Studio Version (2022) because net45 is not supported anymore

MelbourneDeveloper commented 2 years ago

Same here.

First try to write to my HID Device and ran into this error.

System.IO.IOException: An error occurred while attempting to write to the device
 ---> System.IO.IOException: Falscher Parameter.
   at System.IO.Strategies.BufferedFileStreamStrategy.WriteToNonSeekableAsync(ReadOnlyMemory`1 source, CancellationToken cancellationToken)
   at Hid.Net.Windows.WindowsHidHandler.WriteReportAsync(Byte[] data, Byte reportId, CancellationToken cancellationToken) in /_/src/Hid.Net/Windows/WindowsHidHandler.cs:line 197
   at Hid.Net.HidDevice.WriteReportAsync(Byte[] data, Byte reportId, CancellationToken cancellationToken) in /_/src/Hid.Net/HidDevice.cs:line 175
   --- End of inner exception stack trace ---
   at Hid.Net.HidDevice.WriteReportAsync(Byte[] data, Byte reportId, CancellationToken cancellationToken) in /_/src/Hid.Net/HidDevice.cs:line 179
Hid.Net.HidDevice: Error: Read/Write Error DeviceId: {deviceId}

Working on a sample project who talks to my HID Device with nuget Package 4.3.0-beta

Platform: Windows 10 Device Type: Hid Version: 4.3.0 https://github.com/MelbourneDeveloper/Device.Net/commit/5524cda62e9ac26d65dfec0ca94ca3142da87bb7

Actually I'm not able to compile develop branch with my Visual Studio Version (2022) because net45 is not supported anymore

4.3.0 is more like the stable version.

Daimonion1980 commented 2 years ago

Actually I was able to figure out what is the problem on my code.

From the TrezorExample.cs I tried to build my Own Class to connect to my device, but was interrupted by the exception:

System.IO.IOException: An error occurred while attempting to write to the device
 ---> System.IO.IOException: Falscher Parameter.

But after changing the writebuffer from 64 to 65 everything was fine and i was able to send the message and to display the answer. I took the size of the writebuffer from TrezorExample.cs

Size 65 is stated everywhere as hid report message size = 64 +1 byte for startbyte. Also @MelbourneDeveloper this written in the documentation https://melbournedeveloper.github.io/Device.Net/articles/HidTransfer.html#use-sendasync-and-readasync

ahmedsiddique-cb commented 9 months ago

Hello,

I am facing the same issue while writing to the hid device, "An error occurred while attempting to write to the device" | false parameter. Even if i change the byte[] size to 64 or 65, nothing seems to work.

I'm using 4.3.0 beta version and i'm using the following code.

var hidFactory = new FilterDeviceDefinition(vId, pId).CreateWindowsHidDeviceFactory(); var device = await hidFactory.GetFirstDeviceAsync(); await device.InitializeAsync(); await device.WriteAndReadAsync(data);