|
|
|
|
@ -1,21 +1,19 @@ |
|
|
|
|
using HidLibrary; |
|
|
|
|
using System; |
|
|
|
|
using System.Linq; |
|
|
|
|
using HidApi; |
|
|
|
|
using System.Text; |
|
|
|
|
|
|
|
|
|
namespace UsbHidTestApp; |
|
|
|
|
namespace UsbHidTestApp_libusb; |
|
|
|
|
|
|
|
|
|
internal class Program |
|
|
|
|
{ |
|
|
|
|
private static HidDevice? _device; |
|
|
|
|
private static HidApi.Device? _device; |
|
|
|
|
private static bool _continue; |
|
|
|
|
private static Thread? readThread; |
|
|
|
|
private static List<HidDevice>? lastDevices; |
|
|
|
|
private static IEnumerable<HidApi.DeviceInfo>? lastDevices; |
|
|
|
|
private static StringComparer stringComparer = StringComparer.OrdinalIgnoreCase; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static bool applicationQuitRequested { get; private set; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void Main(string[] args) |
|
|
|
|
{ |
|
|
|
|
while (applicationQuitRequested == false) |
|
|
|
|
@ -32,23 +30,30 @@ internal class Program |
|
|
|
|
{ |
|
|
|
|
// list devices |
|
|
|
|
case ConsoleKey.L: |
|
|
|
|
List<HidDevice> hidDevices = HidDevices.Enumerate().ToList(); |
|
|
|
|
var hidDevices = Hid.Enumerate(); |
|
|
|
|
List<DeviceInfo> newDevicesDeviceInfo = new(); |
|
|
|
|
Console.WriteLine($"Following HID devices were found: {Environment.NewLine}"); |
|
|
|
|
foreach (var device in hidDevices) |
|
|
|
|
|
|
|
|
|
foreach (var deviceInfo in hidDevices) |
|
|
|
|
{ |
|
|
|
|
bool newDevice = false; |
|
|
|
|
if(lastDevices?.Where(x => x.DevicePath == device.DevicePath).Any() == false) |
|
|
|
|
{ |
|
|
|
|
Console.ForegroundColor = ConsoleColor.Green; |
|
|
|
|
newDevice = true; |
|
|
|
|
} |
|
|
|
|
Console.WriteLine($"-- {device}"); |
|
|
|
|
Console.WriteLine($" {device.Description}"); |
|
|
|
|
if (newDevice) |
|
|
|
|
var device = deviceInfo.ConnectToDevice(); |
|
|
|
|
if (lastDevices?.Where(x => x.Path == device.GetDeviceInfo().Path).Any() == false) |
|
|
|
|
{ |
|
|
|
|
Console.ForegroundColor = ConsoleColor.White; |
|
|
|
|
// add and list later |
|
|
|
|
newDevicesDeviceInfo.Add(deviceInfo); |
|
|
|
|
} |
|
|
|
|
PrintDeviceInfo(deviceInfo); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// print new devices in green |
|
|
|
|
Console.ForegroundColor = ConsoleColor.Green; |
|
|
|
|
foreach (var deviceInfo in newDevicesDeviceInfo) |
|
|
|
|
{ |
|
|
|
|
PrintDeviceInfo(deviceInfo); |
|
|
|
|
} |
|
|
|
|
Console.ForegroundColor = ConsoleColor.White; |
|
|
|
|
newDevicesDeviceInfo.Clear(); // clear list again |
|
|
|
|
|
|
|
|
|
lastDevices = hidDevices; |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
@ -57,11 +62,11 @@ internal class Program |
|
|
|
|
case ConsoleKey.C: |
|
|
|
|
Console.Write($"Write device vendor id as hex: "); |
|
|
|
|
string? vendorIdString = Console.ReadLine(); |
|
|
|
|
int vendorId; |
|
|
|
|
ushort vendorId; |
|
|
|
|
|
|
|
|
|
if (vendorIdString == null || |
|
|
|
|
vendorIdString == "" || |
|
|
|
|
Int32.TryParse(vendorIdString, System.Globalization.NumberStyles.HexNumber, null, out vendorId) == false) |
|
|
|
|
ushort.TryParse(vendorIdString, System.Globalization.NumberStyles.HexNumber, null, out vendorId) == false) |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine($"Invalid vendor ID entered."); |
|
|
|
|
break; |
|
|
|
|
@ -69,39 +74,30 @@ internal class Program |
|
|
|
|
|
|
|
|
|
Console.Write($"Write product vendor id as hex: "); |
|
|
|
|
string? productIdString = Console.ReadLine(); |
|
|
|
|
int productId; |
|
|
|
|
ushort productId; |
|
|
|
|
|
|
|
|
|
if (productIdString == null || |
|
|
|
|
productIdString == "" || |
|
|
|
|
Int32.TryParse(productIdString, System.Globalization.NumberStyles.HexNumber, null, out productId) == false) |
|
|
|
|
ushort.TryParse(productIdString, System.Globalization.NumberStyles.HexNumber, null, out productId) == false) |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine($"Invalid product ID entered."); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var devices = HidDevices.Enumerate(vendorId, productId); |
|
|
|
|
_device = devices.FirstOrDefault();// Where(x => x.DevicePath.Contains("&mi_00")).FirstOrDefault(); |
|
|
|
|
_device = new Device(vendorId, productId); |
|
|
|
|
if (_device == null) |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine("Could not find device."); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_device.OpenDevice(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_device.Inserted += DeviceAttachedHandler; |
|
|
|
|
_device.Removed += DeviceRemovedHandler; |
|
|
|
|
|
|
|
|
|
_continue = true; |
|
|
|
|
readThread = new Thread(Read); |
|
|
|
|
readThread.Start(); |
|
|
|
|
|
|
|
|
|
// not supported apparently: |
|
|
|
|
//_device.MonitorDeviceEvents = true; |
|
|
|
|
//_device.ReadReport(OnReport); |
|
|
|
|
|
|
|
|
|
Console.WriteLine("Connected to device. Write 'quit' to end communication."); |
|
|
|
|
var devInfo = _device.GetDeviceInfo(); |
|
|
|
|
Console.WriteLine($"Connected to device VendorId: 0x{devInfo.VendorId.ToString("X4")}, ProductId: 0x{devInfo.ProductId.ToString("X4")}, Manufacturer: {devInfo.ManufacturerString}."); |
|
|
|
|
Console.WriteLine("Write 'quit' to end communication."); |
|
|
|
|
|
|
|
|
|
while (_continue) |
|
|
|
|
{ |
|
|
|
|
@ -124,9 +120,9 @@ internal class Program |
|
|
|
|
|
|
|
|
|
readThread.Join(); |
|
|
|
|
readThread = null; |
|
|
|
|
_device?.CloseDevice(); |
|
|
|
|
_device.Dispose(); // "close" |
|
|
|
|
Console.WriteLine("Closed connection to device."); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
@ -142,28 +138,15 @@ internal class Program |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static void DeviceRemovedHandler() |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine("Device removed."); |
|
|
|
|
} |
|
|
|
|
Hid.Exit(); //Call at the end of your program |
|
|
|
|
|
|
|
|
|
private static void DeviceAttachedHandler() |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine("Device attached."); |
|
|
|
|
_device?.ReadReport(OnReport); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static void OnReport(HidReport report) |
|
|
|
|
private static void PrintDeviceInfo(DeviceInfo deviceInfo) |
|
|
|
|
{ |
|
|
|
|
if (!_device.IsConnected) { return; } |
|
|
|
|
|
|
|
|
|
var data = report.Data; |
|
|
|
|
|
|
|
|
|
Console.WriteLine(Encoding.ASCII.GetString(data)); |
|
|
|
|
|
|
|
|
|
_device.ReadReport(OnReport); |
|
|
|
|
Console.WriteLine($"-- VendorId: 0x{deviceInfo.VendorId.ToString("X4")}, ProductId: 0x{deviceInfo.ProductId.ToString("X4")}, Manufacturer: {deviceInfo.ManufacturerString}, SerialNumber: {deviceInfo.SerialNumber}, Path:"); |
|
|
|
|
Console.WriteLine($" {deviceInfo.Path}"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static void Read() |
|
|
|
|
@ -172,23 +155,34 @@ internal class Program |
|
|
|
|
{ |
|
|
|
|
try |
|
|
|
|
{ |
|
|
|
|
var readData = _device?.Read(100); |
|
|
|
|
ReadOnlySpan<byte> readData = null; |
|
|
|
|
if(_device != null) |
|
|
|
|
{ |
|
|
|
|
readData = _device.Read(1000); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
Thread.Sleep(20); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (readData != null) |
|
|
|
|
if (readData != null && readData.IsEmpty == false) |
|
|
|
|
{ |
|
|
|
|
string print = Encoding.UTF8.GetString(readData.Data); |
|
|
|
|
string print = Encoding.UTF8.GetString(readData).Substring(2); |
|
|
|
|
//print = print.Replace("\r", "").Replace("\n", ""); // Newline Mode: none |
|
|
|
|
//print = print.Replace("\r", ""); // Newline Mode: only print \n |
|
|
|
|
print = print.Replace("\0", ""); // delete null chars |
|
|
|
|
if(String.IsNullOrEmpty(print) == false) |
|
|
|
|
//print = print.Replace("\0", ""); // delete null chars |
|
|
|
|
if (String.IsNullOrEmpty(print) == false) |
|
|
|
|
{ |
|
|
|
|
Console.Write(print); |
|
|
|
|
Console.WriteLine(print); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
catch (TimeoutException) { } |
|
|
|
|
catch (HidException hidex) |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine($"Got HidException, device likely disconnected: {hidex}"); |
|
|
|
|
Console.WriteLine($"Write 'quit' to end"); |
|
|
|
|
_continue = false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |