Below is the basic test I recommended above. I'm using an FTDI chipset and the D2XX driver.
First, run application 1
namespace SerialPortConsole
{
class Program
{
static SerialPort _serialPort;
static void Main(string[] args)
{
_serialPort = new SerialPort("COM3", 9600);
_serialPort.Open();
Console.WriteLine("Close Post? (y/n) ");
string val = Console.ReadLine();
if(val == "y")
{
_serialPort.Close();
}
}
}
}
Next, run application 2 which tries to open the same serial port, "COM3", that application 1 has open.
namespace SerialPortopenTest
{
class Program
{
static SerialPort _serialPort;
static void Main(string[] args)
{
try
{
_serialPort = new SerialPort("COM3", 9600);
Console.WriteLine($"IsOpen: {_serialPort.IsOpen}");
_serialPort.Open();
Console.WriteLine($"IsOpen: {_serialPort.IsOpen}");
_serialPort.Close();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
The results are:
IsOpen: False
Access to the port 'COM3' is denied.
These are the expected results as explained in the SerialPort.IsOpen documentation. The IsOpen property belongs to the current SerialPort instance. The property does not verify if the port is open by another application.
It is up to you to write proper exception handlers and logic flow to handle this situation. A standard try...catch works great. For example...
class Program
{
static SerialPort _serialPort;
static void Main(string[] args)
{
string userInput = "y";
while (userInput == "y")
{
try
{
_serialPort = new SerialPort("COM3", 9600);
Console.WriteLine($"IsOpen: {_serialPort.IsOpen}");
_serialPort.Open();
Console.WriteLine($"IsOpen: {_serialPort.IsOpen}");
_serialPort.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine("Try closing the application that has the port open. Do you want to try opening COM3 at 9600 Baud again (y/n)? ");
userInput = Console.ReadLine();
if(userInput == "n")
{
break;
}
}
}
Console.WriteLine("Goodbye");
}
}