前置き
RS-232で通信してはかりの重量を取得するアプリを作ってるけどCOMポート番号が稀に変わる事があるので自動で設定できるようにしたいなぁと。
そしたらWMIを使ったら取得できるみたいだなぁと。
WMIとは
Windows Management Instrumentation (WMI) で、ハードウェアやソフトウェアの情報取得するインターフェース。詳しくはココ
Powershellで使用すると次のようになる。下記はデバイス情報を取得している。
Get-WmiObject -Query "SELECT * FROM Win32_PnPEntity"
デバイスマネージャなんか開くのめんどくさいぜという方のためにあるような物。
c#でCOMポート番号取得
ManagementObjectSearcher クラスを使うとWMIを使用できる。
using System;
using System.Management;
namespace CheckDeviceConnectionTest
{
class Program
{
static void Main(string[] args)
{
string name = "通信ポート";
DeviceChecker dc = new DeviceChecker();
dc.Name = name;
dc.PartialMactch = true;
if (dc.IsDeviceConnected())
{
Console.WriteLine("Port : " + dc.GetPortName());
}
else
{
Console.WriteLine("接続されていません。");
}
Console.Read();
}
}
class DeviceChecker
{
public string Name { get; set; }
// 部分一致
public bool PartialMactch { get; set; }
private string QueryString
{
get
{
if (PartialMactch)
{
return "SELECT * FROM Win32_PnPEntity WHERE Name LIKE \"%" + Name + "%\"";
}
else
{
return "SELECT * FROM Win32_PnPEntity WHERE Name =" + Name;
}
}
}
public DeviceChecker()
{
PartialMactch = true;
}
// 接続されてるか確認
public bool IsDeviceConnected()
{
ManagementObjectSearcher mos = new ManagementObjectSearcher();
mos.Query.QueryString = QueryString;
var moc = mos.Get();
return moc.Count > 0;
}
// ポート番号取得
public string GetPortName()
{
ManagementObjectSearcher mos = new ManagementObjectSearcher();
var check = new System.Text.RegularExpressions.Regex("(COM[1-9][0-9]?[0-9]?)");
mos.Query.QueryString = QueryString;
var moc = mos.Get();
foreach(var m in moc)
{
string value = m.GetPropertyValue("Name") as string;
if(value == null)
{
continue;
}
if (check.IsMatch(value))
{
var match = check.Match(value);
return match.Captures[0].Value;
}
}
return null;
}
}
}