using HidApi; using System.Text; namespace UsbHidTestApp_libusb; internal class Program { private static HidApi.Device? _device; private static bool _continue; private static Thread? readThread; private static IEnumerable? lastDevices; private static StringComparer stringComparer = StringComparer.OrdinalIgnoreCase; public static bool applicationQuitRequested { get; private set; } static void Main(string[] args) { while (applicationQuitRequested == false) { Console.WriteLine($"----- USB HID PROTOCOL TEST APP -----"); Console.WriteLine($"Command list:"); Console.WriteLine($"l = list devices"); Console.WriteLine($"c = connect"); Console.WriteLine($"q = quit"); var key = Console.ReadKey(); switch (key.Key) { // list devices case ConsoleKey.L: var hidDevices = Hid.Enumerate(); Console.WriteLine($"Following HID devices were found: {Environment.NewLine}"); foreach (var deviceInfo in hidDevices) { bool newDevice = false; var device = deviceInfo.ConnectToDevice(); if (lastDevices?.Where(x => x.Path == device.GetDeviceInfo().Path).Any() == false) { Console.ForegroundColor = ConsoleColor.Green; newDevice = true; } Console.WriteLine($"-- VendorId: 0x{deviceInfo.VendorId.ToString("X4")}, ProductId: 0x{deviceInfo.ProductId.ToString("X4")}, Manufacturer: {deviceInfo.ManufacturerString}, Path:"); Console.WriteLine($" {deviceInfo.Path}"); if (newDevice) { Console.ForegroundColor = ConsoleColor.White; } } lastDevices = hidDevices; break; // connect case ConsoleKey.C: Console.Write($"Write device vendor id as hex: "); string? vendorIdString = Console.ReadLine(); ushort vendorId; if (vendorIdString == null || vendorIdString == "" || ushort.TryParse(vendorIdString, System.Globalization.NumberStyles.HexNumber, null, out vendorId) == false) { Console.WriteLine($"Invalid vendor ID entered."); break; } Console.Write($"Write product vendor id as hex: "); string? productIdString = Console.ReadLine(); ushort productId; if (productIdString == null || productIdString == "" || ushort.TryParse(productIdString, System.Globalization.NumberStyles.HexNumber, null, out productId) == false) { Console.WriteLine($"Invalid product ID entered."); break; } _device = new Device(vendorId, productId); if (_device == null) { Console.WriteLine("Could not find device."); break; } _continue = true; readThread = new Thread(Read); readThread.Start(); 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) { var message = Console.ReadLine(); if (stringComparer.Equals("quit", message)) { _continue = false; } else { byte[] msgBytes = Encoding.ASCII.GetBytes(message!); List listBytes = new List(); listBytes.Add((byte)' '); // temp fix for first sign wrong listBytes.AddRange(msgBytes); listBytes.Add((byte)'\n'); _device.Write(listBytes.ToArray()); } } readThread.Join(); readThread = null; _device.Dispose(); // "close" Console.WriteLine("Closed connection to device."); break; // quit case ConsoleKey.Q: applicationQuitRequested = true; break; default: Console.WriteLine($"{Environment.NewLine}Did not recognize key.. {Environment.NewLine}"); break; } } Hid.Exit(); //Call at the end of your program } public static void Read() { while (_continue) { try { ReadOnlySpan readData = null; if(_device != null) { readData = _device.Read(1000); } else { Thread.Sleep(20); } if (readData != null && readData.IsEmpty == false) { string print = Encoding.UTF8.GetString(readData); //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) { Console.WriteLine(print); } } } catch (HidException hidex) { Console.WriteLine($"Got HidException, device likely disconnected: {hidex}"); Console.WriteLine($"Write 'quit' to end"); _continue = false; } } } }