获取串口信息

发布于 2024-09-01 06:39:37 字数 606 浏览 4 评论 0原文

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

     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)。如果您有任何想法,我们将不胜感激。谢谢。

I have some code that loads the serial ports into a combo-box:

     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;

I would like to add the port descriptions (similar to what are shown for the COM ports in the Device Manager) to the list and sort the items in the list that are after index 0 (solved: see above snippet). Does anyone have any suggestions for adding the port descriptions? I am using Microsoft Visual C# 2008 Express Edition (.NET 2.0). Any thoughts you may have would be appreciated. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

半世晨晓 2024-09-08 06:39:37

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

        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);
            }
        }
    

I tried so many solutions on here that didn't work for me, only displaying some of the ports. But the following displayed All of them and their information.

        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);
            }
        }
    
谈情不如逗狗 2024-09-08 06:39:37

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

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

示例代码(确保添加对 System.管理):

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

EDIT: Sorry, I zipped past your question too quick. I realize now that you're looking for a list with the port name + port description. I've updated the code accordingly...

Using System.Management, you can query for all the ports, and all the information for each port (just like Device Manager...)

Sample code (make sure to add reference to 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();
        }
    }
}

More info here: http://msdn.microsoft.com/en-us/library/aa394582%28VS.85%29.aspx

别念他 2024-09-08 06:39:37

使用以下代码片段

执行时会给出以下输出。

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"))

Use following code snippet

It gives following output when executed.

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

Don't forget to add

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

Also add reference to system.Management (by default it is not available)

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

Update:
You may also check for

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

instead of

if (queryObj["Caption"].ToString().Contains("(COM"))
青瓷清茶倾城歌 2024-09-08 06:39:37

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

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"))
{
    const String CUR_CTRL = "HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\";

    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_RegEnum  = CUR_CTRL + "Enum\\" + s_DeviceID + "\\Device Parameters";
        String s_RegServ  = CUR_CTRL + "Services\\BTHPORT\\Parameters\\Devices\\";
        String s_PortName = Registry.GetValue(s_RegEnum, "PortName", "").ToString();
        String s_BT_Dir   = null; // Bluetooth port direction
        String s_BT_Dev   = "";   // Bluetooth paired device name
        String s_BT_MAC   = "";   // Bluetooth paired device MAC address

        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);

        if (s_DeviceID.StartsWith("BTHENUM\\")) // Bluetooth
        {
            s_BT_Dir = "Incoming";

            // "{00001101-0000-1000-8000-00805f9b34fb}#7445CEA614BC_C00000000"
            String s_UniqueID = Registry.GetValue(s_RegEnum, "Bluetooth_UniqueID", "").ToString();

            String[] s_Split = s_UniqueID.Split('#');
            if (s_Split.Length == 2)
            {
                s_Split = s_Split[1].Split('_');

                // Ignore MAC = "000000000000"
                if (s_Split.Length == 2 && s_Split[0].Trim('0').Length > 0) 
                {
                    s_BT_MAC = s_Split[0]; // 12 digits: "7445CEA614BC"
                    s_BT_Dir = "Outgoing";

                    // Read the Bluetooth device that is paired with the COM port.
                    Object o_BtDevice = Registry.GetValue(s_RegServ + s_BT_MAC, "Name", null);
                    if (o_BtDevice is Byte[])
                        s_BT_Dev = Encoding.UTF8.GetString((Byte[])o_BtDevice);
                }
            }

            Console.WriteLine("Port Direction: " + s_BT_Dir);
            Console.WriteLine("Paired Device:  " + s_BT_Dev);
            Console.WriteLine("Device MAC Adr: " + s_BT_MAC);
        }

        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}_VID&0001005D_PID&223B\7&36284202&0&7445CEA614BC_C00000000
Port Direction: Outgoing
Paired Device:  WH-CH510
Device MAC Adr: 7445CEA614BC
-----------------------------------
Port Name:      COM9
Description:    Standard Serial over Bluetooth link
Manufacturer:   Microsoft
Device ID:      BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMFG&0000\7&36284202&0&000000000000_00000000
Port Direction: Incoming
Paired Device:
Device MAC Adr: 
-----------------------------------
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 端口。

注意:如果您在打开蓝牙 COM 端口时遇到 UnauthorizedAccessException,解决方案可能是删除设备并再次进行配对。

None of the answers here satisfies my needs.

The answer from Muno is wrong because it lists ONLY the USB ports.

The answer from code4life is wrong because it lists all EXCEPT the USB ports. (Nevertheless it has 44 up-votes!!!)

I have an EPSON printer simulation port on my computer which is not listed by any of the answers here. So I had to write my own solution. Additionally I want to display more information than just the caption string. I also need to separate the port name from the description.

