获取串口信息

问题描述 投票:0回答:9

我有一些代码将串行端口加载到组合框中:

     List<String> tList = new List<String>(); 

     comboBoxComPort.Items.Clear();

     foreach (string s in SerialPort.GetPortNames())
     {
        tList.Add(s);
     }

     tList.Sort();
     comboBoxComPort.Items.Add("Select COM port...");
     comboBoxComPort.Items.AddRange(tList.ToArray());
     comboBoxComPort.SelectedIndex = 0;

我想将端口描述(类似于设备管理器中 COM 端口显示的内容)添加到列表中 并对列表中索引 0 之后的项目进行排序(已解决:请参阅上面的代码片段)。有人对添加端口描述有什么建议吗?我正在使用 Microsoft Visual C# 2008 Express Edition (.NET 2.0)。如果您有任何想法,我们将不胜感激。谢谢。

c# sorting combobox serial-port
9个回答
50
投票

我在这里尝试了很多解决方案,但对我来说不起作用,只显示了一些端口。但下面显示了所有这些人和他们的信息。

        using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE Caption like '%(COM%'"))
        {
            var portnames = SerialPort.GetPortNames();
            var ports = searcher.Get().Cast<ManagementBaseObject>().ToList().Select(p => p["Caption"].ToString());

            var portList = portnames.Select(n => n + " - " + ports.FirstOrDefault(s => s.Contains(n))).ToList();
            
            foreach(string s in portList)
            {
                Console.WriteLine(s);
            }
        }
    

43
投票

编辑:抱歉,我很快就跳过了你的问题。我现在意识到您正在寻找包含端口名称+端口描述的列表。我已经相应地更新了代码...

使用System.Management,您可以查询所有端口,以及每个端口的所有信息(就像设备管理器...)

示例代码(确保添加对 System.Management 的引用):

using System;
using System.Management;
using System.Collections.Generic;
using System.Linq;
using System.IO.Ports;        

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var searcher = new ManagementObjectSearcher
                ("SELECT * FROM WIN32_SerialPort"))
            {
                string[] portnames = SerialPort.GetPortNames();
                var ports = searcher.Get().Cast<ManagementBaseObject>().ToList();
                var tList = (from n in portnames
                            join p in ports on n equals p["DeviceID"].ToString()
                            select n + " - " + p["Caption"]).ToList();

                tList.ForEach(Console.WriteLine);
            }

            // pause program execution to review results...
            Console.WriteLine("Press enter to exit");
            Console.ReadLine();
        }
    }
}

更多信息在这里:http://msdn.microsoft.com/en-us/library/aa394582%28VS.85%29.aspx


34
投票

使用以下代码片段

执行时会给出以下输出。

serial port : Communications Port (COM1)
serial port : Communications Port (COM2)

别忘了添加

using System;
using System.Management;
using System.Windows.Forms;

还添加对

system.Management
的引用(默认情况下不可用)

C#

private void GetSerialPort()
{

    try
    {
        ManagementObjectSearcher searcher = 
            new ManagementObjectSearcher("root\\CIMV2", 
            "SELECT * FROM Win32_PnPEntity"); 

        foreach (ManagementObject queryObj in searcher.Get())
        {
            if (queryObj["Caption"].ToString().Contains("(COM"))
            {
                Console.WriteLine("serial port : {0}", queryObj["Caption"]);
            }

        }
    }
    catch (ManagementException e)
    {
        MessageBox.Show( e.Message);
    }

}

VB

  Private Sub GetAllSerialPortsName()
        Try
            Dim searcher As New ManagementObjectSearcher("root\CIMV2", "SELECT * FROM Win32_PnPEntity")
            For Each queryObj As ManagementObject In searcher.Get()
                If InStr(queryObj("Caption"), "(COM") > 0 Then
                    Console.WriteLine("serial port : {0}", queryObj("Caption"))
                End If
            Next
        Catch err As ManagementException
            MsgBox(err.Message)
        End Try
    End Sub

更新: 您还可以检查

if (queryObj["Caption"].ToString().StartsWith("serial port"))

