取得所有連接到電腦上的Serial Port詳細資訊

部分解

方法一

最簡單的方法,就是直接利用SerialPort這個Class來取得。

// A string array consists of port names.
string[] ports2 = SerialPort.GetPortNames();

所以假如你電腦上連接Arduino(COM7),我們就可以把收到的Port放在一個ComboBox下拉式選單裡。

Port Name

摁?要是不看裝置管理員還真不知道Arduino被放在COM7,這種方式雖然可行但太不直觀,於是我們想要取得更詳細一點的資訊,這時就可以利用方法二。

方法二

這個方法是利用ManagementObjectSearcher這個Class去向電腦撈取所有連接裝置的詳細資料。DeviceID就是之後要連Serial Port時可以識別的字串,而Caption就是我們想要的連接埠註解,程式如下。

var searcher = new ManagementObjectSearcher("SELECT DeviceID,Caption FROM WIN32_SerialPort");

foreach (ManagementObject port in searcher.Get())
{
    // ex: COM7
    string name = port.GetPropertyValue("DeviceID").ToString();
    // ex: Arduino Uno (COM7)
    string description = port.GetPropertyValue("Caption").ToString();
    // do what ever you want...
    
}

讓我們來看看結果,成功…嗎?似乎少了什麼,第一張圖中的COM6這個Port不見了!

Port Descriptions

事實上,連接在COM6上的是一個USB轉TTL/RS232序列傳輸介面,由於他只是一個類似轉接頭的東西,並不是一個裝置,所以用第二個方法會把這個Port給漏掉,不過如果沒有此需求的話,其實這樣就可以了。

用這個方法記得要在專案中加入參考System.Management,才可以編譯成功。位置在主選單的專案→加入參考→組件→勾選System.Management→確定。

完整解

為了找到USB轉TTL/RS232序列傳輸介面,只好沿用第一個方法補上。另外,為了存放這些Port的名稱跟描述,自己寫了一個ComProt的結構去做存取。

// custom struct with our desired values
struct ComPort
{
    public string name;
    public string description;
    
    public ComPort(string name, string description)
    {
        this.name = name;
        this.description = description;
    }
}

// Method 2 function
private List<ComPort> GetSerialPort2()
{
    List<ComPort> ports = new List<ComPort>();

    var searcher = new ManagementObjectSearcher("SELECT DeviceID,Caption FROM WIN32_SerialPort");
    foreach (ManagementObject port in searcher.Get())
    {
        // show the service
        ComPort c = new ComPort();
        c.name = port.GetPropertyValue("DeviceID").ToString();
        c.description = port.GetPropertyValue("Caption").ToString();
        ports.Add(c);
    }

    return ports;
}

private List<ComPort> GetAllPorts()
{
    // Method 2
    List<ComPort> ports = GetSerialPort2();
    foreach (ComPort port in ports)
    {
    	ports.Add(port);
    }

    // Method 1
    string[] ports2 = SerialPort.GetPortNames();
    foreach (string port in ports2)
    {
    	// Only need to check the Port Name
        if (!ports.Exists(x => x.name == port))
        {
            ports.Add(new ComPort(port, port));
        }
    }

    return ports;
}

在GetAllPorts涵式中,做了一些檢查以免有Port重複出現,這樣就可以獲取到所有連接到電腦上的裝置了,把得到的Port們放到一個ComboBox下拉式選單裡。

搞定!

 

參考資料

  1. System.IO.Ports.SerialPort – Microsoft Docs

  2. ManagementObjectSearcher Class – Microsoft Docs