【C#】Bluetooth機器のMACアドレスによってCOM番号を取得する方法

Bluetooth通信(SPP)によってIoT機器とのシリアル通信を行うWindowsアプリケーション(WinForms)を開発するために、Bluetoothデバイスに割り振られているMACアドレスによってCOM番号を取得するコードを書きました。

前提としてBluetooth機器とWindowsPCがペアリング済み、かつ、SPPで接続可能である必要があります。

環境

サーバ:RFIDリーダライタ
クライアント:Windowsアプリケーション(C# WinForms)

論よりコード
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;
using System.Text.RegularExpressions;

namespace bluetoothspp
{
	class ComPort
	{
		private readonly string[] mComPort = new string[3]; // COM番号。
		
		/// <summary>
		/// パブリックメソッド。Bluetooth機器のCOM番号を取得するサンプル。
		/// </summary>
		/// <param name="aryMacAddr">BluetoothデバイスのMACアドレス</param>
		/// <returns>COM番号</returns>
		public string[] GetComPort(string[] aryMacAddr)
		{
			// WMIデータベース検索用のオブジェクトを作成する。
			ManagementObjectSearcher serialSearcher =
				new ManagementObjectSearcher (
					"root\\CIMV2",
					"SELECT * FROM Win32_SerialPort"
				);

			// シリアルポート情報をクエリに設定する。
			IEnumerable<dynamic> querySerialPort = 
				from ManagementObject obj in serialSearcher.Get()
				select new
				{
					Name = obj["Name"],
					DeviceID = obj["DeviceID"],
					PNPDeviceID = obj["PNPDeviceID"]
				};

			// 上記クエリを実行する。
			foreach (dynamic port in querySerialPort)
			{
				dynamic dynPnpDeviceId = port.PNPDeviceID.ToString();

				Regex regexPortName = new Regex(@"(COM\d+)");
				Match matchComPort = regexPortName.Match(port.Name.ToString());

				if (dynPnpDeviceId.Contains("BTHENUM"))
				{
					// PNPDeviceIDからBluetoothデバイスID(MACアドレス)を取得する。
					dynamic dynBluetoothDeviceAddr = dynPnpDeviceId.Split('&')[4].Split('_')[0];

					if (dynBluetoothDeviceAddr.Length == 12
						&& dynBluetoothDeviceAddr != "000000000000")
					{
						// MACアドレスを整形する。
						string bluetoothDeviceAddr = string.Format (
							"{0}:{1}:{2}:{3}:{4}:{5}",
							dynBluetoothDeviceAddr.Substring(0, 2),
							dynBluetoothDeviceAddr.Substring(2, 2),
							dynBluetoothDeviceAddr.Substring(4, 2),
							dynBluetoothDeviceAddr.Substring(6, 2),
							dynBluetoothDeviceAddr.Substring(8, 2),
							dynBluetoothDeviceAddr.Substring(10, 2)
						);

						// MACアドレスによってCOM番号を特定する。
						foreach (var (macAddr, i) in
							aryMacAddr.Select((macAddr, i) => (macAddr, i)))
						{
							if (matchComPort.Success
								&& macAddr.Equals(bluetoothDeviceAddr))
							{
								mComPort[i] = matchComPort.Groups[1].ToString();
							}
						}
					}
				}
			}

			return mComPort;
		}
	}
}
ポイント

WMIを使用して使用中のCOM番号を全て見つけます。
更に、PNPDeviceIDをフィルタリングしてBluetoothデバイスのMACアドレスを特定します。

参考
How can I find out a COM port number of a bluetooth device in c#?
My company developed a device that communicates with a PC via Bluetooth using a virtual COM port. Now we need a user to pair a device with a PC (MS Windows OS)...
Getting COM port of a bluetooth device by device name in c#
I writing some code in C# to get the COM port where a bluetooth device with a specific name is mapped. I tried several solutions similar to the ones listed here...