而不是

if (queryObj["Caption"].ToString().Contains("(COM"))

21
投票

这里的答案都不能满足我的需求。

Muno 的答案是错误,因为它只列出了 USB 端口。

code4life 的答案是错误,因为它列出了除 USB 端口之外的所有端口。 (尽管如此,它还是有 44 票赞成!!!)

我的计算机上有一个 EPSON 打印机模拟端口,此处的任何答案均未列出该端口。所以我必须编写自己的解决方案。此外,我想显示更多信息,而不仅仅是标题字符串。我还需要将端口名称与描述分开。

我的代码已在 Windows XP、7、10 和 11 上进行了测试。

端口名称(如“COM1”)必须从 注册表 中读取,因为 WMI 不会为所有 COM 端口 (EPSON) 提供此信息。

如果您使用我的代码,您将不再需要SerialPort.GetPortNames()。我的函数返回相同的端口,但有更多详细信息。微软为什么不把这样的功能实现到框架中呢??

using System.Management;
using Microsoft.Win32;

using (ManagementClass i_Entity = new ManagementClass("Win32_PnPEntity"))
{
    foreach (ManagementObject i_Inst in i_Entity.GetInstances())
    {
        Object o_Guid = i_Inst.GetPropertyValue("ClassGuid");
        if (o_Guid == null || o_Guid.ToString().ToUpper() != "{4D36E978-E325-11CE-BFC1-08002BE10318}")
            continue; // Skip all devices except device class "PORTS"

        String s_Caption  = i_Inst.GetPropertyValue("Caption")     .ToString();
        String s_Manufact = i_Inst.GetPropertyValue("Manufacturer").ToString();
        String s_DeviceID = i_Inst.GetPropertyValue("PnpDeviceID") .ToString();
        String s_RegPath  = "HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Enum\\" + s_DeviceID + "\\Device Parameters";
        String s_PortName = Registry.GetValue(s_RegPath, "PortName", "").ToString();

        int s32_Pos = s_Caption.IndexOf(" (COM");
        if (s32_Pos > 0) // remove COM port from description
            s_Caption = s_Caption.Substring(0, s32_Pos);

        Console.WriteLine("Port Name:    " + s_PortName);
        Console.WriteLine("Description:  " + s_Caption);
        Console.WriteLine("Manufacturer: " + s_Manufact);
        Console.WriteLine("Device ID:    " + s_DeviceID);
        Console.WriteLine("-----------------------------------");
    }
}

我用很多 COM 端口测试了代码。这是控制台输出:

Port Name: COM29 Description: CDC Interface (Virtual COM Port) for USB Debug Manufacturer: GHI Electronics, LLC Device ID: USB\VID_1B9F&PID_F003&MI_01\6&3009671A&0&0001 ----------------------------------- Port Name: COM28 Description: Teensy USB Serial Manufacturer: PJRC.COM, LLC. Device ID: USB\VID_16C0&PID_0483\1256310 ----------------------------------- Port Name: COM25 Description: USB-SERIAL CH340 Manufacturer: wch.cn Device ID: USB\VID_1A86&PID_7523\5&2499667D&0&3 ----------------------------------- Port Name: COM26 Description: Prolific USB-to-Serial Comm Port Manufacturer: Prolific Device ID: USB\VID_067B&PID_2303\5&2499667D&0&4 ----------------------------------- Port Name: COM1 Description: Comunications Port Manufacturer: (Standard port types) Device ID: ACPI\PNP0501\1 ----------------------------------- Port Name: COM999 Description: EPSON TM Virtual Port Driver Manufacturer: EPSON Device ID: ROOT\PORTS\0000 ----------------------------------- Port Name: COM20 Description: EPSON COM Emulation USB Port Manufacturer: EPSON Device ID: ROOT\PORTS\0001 ----------------------------------- Port Name: COM8 Description: Standard Serial over Bluetooth link Manufacturer: Microsoft Device ID: BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMFG&000F\8&3ADBDF90&0&001DA568988B_C00000000 ----------------------------------- Port Name: COM9 Description: Standard Serial over Bluetooth link Manufacturer: Microsoft Device ID: BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMFG&0000\8&3ADBDF90&0&000000000000_00000002 ----------------------------------- Port Name: COM30 Description: Arduino Uno Manufacturer: Arduino LLC (www.arduino.cc) Device ID: USB\VID_2341&PID_0001\74132343530351F03132 -----------------------------------

