Usando o Visual Studio 2022 Community no Windows 10, seguindo um tutorial em C# no qual um projeto "Aplicativo Windows Forms (.NET Framework)" lista todas as portas COM e suas descrições, como seriam vistas/encontradas no Gerenciador de Dispositivos do Windows. Gerenciador de Dispositivos - Portas (COM e LPT)
No aplicativo de formulários, há uma caixa de texto que exibe a lista de portas COM e suas descrições quando iniciada. E também um botão para sair do programa.
Quando eu construo e inicio o depurador, um erro é gerado no Visual Studio específico para esta linha de código (a parte que reúne as descrições da porta COM):
var ports = searcher.Get()
.Cast<ManagementBaseObject>()
.ToList()
.Select(p => p["Caption"].ToString());
O erro mostrado é este:
Exceção não tratada: System.Management.ManagementException: 'Consulta inválida'
Não sei por que esse erro é gerado, pois o código é o que está no tutorial.
Além disso, não sei como diagnosticar e corrigir o problema.
Este é o código do tutorial:
using System;
using System.Collections.Generic;
using System.Data;
using System.IO.Ports;
using System.Linq;
using System.Management;
using System.Windows.Forms;
namespace Device_Manager_COMS_searcher
{
public partial class Form1 : Form
{
List<string> portnames = new List<string>();
public Form1()
{
InitializeComponent();
portnames = GetPorts();
foreach (string port in portnames)
{
textBox1.AppendText(port + "\r\n");
}
}
public List<string> GetPorts()
{
// This searches all the properties of the Plug and Play devices
// (using "Win32_PnPEntity"). The "caption" is the text description of
// the COM port object.
// Search all Plug n Play entities where the Caption has "(COM" plus
// any number of leading and lagging characters.
using (var searcher = new ManagementObjectSearcher("SELECT * FROM" + "Win32_PnpEntity WHERE Caption like '%(COM%'"))
{
// This gets the simple port names, such as "COM4"
string[] portnames = SerialPort.GetPortNames();
// This gets the caption/description of the found ports
// Throws the error: System.Management.Managementexception: 'invalid query'
var ports = searcher.Get().Cast<ManagementBaseObject>().ToList().Select(p => p["Caption"].ToString());
// Append the description of each port to the corresponding port name
// and add to the list
List<string> portList = portnames.Select(n => n + " - " + ports.FirstOrDefault(s => s.Contains(n))).ToList();
return portList;
}
}
private void button1_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
No Visual Studio, adicionei a referência System.Management
por meio do Gerenciador de Referências.
Também tentei adicionar a mesma referência via NuGet, mas ambos não corrigiram o problema.
Por motivos de segurança, eu queria ver se o programa/aplicativo conseguiria iniciar e encontrar as portas COM sem as descrições. Então, alterei o design do formulário para adicionar mais um botão, "OBTER COMS", que, ao ser clicado, buscaria apenas as portas COM e seus números, mas não a descrição.
Assim:
using System;
using System.Collections.Generic;
using System.Data;
using System.IO.Ports;
using System.Linq;
using System.Management;
using System.Windows.Forms;
namespace Device_Manager_COMS_searcher
{
public partial class Form1 : Form
{
List<string> portnames = new List<string>();
public Form1()
{
InitializeComponent();
}
public List<string> GetPorts()
{
// This searches all the properties of the Plug and Play devices
// (using "Win32_PnPEntity"). The "caption" is the text description of
// the COM port object.
// Search all Plug n Play entities where the Caption has "(COM" plus
// any number of leading and lagging characters.
using (var searcher = new ManagementObjectSearcher("SELECT * FROM" + "Win32_PnpEntity WHERE Caption like '%(COM%'"))
{
// This gets the simple port names, such as "COM4"
string[] portnames = SerialPort.GetPortNames();
// Append the description of each port to the corresponding port name
// and add to the list
List<string> portList = portnames.Select(n => n).ToList();
return portList;
}
}
private void button1_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void button2_Click(object sender, EventArgs e)
{
portnames = GetPorts();
foreach (string port in portnames)
{
textBox1.AppendText(port + "\r\n");
}
}
}
}
Depois de compilado e iniciado, o depurador funciona. Clico no botão "GET COMS" e ele exibe as portas COM com os itens conectados, assim:
Exemplo prático menos descritores para portas COM
Mas, novamente, se eu alterar o código para a GetPorts()
seção que adiciona um descritor, assim:
public List<string> GetPorts()
{
// This searches all the properties of the Plug and Play devices
// (using "Win32_PnPEntity"). The "caption" is the text description of
// the COM port object.
// Search all Plug n Play entities where the Caption has "(COM" plus
// any number of leading and lagging characters.
using (var searcher = new ManagementObjectSearcher("SELECT * FROM" + "Win32_PnpEntity WHERE Caption like '%(COM%'"))
{
// This gets the simple port names, such as "COM4"
string[] portnames = SerialPort.GetPortNames();
// This gets the caption/description of the found ports
// Throws error: System.Management.Managementexception: 'invalid query'
var ports = searcher.Get().Cast<ManagementBaseObject>().ToList().Select(p => p["Caption"].ToString());
// Append the description of each port to the corresponding port name
// and add to the list
List<string> portList = portnames.Select(n => n + " - " + ports.FirstOrDefault(s => s.Contains(n))).ToList();
return portList;
}
}
Entendi o erro.
Precisa de ajuda para consertar isso, por favor