WMI:获取所有串行(COM)端口的列表,包括虚拟端口
WMI: Get list of all serial (COM) ports including virtual ports
我目前正在开发一个与 Arduino 微控制器交互的 C# 小程序。该程序有一个组合框,您可以在其中选择 COM 端口。 µc 通过 USB 和虚拟 COM 端口 (CH340) 连接。
我使用下面的代码将可用的 COM 端口填入组合框。
private void Form1_Load(object sender, EventArgs e)
{
string[] PortNames = SerialPort. GetPortNames();
comboBoxPort.Items.AddRange(PortNames);
}
这样做的缺点是,您必须查看设备管理器以查看哪个是适用于 µc 的正确设备。例如,我的 PC 有 4 个活动的 COM 端口,一个物理端口,2 个虚拟端口,另一个用于 µc 的虚拟端口。我正在寻找的是一种显示具有相关 COM 端口的设备的完整名称的方法(就像您可以在设备管理器中找到它一样)
COM-ports in the Device Manager
经过一番研究后,我发现还有另一种可能是使用 WMI。在使用 "WMI Code Creator" 进行了大量测试之后,我不知道我还能尝试什么来完成我一直在做的事情。我尝试过的所有命名空间和 类 都只生成 COM 端口,如 COM1、COM2……或者它们生成的硬件 ID 对程序的用户没有用。
下面的代码或多或少正是我要搜索的内容,但它仅适用于 COM 端口中的“真实”构建。
using System;
using System.Management;
using System.Windows.Forms;
namespace WMISample
{
public class MyWMIQuery
{
public static void Main()
{
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\CIMV2",
"SELECT * FROM Win32_SerialPort");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("Win32_SerialPort instance");
Console.WriteLine("-----------------------------------");
Console.WriteLine("Name: {0}", queryObj["Name"]);
}
}
catch (ManagementException e)
{
MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
}
}
}
}
是否有任何其他可能的方法来获取所有 COM 端口的列表,就像设备管理器中有一个一样?是否可以使用设备的硬件 ID 以某种方式识别它们,然后在第二步中为它们获取正确的名称?
如果我能得到一些帮助,我将非常高兴。一定有办法做到这一点,但我找不到。
如果有些东西听起来很奇怪,请原谅我的英语:)
如前所述,这里是用所有可用的 COM 端口填充组合框并在选择后设置关联端口的完整工作代码。
(原回答如何获取端口名 --> link)
感谢@o_O link,我希望有人会发现此代码有用。
private void Form1_Load(object sender, EventArgs e)
{
// Get all serial (COM)-ports you can see in the devicemanager
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\cimv2",
"SELECT * FROM Win32_PnPEntity WHERE ClassGuid=\"{4d36e978-e325-11ce-bfc1-08002be10318}\"");
// Sort the items in the combobox
CmdBoxPort.Sorted = true;
// Add all available (COM)-ports to the combobox
foreach (ManagementObject queryObj in searcher.Get())
CmdBoxPort.Items.Add(queryObj["Caption"]);
}
private void CmdBoxPort_SelectedIndexChanged(object sender, EventArgs e)
{
// Set the right port for the selected item.
// The portname is based on the "COMx" part of the string (SelectedItem)
string item = CmdBoxPort.SelectedItem.ToString();
// Search for the expression "(COM" in the "selectedItem" string
if (item.Contains("(COM"))
{
// Get the index number where "(COM" starts in the string
int indexOfCom = item.IndexOf("(COM");
// Set PortName to COMx based on the expression in the "selectedItem" string
// It automatically gets the correct length of the COMx expression to make sure
// that also a COM10, COM11 and so on is working properly.
serialPort1.PortName = item.Substring(indexOfCom + 1, item.Length - indexOfCom - 2);
}
else
return;
}
我目前正在开发一个与 Arduino 微控制器交互的 C# 小程序。该程序有一个组合框,您可以在其中选择 COM 端口。 µc 通过 USB 和虚拟 COM 端口 (CH340) 连接。
我使用下面的代码将可用的 COM 端口填入组合框。
private void Form1_Load(object sender, EventArgs e)
{
string[] PortNames = SerialPort. GetPortNames();
comboBoxPort.Items.AddRange(PortNames);
}
这样做的缺点是,您必须查看设备管理器以查看哪个是适用于 µc 的正确设备。例如,我的 PC 有 4 个活动的 COM 端口,一个物理端口,2 个虚拟端口,另一个用于 µc 的虚拟端口。我正在寻找的是一种显示具有相关 COM 端口的设备的完整名称的方法(就像您可以在设备管理器中找到它一样)
COM-ports in the Device Manager
经过一番研究后,我发现还有另一种可能是使用 WMI。在使用 "WMI Code Creator" 进行了大量测试之后,我不知道我还能尝试什么来完成我一直在做的事情。我尝试过的所有命名空间和 类 都只生成 COM 端口,如 COM1、COM2……或者它们生成的硬件 ID 对程序的用户没有用。 下面的代码或多或少正是我要搜索的内容,但它仅适用于 COM 端口中的“真实”构建。
using System;
using System.Management;
using System.Windows.Forms;
namespace WMISample
{
public class MyWMIQuery
{
public static void Main()
{
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\CIMV2",
"SELECT * FROM Win32_SerialPort");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("Win32_SerialPort instance");
Console.WriteLine("-----------------------------------");
Console.WriteLine("Name: {0}", queryObj["Name"]);
}
}
catch (ManagementException e)
{
MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
}
}
}
}
是否有任何其他可能的方法来获取所有 COM 端口的列表,就像设备管理器中有一个一样?是否可以使用设备的硬件 ID 以某种方式识别它们,然后在第二步中为它们获取正确的名称?
如果我能得到一些帮助,我将非常高兴。一定有办法做到这一点,但我找不到。
如果有些东西听起来很奇怪,请原谅我的英语:)
如前所述,这里是用所有可用的 COM 端口填充组合框并在选择后设置关联端口的完整工作代码。
(原回答如何获取端口名 --> link)
感谢@o_O link,我希望有人会发现此代码有用。
private void Form1_Load(object sender, EventArgs e)
{
// Get all serial (COM)-ports you can see in the devicemanager
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\cimv2",
"SELECT * FROM Win32_PnPEntity WHERE ClassGuid=\"{4d36e978-e325-11ce-bfc1-08002be10318}\"");
// Sort the items in the combobox
CmdBoxPort.Sorted = true;
// Add all available (COM)-ports to the combobox
foreach (ManagementObject queryObj in searcher.Get())
CmdBoxPort.Items.Add(queryObj["Caption"]);
}
private void CmdBoxPort_SelectedIndexChanged(object sender, EventArgs e)
{
// Set the right port for the selected item.
// The portname is based on the "COMx" part of the string (SelectedItem)
string item = CmdBoxPort.SelectedItem.ToString();
// Search for the expression "(COM" in the "selectedItem" string
if (item.Contains("(COM"))
{
// Get the index number where "(COM" starts in the string
int indexOfCom = item.IndexOf("(COM");
// Set PortName to COMx based on the expression in the "selectedItem" string
// It automatically gets the correct length of the COMx expression to make sure
// that also a COM10, COM11 and so on is working properly.
serialPort1.PortName = item.Substring(indexOfCom + 1, item.Length - indexOfCom - 2);
}
else
return;
}