COM1是主板上的COM口。

COM 8 和 9 是蓝牙 COM 端口。

COM 25 和 26 是 USB 转 RS232 适配器。

COM 28、29 和 30 是类似 Arduino 的板。

COM 20 和 999 是 EPSON 端口。


17
投票
帖子

获取有关 C# 中串口的更多信息

嗨拉文布,

我们无法通过SerialPort类型获取信息。我不知道为什么您的应用程序中需要此信息。但是,有一个“已解决的线程”与您有相同的问题。您可以查看那里的代码,看看它是否可以帮助您。

如果您还有任何问题,请随时告诉我。 最诚挚的问候, 周布鲁斯

该帖子中的链接指向此帖子:

如何使用 System.IO.Ports.SerialPort 获取有关端口的更多信息

您可能可以从 WMI 查询中获取此信息。查看此工具以帮助您找到正确的代码。你为什么要关心呢?这只是USB仿真器的一个细节,普通串口不会有这个。串行端口只是“COMx”,仅此而已。

我结合了以前的答案并使用了 Win32_PnPEntity 类的结构,可以在
here

12
投票

using System.Management; public static void Main() { GetPortInformation(); } public string GetPortInformation() { ManagementClass processClass = new ManagementClass("Win32_PnPEntity"); ManagementObjectCollection Ports = processClass.GetInstances(); foreach (ManagementObject property in Ports) { var name = property.GetPropertyValue("Name"); if (name != null && name.ToString().Contains("USB") && name.ToString().Contains("COM")) { var portInfo = new SerialPortInfo(property); //Thats all information i got from port. //Do whatever you want with this information } } return string.Empty; } SerialPortInfo 类:

public class SerialPortInfo
{
    public SerialPortInfo(ManagementObject property)
    {
        this.Availability = property.GetPropertyValue("Availability") as int? ?? 0;
        this.Caption = property.GetPropertyValue("Caption") as string ?? string.Empty;
        this.ClassGuid = property.GetPropertyValue("ClassGuid") as string ?? string.Empty;
        this.CompatibleID = property.GetPropertyValue("CompatibleID") as string[] ?? new string[] {};
        this.ConfigManagerErrorCode = property.GetPropertyValue("ConfigManagerErrorCode") as int? ?? 0;
        this.ConfigManagerUserConfig = property.GetPropertyValue("ConfigManagerUserConfig") as bool? ?? false;
        this.CreationClassName = property.GetPropertyValue("CreationClassName") as string ?? string.Empty;
        this.Description = property.GetPropertyValue("Description") as string ?? string.Empty;
        this.DeviceID = property.GetPropertyValue("DeviceID") as string ?? string.Empty;
        this.ErrorCleared = property.GetPropertyValue("ErrorCleared") as bool? ?? false;
        this.ErrorDescription = property.GetPropertyValue("ErrorDescription") as string ?? string.Empty;
        this.HardwareID = property.GetPropertyValue("HardwareID") as string[] ?? new string[] { };
        this.InstallDate = property.GetPropertyValue("InstallDate") as DateTime? ?? DateTime.MinValue;
        this.LastErrorCode = property.GetPropertyValue("LastErrorCode") as int? ?? 0;
        this.Manufacturer = property.GetPropertyValue("Manufacturer") as string ?? string.Empty;
        this.Name = property.GetPropertyValue("Name") as string ?? string.Empty;
        this.PNPClass = property.GetPropertyValue("PNPClass") as string ?? string.Empty;
        this.PNPDeviceID = property.GetPropertyValue("PNPDeviceID") as string ?? string.Empty;
        this.PowerManagementCapabilities = property.GetPropertyValue("PowerManagementCapabilities") as int[] ?? new int[] { };
        this.PowerManagementSupported = property.GetPropertyValue("PowerManagementSupported") as bool? ?? false;
        this.Present = property.GetPropertyValue("Present") as bool? ?? false;
        this.Service = property.GetPropertyValue("Service") as string ?? string.Empty;
        this.Status = property.GetPropertyValue("Status") as string ?? string.Empty;
        this.StatusInfo = property.GetPropertyValue("StatusInfo") as int? ?? 0;
        this.SystemCreationClassName = property.GetPropertyValue("SystemCreationClassName") as string ?? string.Empty;
        this.SystemName = property.GetPropertyValue("SystemName") as string ?? string.Empty;
    }

    int Availability;
    string Caption;
    string ClassGuid;
    string[] CompatibleID;
    int ConfigManagerErrorCode;
    bool ConfigManagerUserConfig;
    string CreationClassName;
    string Description;
    string DeviceID;
    bool ErrorCleared;
    string ErrorDescription;
    string[] HardwareID;
    DateTime InstallDate;
    int LastErrorCode;
    string Manufacturer;
    string Name;
    string PNPClass;
    string PNPDeviceID;
    int[] PowerManagementCapabilities;
    bool PowerManagementSupported;
    bool Present;
    string Service;
    string Status;
    int StatusInfo;
    string SystemCreationClassName;
    string SystemName;       

}

我不太清楚“对索引 0 之后的项目进行排序”是什么意思,但如果您只想对 
SerialPort.GetPortNames()

2
投票
Array.Sort

    
我重写了 Elmue 的答案,并使用 Muno 的

SerialPortInfo

0
投票
(.net 6)

using Microsoft.Win32;
using System.Management;
using System.Runtime.Versioning;

public static class SerialPortSearcher
{

    [SupportedOSPlatform("windows")]
    public static IEnumerable<ISerialPortInfo> Search()
    {
        using var entity = new ManagementClass("Win32_PnPEntity");
        foreach (var instance in entity.GetInstances().Cast<ManagementObject>())
        {
            var classGuid = instance.GetPropertyValue("ClassGuid");
            // Skip all devices except device class "PORTS"
            if (classGuid?.ToString()?.ToUpper() == "{4D36E978-E325-11CE-BFC1-08002BE10318}")
            {
                yield return new SerialPortInfo(instance);
            }
        }
    }

    [SupportedOSPlatform("windows")]
    private class SerialPortInfo : ISerialPortInfo
    {
        public SerialPortInfo(ManagementObject obj)
        {
            this.Availability = obj.GetPropertyValue("Availability") as int? ?? 0;
            this.Caption = obj.GetPropertyValue("Caption") as string ?? string.Empty;
            this.ClassGuid = obj.GetPropertyValue("ClassGuid") as string ?? string.Empty;
            this.CompatibleID = obj.GetPropertyValue("CompatibleID") as string[] ?? new string[] { };
            this.ConfigManagerErrorCode = obj.GetPropertyValue("ConfigManagerErrorCode") as int? ?? 0;
            this.ConfigManagerUserConfig = obj.GetPropertyValue("ConfigManagerUserConfig") as bool? ?? false;
            this.CreationClassName = obj.GetPropertyValue("CreationClassName") as string ?? string.Empty;
            this.Description = obj.GetPropertyValue("Description") as string ?? string.Empty;
            this.DeviceID = obj.GetPropertyValue("DeviceID") as string ?? string.Empty;
            this.ErrorCleared = obj.GetPropertyValue("ErrorCleared") as bool? ?? false;
            this.ErrorDescription = obj.GetPropertyValue("ErrorDescription") as string ?? string.Empty;
            this.HardwareID = obj.GetPropertyValue("HardwareID") as string[] ?? new string[] { };
            this.InstallDate = obj.GetPropertyValue("InstallDate") as DateTime? ?? DateTime.MinValue;
            this.LastErrorCode = obj.GetPropertyValue("LastErrorCode") as int? ?? 0;
            this.Manufacturer = obj.GetPropertyValue("Manufacturer") as string ?? string.Empty;
            this.Name = obj.GetPropertyValue("Name") as string ?? string.Empty;
            this.PNPClass = obj.GetPropertyValue("PNPClass") as string ?? string.Empty;
            this.PNPDeviceID = obj.GetPropertyValue("PnpDeviceID") as string ?? string.Empty;
            this.PowerManagementCapabilities = obj.GetPropertyValue("PowerManagementCapabilities") as int[] ?? new int[] { };
            this.PowerManagementSupported = obj.GetPropertyValue("PowerManagementSupported") as bool? ?? false;
            this.Present = obj.GetPropertyValue("Present") as bool? ?? false;
            this.Service = obj.GetPropertyValue("Service") as string ?? string.Empty;
            this.Status = obj.GetPropertyValue("Status") as string ?? string.Empty;
            this.StatusInfo = obj.GetPropertyValue("StatusInfo") as int? ?? 0;
            this.SystemCreationClassName = obj.GetPropertyValue("SystemCreationClassName") as string ?? string.Empty;
            this.SystemName = obj.GetPropertyValue("SystemName") as string ?? string.Empty;

            var regPath = "HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Enum\\" + PNPDeviceID + "\\Device Parameters";
            this.PortName = Registry.GetValue(regPath, "PortName", "")?.ToString();

            //int i = Caption.IndexOf(" (COM");
            //if (i > 0) // remove COM port from description
            //    Caption = Caption.Substring(0, i);

        }

        public int Availability { get; }
        public string Caption { get; }
        public string ClassGuid { get; }
        public string[] CompatibleID { get; }
        public int ConfigManagerErrorCode { get; }
        public bool ConfigManagerUserConfig { get; }
        public string CreationClassName { get; }
        public string Description { get; }
        public string DeviceID { get; }
        public bool ErrorCleared { get; }
        public string ErrorDescription { get; }
        public string[] HardwareID { get; }
        public DateTime InstallDate { get; }
        public int LastErrorCode { get; }
        public string Manufacturer { get; }
        public string Name { get; }
        public string PNPClass { get; }
        public string PNPDeviceID { get; }
        public int[] PowerManagementCapabilities { get; }
        public bool PowerManagementSupported { get; }
        public bool Present { get; }
        public string Service { get; }
        public string Status { get; }
        public int StatusInfo { get; }
        public string SystemCreationClassName { get; }
        public string SystemName { get; }
        public string? PortName { get; }
    }
}

public interface ISerialPortInfo
{
    int Availability { get; }
    string Caption { get; }
    string ClassGuid { get; }
    string[] CompatibleID { get; }
    int ConfigManagerErrorCode { get; }
    bool ConfigManagerUserConfig { get; }
    string CreationClassName { get; }
    string Description { get; }
    string DeviceID { get; }
    bool ErrorCleared { get; }
    string ErrorDescription { get; }
    string[] HardwareID { get; }
    DateTime InstallDate { get; }
    int LastErrorCode { get; }
    string Manufacturer { get; }
    string Name { get; }
    string PNPClass { get; }
    string PNPDeviceID { get; }
    string? PortName { get; }
    int[] PowerManagementCapabilities { get; }
    bool PowerManagementSupported { get; }
    bool Present { get; }
    string Service { get; }
    string Status { get; }
    int StatusInfo { get; }
    string SystemCreationClassName { get; }
    string SystemName { get; }
}


Program.cs
中进行测试:

using System.Text.Json; var ports = SerialPortSearcher.Search().ToArray(); Console.WriteLine(JsonSerializer.Serialize(ports, new JsonSerializerOptions { WriteIndented = true }));

    

this.comboPortName.Items.AddRange(
    (from qP in System.IO.Ports.SerialPort.GetPortNames()
     orderby System.Text.RegularExpressions.Regex.Replace(qP, "~\\d",
     string.Empty).PadLeft(6, '0')
     select qP).ToArray()
);

-3
投票
© www.soinside.com 2019 - 2024. All rights reserved.