问题
I am using Visual Studio 2010 and programing in C# (.NET 3.5).
I want to write/read data from COM10.
Here is the simple code for that:
static void Main(string[] args)
{
String Portname = String.Empty;
/* List out all COM ports present on the computer. */
foreach (string ports in SerialPort.GetPortNames())
{
Console.WriteLine(ports);
/* If COM10 exists, copy the name for further use. */
if (ports == "COM10")
{
Portname = ports; //I also tried this: "\\.\\COM10";
}
}
/* If COM10 not found, return */
if (Portname == String.Empty)
{
Console.WriteLine("Exiting");
return;
}
SerialPort Port = new SerialPort(Portname,
9600, // Baudrate
Parity.None, //Parity
8, //DataBits
StopBits.One); //Stop Bits
Port.Open();
for (int count = 0; count < 5; count++)
{
Port.WriteLine("\nHello");
}
Port.Close();
while (true);
}
Whenever I use Portname
as "COM10" in SerialPort Port = new SerialPort(Portname,9600,.....);
, it gives an error as
The port 'COM10' does not exist
On Port.Open()
, it should not even reach to command Port.Open()
if COM10 doesn't exist.
Another way, I tried Portname as "\.\COM10". It gives an error as
The given port name does not start with COM/com or does not resolve to a valid serial port.
This happens with any port number greater than COM9.
Is there a way out?
回答1:
The reason why you can't open a serial port greater than 10 is because FCL SerialPort implemented like in the following sample:
[MonitoringDescription("PortName")]
[Browsable(true)]
[DefaultValue("COM1")]
public string PortName
{
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get
{
return this.portName;
}
set
{
if (value == null)
throw new ArgumentNullException("PortName");
if (value.Length == 0)
throw new ArgumentException(SR.GetString("PortNameEmpty_String"), "PortName");
if (value.StartsWith("\\\\", StringComparison.Ordinal))
throw new ArgumentException(SR.GetString("Arg_SecurityException"), "PortName");
if (this.IsOpen)
throw new InvalidOperationException(SR.GetString("Cant_be_set_when_open", new object[1]
{
(object) "PortName"
}));
else
this.portName = value;
}
}
As you see, standard SerialPort does not allow you to use \\.\ notation in the port name. And I don't know why they did this. With \\.\ notation, ports greater than 10 can be opened. So, the only way is to implement your own SerialPort component.
回答2:
I don't think GetPortNames() or Open() are causing your issue: my bet is that it's hardware-related. Have you tried your code on a different machine?
Unfortunately, i don't have direct experience with your scenario, since two-digit ports have always worked for me... But there's one thing i'd like to note: i've learned in time that it's better to be safe than sorry, and thus i've increased my usage of try-catch blocks. In your case, i'd do this:
static System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
private static int defaultBaudRate = 9600, defaultDataBits = 8;
static System.IO.Ports.SerialPort TryOpeningPort(string portName)
{
System.IO.Ports.SerialPort port = null;
timer.Start();
try
{
port = new System.IO.Ports.SerialPort(portName,
defaultBaudRate, System.IO.Ports.Parity.None, defaultDataBits, System.IO.Ports.StopBits.One);
port.Open();
port.Close();
/**/Console.WriteLine(portName + " : OK");
}
catch (Exception exceptionInfo) //most common is System.UnauthorizedAccessException
{
port = null;
/**/Console.WriteLine(portName + " -- " + exceptionInfo.GetType().ToString() + " : " + exceptionInfo.Message);
}
timer.Stop();
//Console.WriteLine("Elapsed time : " + timer.ElapsedMilliseconds + "ms" + System.Environment.NewLine);
timer.Reset();
return port;
}
You can call this either directly, as in:
TryOpeningPort("COM10");
or using your initial-check approach:
foreach (string portName in System.IO.Ports.SerialPort.GetPortNames())
if (portName.Equals("Com10", StringComparison.InvariantCultureIgnoreCase))
TryOpeningPort(portName);
回答3:
- For port smaller or equal to 9:
new SerialPort("COM9")
- For port greater than 9:
new SerialPort("\\\\.\\COM10")
I tested the use of the property serialArduino.PortName = ...
for ports greater than 9, but this was always leading to errors, so I used the constructor new SerialPort()
.
来源:https://stackoverflow.com/questions/4677127/accessing-com10-or-greater-port-in-c-sharp