My code has been tested on Windows XP, 7, 10 and 11.

The Port Name (like "COM1") must be read from the registry because WMI does not give this information for all COM ports (EPSON).

If you use my code you do not need SerialPort.GetPortNames() anymore. My function returns the same ports, but with additional details. Why did Microsoft not implement such a function into the framework??

using System.Management;
using Microsoft.Win32;

using (ManagementClass i_Entity = new ManagementClass("Win32_PnPEntity"))
{
    const String CUR_CTRL = "HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\";

    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_RegEnum  = CUR_CTRL + "Enum\\" + s_DeviceID + "\\Device Parameters";
        String s_RegServ  = CUR_CTRL + "Services\\BTHPORT\\Parameters\\Devices\\";
        String s_PortName = Registry.GetValue(s_RegEnum, "PortName", "").ToString();
        String s_BT_Dir   = null; // Bluetooth port direction
        String s_BT_Dev   = "";   // Bluetooth paired device name
        String s_BT_MAC   = "";   // Bluetooth paired device MAC address

        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);

        if (s_DeviceID.StartsWith("BTHENUM\\")) // Bluetooth
        {
            s_BT_Dir = "Incoming";

            // "{00001101-0000-1000-8000-00805f9b34fb}#7445CEA614BC_C00000000"
            String s_UniqueID = Registry.GetValue(s_RegEnum, "Bluetooth_UniqueID", "").ToString();

            String[] s_Split = s_UniqueID.Split('#');
            if (s_Split.Length == 2)
            {
                s_Split = s_Split[1].Split('_');

                // Ignore MAC = "000000000000"
                if (s_Split.Length == 2 && s_Split[0].Trim('0').Length > 0) 
                {
                    s_BT_MAC = s_Split[0]; // 12 digits: "7445CEA614BC"
                    s_BT_Dir = "Outgoing";

                    // Read the Bluetooth device that is paired with the COM port.
                    Object o_BtDevice = Registry.GetValue(s_RegServ + s_BT_MAC, "Name", null);
                    if (o_BtDevice is Byte[])
                        s_BT_Dev = Encoding.UTF8.GetString((Byte[])o_BtDevice);
                }
            }

            Console.WriteLine("Port Direction: " + s_BT_Dir);
            Console.WriteLine("Paired Device:  " + s_BT_Dev);
            Console.WriteLine("Device MAC Adr: " + s_BT_MAC);
        }

        Console.WriteLine("-----------------------------------");
    }
}

I tested the code with a lot of COM ports. This is the Console output:

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}_VID&0001005D_PID&223B\7&36284202&0&7445CEA614BC_C00000000
Port Direction: Outgoing
Paired Device:  WH-CH510
Device MAC Adr: 7445CEA614BC
-----------------------------------
Port Name:      COM9
Description:    Standard Serial over Bluetooth link
Manufacturer:   Microsoft
Device ID:      BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMFG&0000\7&36284202&0&000000000000_00000000
Port Direction: Incoming
Paired Device:
Device MAC Adr: 
-----------------------------------
Port Name:      COM30
Description:    Arduino Uno
Manufacturer:   Arduino LLC (www.arduino.cc)
Device ID:      USB\VID_2341&PID_0001\74132343530351F03132
-----------------------------------

COM1 is a COM port on the mainboard.

COM 8 and 9 are Buetooth COM ports.

COM 25 and 26 are USB to RS232 adapters.

COM 28 and 29 and 30 are Arduino-like boards.

COM 20 and 999 are EPSON ports.

NOTE: If you get an UnauthorizedAccessException when opening a Bluetooth COM port the solution may be remove the device and do the pairing again.

甜点 2024-09-08 06:39:37

有一个 关于同一问题的帖子MSDN:

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

嗨拉文布,

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

如果您有任何其他问题,请随时告诉我。

最诚挚的问候,
周小龙

那篇文章中的链接指向此:

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

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

There is a post about this same issue on MSDN:

Getting more information about a serial port in C#

Hi Ravenb,

We can't get the information through the SerialPort type. I don't know why you need this info in your application. However, there's a solved thread with the same question as you. You can check out the code there, and see if it can help you.

If you have any further problem, please feel free to let me know.

Best regards,
Bruce Zhou

The link in that post goes to this one:

How to get more info about port using System.IO.Ports.SerialPort

You can probably get this info from a WMI query. Check out this tool to help you find the right code. Why would you care though? This is just a detail for a USB emulator, normal serial ports won't have this. A serial port is simply know by "COMx", nothing more.

信愁 2024-09-08 06:39:37

我结合了以前的答案并使用了 Win32_PnPEntity 类的结构,可以找到 在这里
得到这样的解决方案:

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;       

}

