シリアル COM ポートが既に開いている/使用されているかどうかをプログラムで確認する簡単な方法はありますか?
通常、私は使用します:
try
{
// open port
}
catch (Exception ex)
{
// handle the exception
}
ただし、別のCOMポートなどを使用できるように、プログラムでチェックしたいと思います。
シリアル COM ポートが既に開いている/使用されているかどうかをプログラムで確認する簡単な方法はありますか?
通常、私は使用します:
try
{
// open port
}
catch (Exception ex)
{
// handle the exception
}
ただし、別のCOMポートなどを使用できるように、プログラムでチェックしたいと思います。
デバイスを検索するために、少し前に似たようなものが必要でした。
利用可能な COM ポートのリストを取得し、単純にそれらを反復処理しました。例外がスローされなかった場合は、デバイスと通信しようとしました。少しラフですが、動作します。
var portNames = SerialPort.GetPortNames();
foreach(var port in portNames) {
//Try for every portName and break on the first working
}
これが私がやった方法です:
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, IntPtr securityAttrs, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);
その後
int dwFlagsAndAttributes = 0x40000000;
var portName = "COM5";
var isValid = SerialPort.GetPortNames().Any(x => string.Compare(x, portName, true) == 0);
if (!isValid)
throw new System.IO.IOException(string.Format("{0} port was not found", portName));
//Borrowed from Microsoft's Serial Port Open Method :)
SafeFileHandle hFile = CreateFile(@"\\.\" + portName, -1073741824, 0, IntPtr.Zero, 3, dwFlagsAndAttributes, IntPtr.Zero);
if (hFile.IsInvalid)
throw new System.IO.IOException(string.Format("{0} port is already open", portName));
hFile.Close();
using (var serialPort = new SerialPort(portName, 115200, Parity.None, 8, StopBits.One))
{
serialPort.Open();
}
SerialPort クラスには、いくつかの例外をスローするOpenメソッドがあります。上記のリファレンスには詳細な例が含まれています。
IsOpenプロパティも参照してください。
簡単なテスト:
using System;
using System.IO.Ports;
using System.Collections.Generic;
using System.Text;
namespace SerPort1
{
class Program
{
static private SerialPort MyPort;
static void Main(string[] args)
{
MyPort = new SerialPort("COM1");
OpenMyPort();
Console.WriteLine("BaudRate {0}", MyPort.BaudRate);
OpenMyPort();
MyPort.Close();
Console.ReadLine();
}
private static void OpenMyPort()
{
try
{
MyPort.Open();
}
catch (Exception ex)
{
Console.WriteLine("Error opening my port: {0}", ex.Message);
}
}
}
}
public void MobileMessages(string ComNo, string MobileMessage, string MobileNo)
{
if (SerialPort.IsOpen )
SerialPort.Close();
try
{
SerialPort.PortName = ComNo;
SerialPort.BaudRate = 9600;
SerialPort.Parity = Parity.None;
SerialPort.StopBits = StopBits.One;
SerialPort.DataBits = 8;
SerialPort.Handshake = Handshake.RequestToSend;
SerialPort.DtrEnable = true;
SerialPort.RtsEnable = true;
SerialPort.NewLine = Constants.vbCrLf;
string message;
message = MobileMessage;
SerialPort.Open();
if (SerialPort.IsOpen )
{
SerialPort.Write("AT" + Constants.vbCrLf);
SerialPort.Write("AT+CMGF=1" + Constants.vbCrLf);
SerialPort.Write("AT+CMGS=" + Strings.Chr(34) + MobileNo + Strings.Chr(34) + Constants.vbCrLf);
SerialPort.Write(message + Strings.Chr(26));
}
else
("Port not available");
SerialPort.Close();
System.Threading.Thread.Sleep(5000);
}
catch (Exception ex)
{
message.show("The port " + ComNo + " does not exist, change port no ");
}
}
私にとって何がうまくいったかを共有する(単純なヘルパーメソッド):
private string portName { get; set; } = string.Empty;
/// <summary>
/// Returns SerialPort Port State (Open / Closed)
/// </summary>
/// <returns></returns>
internal bool HasOpenPort()
{
bool portState = false;
if (portName != string.Empty)
{
using (SerialPort serialPort = new SerialPort(portName))
{
foreach (var itm in SerialPort.GetPortNames())
{
if (itm.Contains(serialPort.PortName))
{
if (serialPort.IsOpen) { portState = true; }
else { portState = false; }
}
}
}
}
else { System.Windows.Forms.MessageBox.Show("Error: No Port Specified."); }
return portState;
}
注:
- より高度な手法については、ManagementObjectSearcher Classを使用することをお勧めします。
詳細はこちら.
- Arduino デバイスの場合、ポートを開いたままにします。
- 例外をキャッチする必要がある場合は、Try Catch ブロックを使用することをお勧めします。
- 「TimeoutException」も確認
してください。
- SerialPort (Open) 例外を取得する方法の詳細については、こちらを参照してください。
次のコードを試して、ポートがすでに開いているかどうかを確認できます。確認したいポートが具体的にわからないと思います。
foreach (var portName in Serial.GetPortNames()
{
SerialPort port = new SerialPort(portName);
if (port.IsOpen){
/** do something **/
}
else {
/** do something **/
}
}