Getting wrong serial-port names from bluetoothdevice (c#) - c#

To get all avaliable Serialports from the system i use the following command.
SerialPort.GetPortNames
It works fine for the mainboard serial port, but with the bluetooth device i get the wrong portnames.
For Example: Instead of COM7 i get sometimes COM70 or COM7ö. Its always 1 letter to much.
any suggestens?
PS: I am using newest Visual Studio Express in Windows 7
PPS: The dirty hack to cut the last letter didn't work because i don't know which one is the bluetooth serial port (with various bluetoothstick or devices it changes the number of the comport) and after trying various sticks i reached COM10, ergo COM100 or COM10f
EDIT: the code i am using right now. reading the regestry, but still the same problem.
RegistryKey myRegistry = Registry.LocalMachine.OpenSubKey("Hardware\\DeviceMap\\SerialComm");
foreach (string valuename in myRegistry.GetValueNames())
{
if (myRegistry.GetValue(valuename) is String)
{
if (valuename.Contains("BthModem"))
{
richTextBox1.AppendText(">" + myRegistry.GetValue(valuename) + "<" + Environment.NewLine);
}
}
}
Normally the second or third request is working with a result like
COM11ᯋ<
COM10S<
COM11<
COM10<
COM11<
COM10<
how can that be?

This has been reported as a bug with non-null terminated strings:
Can you manually walk the registry?
HKLM\Hardware\DeviceMap\SerialComm

You can utilize WMI to query the system for serial ports, including those that are added by bluetooth devices and USB-To-Serial devices. Maybe that way you won't encounter this issue. See at CodeProject.

I have the same issue. SerialPort.GetPortNames basically uses the registry anyway- both of those methods don't seem to work with bluetooth.
The workaround I'm currently using is to loop through the first X com ports and see if they exist, which is hardly elegant. MS: FAIL.

Related

Read data via bluetooth using c#

I am using Lecia Disto e7100i which basically measures distance and area using laser. This device has bluetooth and can be paired with windows.
I am trying to develop an wpf app that reads the mesaured data using c#
There is no sdk that comes along with the device.
I have tried to use 32feet.Net but since there is no proper documentation I don't know where to start.
Is there any way that I can do to solve my problem?
This is not a full response, instead its more of a guideline on how to resolve your issue:
Pair the device with your Computer
Run the included software that displays the data somehow
Use WireShark to analyze the traffic
see if it is a standard protocol type or something custom
understand the protocol and reimplement it using c# and BluetoothSockets
To get started, you can try:
var client = new BluetoothClient();
// Select the bluetooth device
var dlg = new SelectBluetoothDeviceDialog();
DialogResult result = dlg.ShowDialog(this);
if (result != DialogResult.OK)
{
return;
}
BluetoothDeviceInfo device = dlg.SelectedDevice;
BluetoothAddress addr = device.DeviceAddress;
Console.WriteLine(device.DeviceName);
BluetoothSecurity.PairRequest(addr, "PIN"); // set the pin here or take user input
device.SetServiceState(BluetoothService.HumanInterfaceDevice, true);
Thread.Sleep(100); // Precautionary
if (device.InstalledServices.Length == 0)
{
// handle appropriately
}
client.Connect(addr, BluetoothService.HumanInterfaceDevice);
Also make sure that
Device appears in "Bluetooth devices" in the "Control panel".
Device is HID or change code accordingly.
Hope it helps. Cheers!
Try this demo project, and the following articles after that one.
Try to follow this tutorial
Here you can see a direct answer by the mantainer of 32feet, with which you can get in touch
Check also this answer

SerialPort.GetPortNames() creates System.StackOverflowException

I've made a Bootloader implementation in a SAMD21J18A mcu, based on a
Atmel example. I can connect to the bootloader via USB CDC and it is recognized in windows as a COM port with the name: AT91 USB to Serial Converter, not showing any problems.
The COM-port works fine, I've made a working Windows Form C# program to download code to the bootloader. In the working program I've just manually set the PortName.
Now, I want to make the program more user friendly and want to make a ComboBoxto enable the user to pick the COM-port to use. Therefore I'm calling the GetPortNames function:
string[] Ports = null;
Ports = SerialPort.GetPortNames();
This works fine, as long as I don't plugin my bootloader.
If I attach eg. a FTDI device, it detects the device and adds it to the list, but if I attach the Bootloader("AT91 USB to Serial Converter"), then I get a System.StackOverflowException on the SerialPort.GetPortNames() function.
Does anyone know what is wrong with GetPortNames or the USB CDC driver?
Thanks for your help mjwills :-)
The complete program were too large to show here, so I decided to make a short program showing the problem. However, the new short program didn't have this problem. So, found out the problem didn't directly originate from the line refered to by visual studio.
Anyway, here's the function which created the problem:
// Update comport pull-down list:
private void UpdateComPortList()
{
string[] Ports = null;
Ports = SerialPort.GetPortNames();
int index = -1;
string ComPortName = null;
comboBoxComPort.Items.Clear();
do
{
index += 1;
comboBoxComPort.Items.Add(Ports[index]);
//if(Properties.Settings.Default.comPort == Ports[index]) comboBoxComPort.SelectedIndex = index;
}
while (!((Ports[index] == ComPortName) || (index == Ports.GetUpperBound(0))));
comboBoxComPort.Items.Add("update list...");
}
If I remove the line which I've now commented, the program works.
I think the problem is that, I try to select an item while at the same time adding items...