I combined previous answers and used structure of Win32_PnPEntity class which can be found found here.
Got solution like this:

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 class:

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;       

}
好久不见√ 2024-09-08 06:39:37

我不太清楚“对索引 0 之后的项目进行排序”是什么意思,但如果您只想对 SerialPort.GetPortNames() 返回的字符串数组进行排序,则可以使用 数组排序

I'm not quite sure what you mean by "sorting the items after index 0", but if you just want to sort the array of strings returned by SerialPort.GetPortNames(), you can use Array.Sort.

濫情▎り 2024-09-08 06:39:37

我重写了 Elmue 的答案并使用 Muno 的 SerialPortInfo 类来丰富它。所以它更清晰并提供更多信息。 (.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 }));

I rewrite Elmue's answer and enrich it using Muno's SerialPortInfo class. So it is more clear and provides more information. (.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; }
}

Test it in Program.cs:

using System.Text.Json;

var ports = SerialPortSearcher.Search().ToArray();

Console.WriteLine(JsonSerializer.Serialize(ports, new JsonSerializerOptions { WriteIndented = true }));

拔了角的鹿 2024-09-08 06:39:37

我的一个小变化是,并非所有端口都有描述。

public static class SerialPortSearcher
    {
        public const string PortsClassGuid = "{4D36E978-E325-11CE-BFC1-08002BE10318}";
        public const string ModemClassGuid = "{4D36E96D-E325-11CE-BFC1-08002BE10318}";

        public static IEnumerable<ISerialPortInfo> GetPortInformationYield()
        {
            using (var entity = new ManagementClass("Win32_PnPEntity"))
                foreach (var instance in entity.GetInstances().Cast<ManagementObject>())
                {
                    var classGuid = instance.GetPropertyValue("ClassGuid")?.ToString()?.ToUpper();
                    // Skip all devices except device class "PORTS"
                    if (classGuid == PortsClassGuid || classGuid == ModemClassGuid)
                    {
                        yield return new SerialPortInfo(instance);
                    }
                }
        }

        public static async Task<IEnumerable<ISerialPortInfo>> GetPortInformationAsync()
        {
            return await Task.Run(() =>
            {
                var portInfos = new List<SerialPortInfo>();

                using (var processClass = new ManagementClass("Win32_PnPEntity"))
                {
                    using (ManagementObjectCollection ports = processClass.GetInstances())
                    {
                        foreach (ManagementObject property in ports.Cast<ManagementObject>())
                        {
                            var classGuid = property.GetPropertyValue("ClassGuid")?.ToString()?.ToUpper();
                            // Skip all devices except device class "PORTS"
                            if (classGuid == PortsClassGuid || classGuid == ModemClassGuid)
                            {
                                portInfos.Add(new SerialPortInfo(property));
                            }
                        }
                    }
                }

                return portInfos.AsEnumerable();
            });
        }
    }

A small change from me, not all ports had descriptions.

public static class SerialPortSearcher
    {
        public const string PortsClassGuid = "{4D36E978-E325-11CE-BFC1-08002BE10318}";
        public const string ModemClassGuid = "{4D36E96D-E325-11CE-BFC1-08002BE10318}";

        public static IEnumerable<ISerialPortInfo> GetPortInformationYield()
        {
            using (var entity = new ManagementClass("Win32_PnPEntity"))
                foreach (var instance in entity.GetInstances().Cast<ManagementObject>())
                {
                    var classGuid = instance.GetPropertyValue("ClassGuid")?.ToString()?.ToUpper();
                    // Skip all devices except device class "PORTS"
                    if (classGuid == PortsClassGuid || classGuid == ModemClassGuid)
                    {
                        yield return new SerialPortInfo(instance);
                    }
                }
        }

        public static async Task<IEnumerable<ISerialPortInfo>> GetPortInformationAsync()
        {
            return await Task.Run(() =>
            {
                var portInfos = new List<SerialPortInfo>();

                using (var processClass = new ManagementClass("Win32_PnPEntity"))
                {
                    using (ManagementObjectCollection ports = processClass.GetInstances())
                    {
                        foreach (ManagementObject property in ports.Cast<ManagementObject>())
                        {
                            var classGuid = property.GetPropertyValue("ClassGuid")?.ToString()?.ToUpper();
                            // Skip all devices except device class "PORTS"
                            if (classGuid == PortsClassGuid || classGuid == ModemClassGuid)
                            {
                                portInfos.Add(new SerialPortInfo(property));
                            }
                        }
                    }
                }

                return portInfos.AsEnumerable();
            });
        }
    }
我也只是我 2024-09-08 06:39:37
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()
);
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()
);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文