如何解决使用 Microsoft.Management.Infrastructure 检索串行端口信息
为了获取有关串口设备的信息,使用System.Management
,我们可以按照Getting Serial Port Information中的描述进行:
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();
}
}
}
如何使用 Microsoft.Management.Infrastructure
实现这一点,我还没有找到示例,而且文档不够详细。
解决方法
非常相似:
- 创建一个 CimSession,在其中指定 ComputerName(
null
代表 LocalHost)和一个 CimCredential 对象(需要传递通常的用户名和密码以进行身份验证)。这反映了 System.Management 的ConnectionOption
。 - 使用 CimSession 的 QueryInstances 方法构建查询,传递命名空间和类。这反映了 System.Management 的 SelectQuery 和 ManagementObjectSearcher
-
QueryInstances()
返回一个 IEnumerble<CimInstance> 对象(好消息是这里没有返回 COM 对象)。 - 获取您关心的 Value 中的 CimInstanceProperties。
请注意,您在 WMI 查询中跳过了 ConnectionOption 和 EnumerationOptions,这在性能方面并不是很好。
然后可以将您的查询翻译为:
using Microsoft.Management.Infrastructure;
using Microsoft.Management.Infrastructure.Options;
using (var session = CimSession.Create(null) {
var ports = session.QueryInstances(@"root\cimv2","WQL","SELECT * FROM WIN32_SerialPort");
string[] portnames = SerialPort.GetPortNames();
var tList = (from n in portnames
join p in ports on n equals p.CimInstanceProperties["DeviceID"].Value
select n + " - " + p.CimInstanceProperties["Caption"].Value);
}
我不知道你为什么在这里使用 string[] portnames = SerialPort.GetPortNames();
。
您可以只使用 CimProperties:
using (var session = CimSession.Create(null)) {
var ports = session.QueryInstances(@"root\cimv2","SELECT * FROM WIN32_SerialPort");
var portsDescriptions = ports.Select(p =>
$"{p.CimInstanceProperties["DeviceID"].Value} - {p.CimInstanceProperties["Caption"].Value}");
// If you actually need to materialize a List<T>...
portsDescriptions.ToList().ForEach(Console.WriteLine);
}
无关,但可能有用:我建议构建一些方法来创建具有更多选项的 CimSession。例如:
public static CimSession CreateSession(string computerName)
=> CreateSession(computerName,string.Empty,null);
public static CimSession CreateSession(string computerName,string domain,string userName,SecureString password)
{
if (string.IsNullOrEmpty(computerName) ||
computerName.Equals("localhost",StringComparison.InvariantCultureIgnoreCase)) {
computerName = null;
}
var option = new CimSessionOptions();
if (password != null && password.Length > 0) {
option.AddDestinationCredentials(
new CimCredential(PasswordAuthenticationMechanism.Default,domain,userName,password));
}
return CimSession.Create(computerName,option);
}
所以,而不是:
var session = CimSession.Create(null);
您可以将其称为:
// LocalHost,default permissions
var session = CreateSession(null);
如果需要,或者传递域、用户名和密码(如 Char*)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。