.Net SerialPort still locked after application is killed - c#

I have an application which calls SerialPort.Open() ...
This works fine and data is read/written through the port.
However if a user decides to kill the Application through the TaskManager the application will close without calling my destructor calling SerialPort.Close().
This in turn (only sometimes) causes the following error:
Access to the port 'COM2' is denied.
This occurs on re-startup of the application.
I've read enough posts to know that this wouldn't happen if .Close() was properly called.
So far I have handled this by having a timer which reattempts the .Open().. which eventually succeeds (that is I think it does most of the time).
My question is this:
Is there a DLLImport method which will allow me to free the Comm port resource?

I rubbed my crystal ball and it revealed that you are using a USB driver that emulates a serial port, that the user decided it was a good idea to kill the process because she jerked the USB connector out of the socket and that she is running a pre-Vista version of Windows.
Roughly any two combinations out of that list. Yes, doesn't work, you cannot kill a process when it has a kernel thread going that is completing an I/O request that cannot finish. You can tell from TaskMgr.exe when you use View + Select Columns and tick Handles. The process will zombie with one handle opened. Won't close until the driver actually lets go. Won't happen, USB drivers suck like that.
Starting the program again will bomb, the first instance of the process still has the port opened. Access denied.
Tell the user to keep her hands off the connector. Or buy another one from a different manufacturer. You can help by adding a "Safely Remove Hardware" menu option to your program. That calls the SerialPort.Close() method. Call Sleep(2500) and display a message box that it is okay to unplug it.

Related

Until a process has started, do something

So I have a background program that starts with Windows, minimized to system tray icon. Once it loads I need it to constantly start checking if a process has started (for example VLC). Once the process has started, It must wait for it to close in order to start doing stuff and then get back to check if it has started. I've been trying to do this for a while now, but I just can't figure out how.
How would I constantly check if a program has started?
One way would be to have the Background Deamon look for aprogramm of a specific name. Unfortunately this not overly reliable (due to name overlaps), would require a lot of polling and runs the risk of race conditions (the process starting when your deamon is still working).
What would be reliable, is if it is the Deamon that actually starts the foreground process. That way it could do work before Process.Start() and after Process.WaitForExit(), with full information when both states happen: https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process?view=netcore-3.1
Steam is a good example. It is a single-instance process, so any further requests can be relayed to the running instance. The desktop links to programms/games are actually weblinks - not programm links. Those links use the :steam protocoll, wich is associated with the steam processes. So it goes like this:
user klicks on a WebLink with :steam procotoll
Windows resolves to hand this into a commandline call to the steam programm
A instance is started with the proper order in via commandline. Single instancing will not allow a 2nd instanc to start, but hand the request over a already running one
the already or now suddenly running instance calls the programm, having full data on when it starts and ends - being the actuall logical caller

Control console for C# .net program

I'm running a C# .net program under mono on Unix and I'm looking to control or change the behavior of the program after it has started.
I'll write the new functions into the program so I just need to trigger them without restarting the program.
I'm thinking I could allow the program to accept messages such as SOAP but feel this might be insure. It might be better if I could control the program locally from a separate program but i'm unsure of where to start.
Is there a way to give instructions into the program after it has started without a separate program or if the separate program is the solution does anyone know where to start with this?
Thanks!
I think you can create some UI form into your app and you will be able to controll your app by using this UI. If it isn't using you can hide that form to tray.
Or you can use second app and send some messages to your first application by using sockets, for example.
The way this is usually done in Unix programs (reference) is by sending the SIGHUP signal, and letting the program interpret this as a command to reload its configuration file.
Sending a signal can be done from a terminal or script with the Unix kill command (which is named this way because the default signal is SIGTERM to request the process to shut down itself).
This is how you send SIGHUP to a process with a certain PID:
kill -HUP [pid]
You can use the mono UnixSignal class to handle these Unix signals in a .NET program. One way is to use .WaitOne to wait for the signal on a dedicated thread. Another way is by regularly polling .IsSet or .Count.

System.IO.Ports.SerialPort Write() Timeout