Cannot create UsbDevice from DeviceInformation.Id

I'm trying to connect to a device (SecuGen Hamster Pro 20) through Windows.Devices.Usb APIs using Universal Windows App for PC only (no phones)(WinRT).
The device is a fingerprint scanner.
I've done all the steps found online to do that:
I've looked for all devices using:
var myDevices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync();
This returns about 1400 devices. After some filteration using:
var resultList = myDevices.Where(s => s.Name.ToLower().Contains("secu")).ToList<DeviceInformation>();
resultList contains 3 devices in my machine (I've tried it on other machine and found 10 results on some).
I didn't use the overload for finding devices DeviceInformation.FindAllAsync(String aqsFilter) because it returns 0 results althought I'm sure I've done it right (used correct VID & PID)
The problem here is when I try to create a UsbDevice object from any of the 3 results using:
UsbDevice device = await UsbDevice.FromIdAsync(resultList[0].Id);
The return value is null, I've tried all of them (resultList[0] , resultList[1] , resultList[2]) with no luck.
I configured the capabilities using:
<DeviceCapability Name="usb">
<Device Id="vidpid:1162 2200">
<Function Type="name:vendorSpecific"/>
</Device>
</DeviceCapability>
I also tried to create a UsbDevice object from any of the 1400 devices returned from DeviceInformation.FindAllAsync() but all returned null and even some throw an exception that says the system cannot find the file specified 0x80070002
I tried to read DeviceAccessInformation for the device it returned DeviceAccessStatus.Unspecified
Anyone can lead me to what am I missing here?
You have to use UsbDevice.GetDeviceSelector and then use the selector when searching for the device. If that returns nothing, then the device isn't properly 'configured' to use the WinUSB.sys driver. (And from what I understand, it must use that driver to be used with the usbdevice class).
If you manually told it to use that driver in the device manager, then, in theory, you still have to change a key with regedit before that works (Note: I did that and it still wouldn't work). I found a solution that solved it here:
http://www.lewisbenge.net/2013/09/20/integrating-windows-8-1-with-owi-535-robotic-arm/
Basically, you have to install the driver using an inf file. use the one linked on that site and replace the NTamd64 with NTarm depending on the target platform
Firstly, try to narrow down your search by vendor and product Id
This method will help you do that:
public static async Task<List<wde.DeviceInformation>> GetDevicesByProductAndVendorAsync(int vendorId, int productId)
{
return ((IEnumerable<wde.DeviceInformation>)await wde.DeviceInformation.FindAllAsync($"System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True AND System.DeviceInterface.Hid.VendorId:={vendorId} AND System.DeviceInterface.Hid.ProductId:={productId} ").AsTask()).ToList();
}
https://github.com/MelbourneDeveloper/Hid.Net/blob/c69e3368343e59e51e8818c87dbea00e6ccfecae/Hid.Net.UWP/UWPHelpers.cs#L11
You will be able to get a list of connected devices from that. You should then be able to connect with FromIdAsync.

How do i reset the system cache of WLAN info?

I am trying to write a WLAN fingerprinting program using NativeWifi in C#. To do this i run a loop to get the wlan information many times and then later use matlab to average / analyze the data.
The problem is that i get all the same values, even as i move about the house, when the program is running. From the internet i've seen that there is a cache that stores the data of available networks. I was wondering if there is a system call which resets this cache.
I have also seen this using the cmd call
netsh wlan show networks mode=bssid
this gives me the same values until i open the available wifi networks in my OS and if i run it again after, it will give different values.
edit: This system will be for my use only, so i would be comfortable starting over on a linux platform if there is a known library that can handle this for me. I don't even know what to google to even get the information, though. Anything related to "network cache" takes me to help threads of unrelated topics...
I will provide the relevant part of my code below:
public void get_info_instance(StreamWriter file)
{
try
{
foreach (WlanClient.WlanInterface wlanIface in client.Interfaces)
{
Wlan.WlanBssEntry[] wlanBssEntries = wlanIface.GetNetworkBssList();
foreach (Wlan.WlanBssEntry network in wlanBssEntries)
{
int rss = network.rssi;
byte[] macAddr = network.dot11Bssid;
string tMac = "";
for (int i = 0; i < macAddr.Length; i++)
{
tMac += macAddr[i].ToString("x2").PadLeft(2, '0').ToUpper();
}
file.WriteLine("Found network: " + System.Text.ASCIIEncoding.ASCII.GetString(network.dot11Ssid.SSID).ToString());
file.WriteLine("Signal: " + network.linkQuality + "%");
file.WriteLine("BSS Type: " + network.dot11BssType + ".");
file.WriteLine("RSSID: " + rss.ToString());
file.WriteLine("BSSID: " + tMac);
file.WriteLine(" ");
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Internally, netsh is powered by this API. What this means, is that calling netsh wlan show networks mode=bssid just returns the cache of the networks that showed up during the last scan. This is what you've discovered.
This means that in order to refresh this cache, you need to trigger a scan. If your C# library you are using includes it, you could make this happen on demand with a call to WlanScan. I am not sure which C# wrapper you are using, but it probably includes this function. When you get a scan complete notification (register with source WLAN_NOTIFICATION_SOURCE_ACM and look out for wlan_notification_acm_scan_list_refresh), the cache should be updated.
If you let me know which C# library you are using, maybe I can point you to the relevant functions.
You mentioned that opening the available networks causes the cache to refresh. This is because opening the available networks triggers a call to WlanScan.
Profiles are not relevant to the available network list -- profiles are what the Wlan service uses to keep track of which networks are configured on your machine -- deleting them does not make WlanSvc scan again. It may be a coincidence that deleting them happens to coincide with a scan, but it is more of a side effect than the designed usage.
edit: to subscribe to notifications using the Managed Wifi API you are using, this snippet should work:
wlanIface.WlanNotification += wlanIface_WlanNotification;
And the callback:
static void wlanIface_WlanNotification(Wlan.WlanNotificationData notifyData)
{
if (notifyData.notificationCode == (int)Wlan.WlanNotificationCodeAcm.ScanComplete)
{
Console.WriteLine("Scan Complete!");
}
}
You can test this by running this, then opening the available networks on Windows. You should see "Scan Complete" shortly after you open it each time. You can use a messagebox instead of Console.WriteLine if you prefer.
To trigger a scan yourself:
wlanIface.Scan();
for all
netsh wlan delete profile name=* i=*
you might not want to do it on all interfaces, and hard code the interface in there for faster result

How to find out status of a usb device using c#?

i am creating a project related to power consumed by our computer systems.
now my requirement is ,
i need to find out power consumed by a usb device(like pendrive) in the system.
can anybody plz help me.
I don't think you can because the USB specification seems not to mention anything about delivering those measurements. The only information I know you can get is if the device is a low-power or high-power device. For USB 2.0 that is 100mA or 500mA with a voltage between 4.4 and 5.25V. So a low-power power device may consume from almost 0 to 5.25*0.1=0,525W and a high-power up to 5.25*0.5=2.625W.
Unfortunately the WMI classes doesn't seem to give you even that information but that could be just me looking at the wrong places.
//using System.Management
var USBDevices = new ManagementObjectSearcher(#"Select * From Win32_USBControllerDevice");
foreach (var device in USBDevices.Get())
{
foreach (var prop in device.Properties)
{
Console.WriteLine(prop.Name + " : " + prop.Value);
}
}
You might have a look at http://www.sharpdevelop.net/OpenSource/SharpUSBLib/default.aspx
An USB library by the creators of SharpDevelop (at least on the same server)

Categories