I am developing custom HID device. I can see the name in device manager (MyCustomDevice). However when I find the device using DeviceWatcher, the DeviceInformation.Name property has value Unknown USB Device (Port Reset Failed). Other applications using WIN32 apis can get correct name of device without problem.
My code:
// Selector for enabled HID devices
string selector = "System.Devices.InterfaceClassGuid:=\"{4D1E55B2-F16F-11CF-88CB-001111000030}\" AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True";
_watcher = DeviceInformation.CreateWatcher(selector, properties);
_watcher.Added += (s, deviceInformation) => {
Console.WriteLine(deviceInformation.Name); // prints "Unknown USB Device (Port Reset Failed)"
};
Device functions correctly, I can communicate with it - the only problem is this Name. Is there possibility to fix it other than going back to WIN32?
To clarify things:
The device uses standard hidusb.sys driver, and there are no yellow exclamation marks in device manager.
Related
I'm facing a very strange three-way headache. I'm using Unity Engine and a BrainLink Bluetooth device as a source of input. I connect to the BrainLink device automatically via code using a library called Neurosky.ThinkGear and so far these two work fine together, but that's assuming the device has been paired manually via Bluetooth & Other Devices window.
Now I've been asked to also PAIR the device automatically, and this is where I hit a snag. Because using Unity Engine I can't use the windows runtime stuff (like Windows.Enumeration.Devices), I've decided to use the InTheHand 32Feet solution for Bluetooth devices and it seems to kind of work. The device appears as listed in Bluetooth & Other Devices if it wasn't already and it's listed as Paired as well. The problem is that when paired via code and not manually, the library that handles connecting to the device (aforementioned Neurosky.ThinkGear) can't connect to the device. It only connects if the device is removed and paired again via Bluetooth & Oher Devices window.
The Code I'm currently testing is as follows:
private void Start()
{
Debug.Log("Operation Start");
//btClient is a class field
btClient = new BluetoothClient();
//Search for existing paired devices that contain "brainlink" in their name
BluetoothDeviceInfo btDevice = CheckExistingPairedDevices();
if (btDevice == null)
{
Debug.Log("No paired device found, trying to discover");
//Try to discover devices in range with "brainlink" in their name
btDevice = TryDiscoverDevice();
}
if(btDevice!= null)
{
Debug.Log("Found Device " + btDevice.DeviceName+", checking for pairing");
bool paired = AttemptPair(btDevice);
Debug.Log("Pair Status: " + paired);
}
else
{
Debug.Log("Could not discover device");
}
CloseClient();
}
This is the method that handles pairing. At the moment, I never pass a value to pin but it's there just in case I need to support other devices in the future.
private bool AttemptPair(BluetoothDeviceInfo btDevice, string pin = null)
{
//Check if this device has been paired before
if (btDevice.Authenticated)
return true;
bool result = BluetoothSecurity.PairRequest(btDevice.DeviceAddress, pin);
btDevice.Refresh();
return result;
}
I have zero knowledge about your devices/tools, but what I know is that to establish a Bluetooth connection, we need to discover devices first.
The reason is that such a discovery creates an object that is later used on Bluetooth actions (e.g., pairing, connecting).
The device appears as listed in Bluetooth & Other Devices if it wasn't
already and it's listed as Paired as well.
I think by this, what you mean is previously paired devices. The device appearing on the list might not mean that the device is currently discovered. I suggest change your code accordingly where you perform discovery first.
I have a QR-Code Scanner Device which is connected via USB with my Computer. The device itself is set to the HID Keyboard Interface. I tried to detect a new QR-Code with the hidlibrary, but unfortunately I can't get it to work. I am using WPF, C# and .NET Core. I tried something like this:
devices = HidDevices.Enumerate(0x05E0, 0x1200).ToList();
SelectedDevice = devices.FirstOrDefault();
SelectedDevice.OpenDevice();
SelectedDevice.Inserted += SelectedDevice_Inserted;
SelectedDevice.Removed += SelectedDevice_Removed;
SelectedDevice.ReadReport(OnReport);
private void OnReport(HidReport report)
{
if (!SelectedDevice.IsConnected) return;
var byteFromDevice = report.Data;
SelectedDevice.ReadReport(OnReport);
}
private void SelectedDevice_Removed()
{
logger.Info("Scanner device removed!");
}
private void SelectedDevice_Inserted()
{
logger.Info("Scanner device attached");
SelectedDevice.ReadReport(OnReport);
}
I am pretty sure that the VendorID(0x05E0) and the ProductID(0x1200) are correct. For safety I'll attach a screenshot of the device settings from windows. When I try to run this code I get this error message: Operation is not supported on this platform.
I searched a lot on google on how to get the scanned data from a QR-Code Scanner but can't find anything working. This hidlibrary was my last chance but somehow it does not work.
I saw things like getting the KeyDownEvent from the QR-Code Scanner, but the problem is, that the code where I receive the events is not in a Form or Window. Therefore I can't receive these events.
Change your device to "USB Serial" and then use SerialPort Class
See this post for how to read the data.
I have created a watcher to connect to BarcodeScanner using Windows.Devices.PointOfService
var watcher = DeviceInformation.CreateWatcher(BarcodeScanner.GetDeviceSelector());
var id = "";
watcher.Added += async (sender, information) =>
{
id = information.Id;
var barcodeScanner = await BarcodeScanner.FromIdAsync(id);
...
}
information parameter contains all data releted to my barcodeScanner, but when i try to get it with FromIdAsync is always null.
Those are data contained into information
- information {Windows.Devices.Enumeration.DeviceInformation} Windows.Devices.Enumeration.DeviceInformation
EnclosureLocation null Windows.Devices.Enumeration.EnclosureLocation
Id "\\\\?\\HID#VID_0536&PID_02E1&MI_01#c&d907bf5&0&0000#{c243ffbd-3afc-45e9-b3d3-2ba18bc7ebc5}\\POSBarcodeScanner" string
IsDefault false bool
IsEnabled true bool
Kind DeviceInterface Windows.Devices.Enumeration.DeviceInformationKind
Name "3800G" string
+ Pairing {Windows.Devices.Enumeration.DeviceInformationPairing} Windows.Devices.Enumeration.DeviceInformationPairing
+ Properties {System.__ComObject} System.Collections.Generic.IReadOnlyDictionary<string, object> {System.__ComObject}
+ Native View 0x1d148140 <Information not available, no symbols loaded for Windows.Devices.Enumeration.dll> IUnknown *
This device is listed as enabled to be accessed with POS.
Where I'm wrong? I have tried also to create the watcher behind a button click, but nothigs change.
If the model name of the scanner you are using is "3800G" as in the question code, it may not be supported by Windows.Devices.PointOfService.
A list of supported models is below.
Supported Point of Service Peripherals
If you want to use it with Windows.Devices.PointOfService, please change it to the model described in this.
In Addition:
Unified POS standard and Windows® Embedded for Point of Service are OPOS/POS for.NET/JavaPOS API. It is not Windows.Devices.PointOfService API.
That model is not listed on Honeywell's site.
And, sales agencies in Japan may be displayed as sales ended. Probably it is an old model. It is better to switch to a new model.
For example, the USB HID Bar code scanner mode setting is described on page 21 of the detailed manual of 1900 series.
If this mode setting description is not in the 3800G manual, you can not use Windows.Devices.PointOfService API on 3800G.
If you can set it, you will be able to use it if you install a device driver corresponding to this mode.
#Luigi Saggese,
You must first put this scanner into USB HID Barcode Scanner Mode. Please see Page 1-3 of the Honeywell 3800g Users Guide for the programming code to put the scanner into this mode.
Once the scanner is in this mode, you should see a POS Barcode Scanner node in Windows Device Manager. The specific scanner will show up in Device Manager as POS HID Barcode Scanner since it is using an in-box class driver which supports the USB HID POS Scanner protocol. At this point it should work with your Watcher.
Terry Warwick, Microsoft
The context is the following, we have multiple trucks that contains a bluetooth to serial device, we have given each truck bluetooth a unique name to be able to connect to a specific truck.
I use this code to retrieve all the RFComm services :
DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort))
The problem is that all the DeviceInformation objects returned contains the name of the RFComm service in the Name property instead of the bluetooth device name. When my project was a Win 8 store app, all was fine since the name property contained the bluetooth device name.
I found that I could create a BluetoothDevice object using the device id returned by the above code, but then the app ask to use the bluetooth device for all devices until I find the good one. I would like to prevent that as it wasn't the case with Win 8 store app.
Second solution I found was to parse the device id of the RFComm service which look like this one
Bluetooth#Bluetooth00:c2:c6:56:b0:61-00:15:be:0f:02:d7#RFCOMM:00000000:{00001101-0000-1000-8000-00805f9b34fb}
to remove everything past "#RFCOMM" and use the DeviceInformation.CreateFromIdAsync() function. This works but I was wondering if there was a cleaner solution to my problem since parsing a string can be a real problem if the string format change.
Is there a way to retrieve the name of the bluetooth device without having to ask to use all bluetooth device until we find it?
You can try with following code to get the name of the Bluetooth device:
var serviceInfoCollection = await DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort), new string[] { "System.Devices.AepService.AepId" });
foreach (var serviceInfo in serviceInfoCollection)
{
var deviceInfo = await DeviceInformation.CreateFromIdAsync((string)serviceInfo.Properties["System.Devices.AepService.AepId"]);
System.Diagnostics.Debug.WriteLine($"Device name is: '{deviceInfo.Name}' and Id is: '{deviceInfo.Id}'");
}
The key point here is that Bluetooth device is one type of AssociationEndpoint objects. AEPs usually represent a device discovered over a wireless or network protocol. An AssociationEndpoint object is a child of a single AssociationEndpointContainer object and can contain 0 or more AssociationEndpointService objects. And RFComm service is one AssociationEndpointService that Bluetooth device contains. For more info, please see DeviceInformationKind enumeration and Enumerate devices over a network.
AssociationEndpointService has several properties. One of them is System.Devices.AepService.AepId which represents the identifier of the parent AssociationEndpoint object. So we can use this property to get the Bluetooth device information and once we get the device information, we can get the device name easily. However System.Devices.AepService.AepId property is not a commen property in DeviceInformation. So we need to use DeviceInformation.FindAllAsync(String, IIterable(String)) method to require this additional propertie. For more info, please see Device information properties.
Update: This may not be "Pairing". This may just need to have a service started and bound to a port. However, this code is not storing it either. I need the device to be stored even after the application is closed.
I am building a program specifically suited for Zebra RW 420's on a Windows Mobile 6 Handheld device. The application needs to allow a mobile device to pair with the printer on COM1. I believe I am very close to getting it, but I can't get the pair request to work.
I am able to communicate with the printer and even print by directly connecting and printing, but I can't get the mobile device to actually pair with it. I've tried a variation of pins to include null, "1", "0000", and "1234". No matter what, the method always returns false. Any suggestions or ideas why this might be failing? I can pair the device just find in the WM6 Bluetooth menu, but not in my application.
It might be important to note that the little light bulb icon on the printer comes on when the program says it is attempting to pair, but after about 5 to 10 seconds, it fails.
BluetoothSecurity.PairRequest(device, "1"))
Additional Information:
I've successfully paired with my Android phone using this code.
I then logged in and set a PIN on the Zebra printer. However, this code still fails to pair with the printer even when I know the pin is correct / set in the printer.
From https://km.zebra.com/kb/index?page=answeropen&type=open&searchid=1336682809706&answerid=16777216&iqaction=5&url=https%3A%2F%2Fkm.zebra.com%2Fkb%2Findex%3Fpage%3Dcontent%26id%3DSO8031%26actp%3Dsearch%26viewlocale%3Den_US&highlightinfo=6292341,26,43#
Zebra Bluetooth enabled mobile printers are 'slave' devices only. The printers will pair with any 'master' device that tries to make a valid connection. Since only a master device can initiate a connection, the printer does not store pairing data, that function is always done on the master device. The printer can only be connected to one master device at a time, but any number of master devices that have stored pairing information for the printer would be able to initiate a connection to the printer without having to rediscover it.
I'm guessing that this means the InTheHand.Net BluetoothSecurity.PairRequest might not work for this type of pairing?
In the Bluetooth section of the WM handheld, under the "Devices" tab, I can add the device. I need to essentially do that. I need to register the device in that list and then set it to use COM 1 in the "COM Ports" section. The application I am using doesn't actually print. It's sole purpose is to prepare the printer for other applications.
The quote from Zebra make it sounds as pairing is actually not required at all. Are you printing from your app? If so just connect to the SPP service and send the text.
BluetoothAddress addr = ...
Guid serviceClass;
serviceClass = BluetoothService.SerialPort;
var ep = new BluetoothEndPoint(addr, serviceClass);
var cli = new BluetoothClient();
cli.Connect(ep);
Stream peerStream = cli.GetStream();
peerStream.Write ...
(From General Bluetooth Data Connections)
The Zebra Mobile Printer needed to be properly configured before pairing with this method will work. Here is what I did:
First, I ran the following commands on the printer:
.
! U1 setvar "bluetooth.authentication" "setpin"
! U1 getvar "bluetooth.authentication"
! U1 getvar "bluetooth.enable"
! U1 getvar "bluetooth.discoverable"
! U1 setvar "bluetooth.bluetooth_pin" "0000"
! U1 getvar "bluetooth.bluetooth_pin"
Then, the application with this code ran successfully.
.
int pair_req = 0;
try
{
if (BluetoothSecurity.SetPin(device, "0000")) {
while (status == false && pair_req < 3)
{
++pair_req;
status_box.Text = status_box.Text + '\n' + "Attempt " + pair_req.ToString();
status_box.Update();
if (BluetoothSecurity.PairRequest(device, "0000"))
{
status = true;
client.Refresh();
status_box.Text = "Paired Successfully.";
status_box.Update();
Thread.Sleep(5000);
}
else
{
status = false;
}
}
}
}
catch (ArgumentNullException e)
{
status_box.Text = "Pair failed.";
status_box.Update();
Thread.Sleep(5000);
}
status_box.Update();
Thread.Sleep(400);