SerialPort.GetPortNames() creates System.StackOverflowException - c#

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...

Related

Serial Port "SerialPort.GetPortNames" not reading anything

Trying to code up a little serial port communications/control panel in C# with Visual Studio 2022. I'm making it up as a WindowsForm app using .Net Framework 4.8. When launching the code all the other aspects work fine (as far as I can test them without being able to choose and connect to a paired serial port). In the window it creates I'm able to navigate without a problem but the combo box that should have the serial ports listed in it instead remains blank. Debugging and monitoring the value of "ports" also has it responding with either "error CS0103: The name 'ports' does not exist in the current context" or just "null". Another similar program uses the same logic to obtain the ports created with the virtual port emulator software I am using and this works without a worry.
Early Relevant Code Blocks
public partial class Form1 : Form
{
string dataOUT;
string sendWith;
string dataIN;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string[] ports = SerialPort.GetPortNames();
cBoxCOMPORT.Items.AddRange(ports);
btnOpen.Enabled = true;
btnClose.Enabled = false;
chBxDTR.Checked = false;
serialPort1.DtrEnable = false;
chBxRTS.Checked = false;
serialPort1.RtsEnable = false;
btnSendOut.Enabled = true;
sendWith = "Both";
toolStripComboBox1.Text = "Add to Old Data";
toolStripComboBox2.Text = "Both";
toolStripComboBox3.Text = "BOTTOM";
}
~additional non-relevant functions
}
I'm sure the ports are available as the previous code solution can still find them so I don't think it's a problem with drivers or my virtual comm ports and I've check them on HKEY_LOCAL_MACHINE and they are present. The old solution was made around a week ago so it might be using .NET Framework 4.7.2 instead of 4.8. Regardless I have just copied and adjusted snippets of relevant code across and remade the design layout. There are no compilation errors or warnings either and I am for sure including the "using System.IO.Ports;" line.
I was following a guide provided on YouTube (https://www.youtube.com/watch?v=I6uhMIFTF24) and it worked. I did however have to remake it on a fresh solution and for whatever reason now the same lines of code don't obtain any of the ports made available.
Any help or ideas would be appreciated. No clue where to look or what to fiddle with to get it to find them in this solution.
I think I've found the issue. The Form1 was not triggering the Form1_Load event when launching the program and creating the window Form1 is the main window in the [Design] tab and under its properties the 'Load' box option had no event tied to it. Changed that to be 'Form1_Load' and this now gets that block of code working so it's finding/displaying the COM Ports as well as all the other related set up. Not sure why this wasn't happening by default or if I missed a step creating it. Will add anything else that develops if a similar issue pops up but hopefully that's the end of that.

Can't receive data from c# hidlibrary and QR-Code Scanner

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.

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

C# - Windows Mobile - Pairing with Zebra RW 420

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);

Getting wrong serial-port names from bluetoothdevice (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.

Categories