The program I'm working on in C# (.Net Framework 2.0) calls for the ability to switch over to a 'remote mode' and send ascii data to another screen via Bluetooth. I'll start by saying I'm not a very experienced programmer, and I know nothing about networking, but after fooling around with the SerialPort class yesterday I was able to work up a little chat program that worked nicely between two Bluetooth-connected devices.
The chat program, however, only sent data when the user hit a button to "send" data. If the two devices weren't properly connected I just threw a TimeoutException along with an error message. The program I'm working on now is much larger, and tries to write data constantly so long as it has the COM port open.
That means if the two devices aren't immediately connected, it has to throw a TimeoutException, and it will continue to throw it, again and again until they ARE properly connected. That's totally unacceptable. It slows the program down to the point where it isn't usable, and litters the Debug output with "TimeoutException Thrown Here" error messages.
Is there a better solution for how to do this? Some way that I can get it to only write the data out if I can confirm that the two devices are connected, without constantly checking (and subsequently getting Timeout Errors while checking).
No. A serial connection is stateless.
This means you don't know if someone is on the other side. All you can do is sending something out and take a look if something meaningful is coming back.
The easiest example for this is the good old analog modem. To find out if it is connected is to send out a AT and check if an OK comes back.
So your solution is the right one, but maybe not properly implemented. You should put your connection built-up sequence into a BackgroundWorker. So these tries will be done in another thread while your GUI stays responsive to the user.

Handling a forced exit

Is there any good way to handle a forced exit in C#?
I have a formless C# application that talks to an LCD over serial. Once the application is running, the only way to kill it is with task manager. The trouble with this is that the program needs to turn the LCD off when it is done, and it doesn't look as if my Application.ApplicationExit event is ever fired in this condition.
Any ideas?
Once the application is running, the only way to kill it is with task manager.
My big idea would be to change this.
Stick an icon in the notification area that the user can use to shut your app down properly, or set it up so that running the app again will instead shut down an already-running instance if one exists, or any other way that sounds like a good idea.
Requiring a user to use Task Manager to shut down your application screams poor design.
Write a code in your program loop (with a timer perhaps) to read a file or a registry key. For example if a file at C:\YOURPROGRAM\CLOSEME contains text "closeme", close your program gracefully. Write another program that write that C:\YOURPROGRAM\CLOSEME file. So, whenever you want to shutdown your program, don't use taskmanager, instead, open second program.
Some options:
Write a separate process with a GUI that can start and stop the main process. For example, when you install the Apache web server on Windows the server itself is installed as a service. It can be started and stopped from the system services management panel, but it also comes with a "monitor" process that sits in the notification area, tells you whether Apache is running and lets you start or stop it manually.
If it's acceptable for your use-case, make the application a console application. You can register a handler for when the user presses CTRL+C (see Console.CancelKeyPress) that performs your cleanup before your process exits. This still won't let you handle someone killing the process from Task Manager, but it's very easy to do and might be good enough depending on your situation.

Is it correct to leave COM1 open all along the program?

Is it correct to leave COM1 open all along the program ?
and close it only in exit from the program ?
thank's in advance
It is quite common to do this, because there will be overhead associated with the open/close operation. You might end up confusing the OS opening and closing it too frequently.
So yes... open it, keep it open (unless there is an error), and close it when you are finished.
The only reason you would close it during the application, is to let other applications share the port.
So far i would say that Fuzz and RaYell are both right (depending on the concrete situation). So for my projects i usually provide a button on my form where you can connect and disconnect the serial port. So you're also able to provide a list of available com ports, where the user can select the desired port and afterwards press connect. So the user is able to decide in the concrete situation if it is needed to close the port or not.
Maybe for more convenience you can also save the last settings, provide some command line arguments, etc. for a better user experience.
If you do that other applications won't be able to use that port until you shutdown your app. That doesn't sound like a good idea, does it? I think you should open it, get/send the data and close it immediately after you are done with it.
It depends on how the hardware attached to it works. When you open/close a port, a hardware signal can be triggered by the UART on one of the pins. I once had a device that would reset itself whenever the port was closed. So, YMMV.
It depends on what your program does and how long it's going to run for. If you're communicating with a modem, for instance, you probably don't want other applications to interrupt your datastream, so in that case you'd keep it open the whole time and close it when finished.
If you're monitoring the status of some external hardware, and only need to check it periodically, it's better to open and close it every time you access it, so other programs can also access it if necessary.

Categories

Resources