c# - 升级到 Windows 10 后 WMI 不工作

标签 c# wmi windows-10

我一直在 Windows 8 上的 Visual Studio 中使用以下代码作为控制台应用程序,以返回连接的串行设备的描述和设备 ID。我在我正在创建的应用程序中使用了这个的修改版本来自动检测 Arduino 的 COM 端口。它不再返回任何东西,因为我已经完成了 Windows 10 的全新安装。我有一个 USB 到串行 AVR 编程器,但它仍然显示使用此代码。我检查了注册表,Arduino 列在 SERIALCOMM 中,Arduino 在设备管理器的“端口(COM 和 LPT)”下显示为“USB 串行端口(COM6)”,我可以使用 Arduino 软件对 Arduino 进行编程。我不知道为什么它不再起作用。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Management;
using System.IO.Ports;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main() 
        {


            ManagementScope connectionScope = new ManagementScope();
            SelectQuery serialQuery = new SelectQuery("SELECT * FROM Win32_SerialPort");
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(connectionScope, serialQuery);

            try
            {
                foreach (ManagementObject item in searcher.Get())
                {
                    string desc = item["Description"].ToString();
                    string deviceId = item["DeviceID"].ToString();

                    Console.WriteLine(desc);
                    Console.WriteLine(deviceId);
                }
            }
            catch (ManagementException e)
            {
                Console.WriteLine(e.Message);
            }

            Console.ReadKey();
        }
    }
}

在尝试寻找解决方案时,我发现以下实现可以使用 MSSerial_PortName 查找端口名称,但我遇到了拒绝访问错误。

using System;
using System.Management;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main() 
        {
            try
            {
                ManagementObjectSearcher MOSearcher = new ManagementObjectSearcher("root\\WMI", "SELECT * FROM MSSerial_PortName");

                foreach (ManagementObject MOject in MOSearcher.Get())
                {
                    Console.WriteLine(MOject["PortName"]); 
                }
            }
            catch (ManagementException me)
            {
                Console.WriteLine("An error occurred while querying for WMI data: " + me.Message);
            }
            Console.ReadKey();
        }
    }
}

最佳答案

好的,我想我现在看到了问题(我会添加一个新答案,但不会替换旧答案,以防有人发现有用的信息)。

Win32_SerialPort 仅检测硬件串行端口(例如 RS232)。 Win32_PnPEntity 标识即插即用设备,包括硬件和虚拟串行端口(例如 FTDI 驱动程序创建的 COM 端口)。

要使用 Win32_PnPEntity 来识别驱动程序需要一些额外的工作。以下代码标识系统上的所有 COM 端口并生成所述端口的列表。从此列表中,您可以确定适当的 COM 端口号以创建您的 SerialPort 对象。

// Class to contain the port info.
public class PortInfo
{
  public string Name;
  public string Description;
}

// Method to prepare the WMI query connection options.
public static ConnectionOptions PrepareOptions ( )
{
  ConnectionOptions options = new ConnectionOptions ( );
  options . Impersonation = ImpersonationLevel . Impersonate;
  options . Authentication = AuthenticationLevel . Default;
  options . EnablePrivileges = true;
  return options;
}

// Method to prepare WMI query management scope.
public static ManagementScope PrepareScope ( string machineName , ConnectionOptions options , string path  )
{
  ManagementScope scope = new ManagementScope ( );
  scope . Path = new ManagementPath ( @"\\" + machineName + path );
  scope . Options = options;
  scope . Connect ( );
  return scope;
}

// Method to retrieve the list of all COM ports.
public static List<PortInfo> FindComPorts ( )
{
  List<PortInfo> portList = new List<PortInfo> ( );
  ConnectionOptions options = PrepareOptions ( );
  ManagementScope scope = PrepareScope ( Environment . MachineName , options , @"\root\CIMV2" );

  // Prepare the query and searcher objects.
  ObjectQuery objectQuery = new ObjectQuery ( "SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 0" );
  ManagementObjectSearcher portSearcher = new ManagementObjectSearcher ( scope , objectQuery );

  using ( portSearcher )
  {
    string caption = null;
    // Invoke the searcher and search through each management object for a COM port.
    foreach ( ManagementObject currentObject in portSearcher . Get ( ) )
    {
      if ( currentObject != null )
      {
        object currentObjectCaption = currentObject [ "Caption" ];
        if ( currentObjectCaption != null )
        {
          caption = currentObjectCaption . ToString ( );
          if ( caption . Contains ( "(COM" ) )
          {
            PortInfo portInfo = new PortInfo ( );
            portInfo . Name = caption . Substring ( caption . LastIndexOf ( "(COM" ) ) . Replace ( "(" , string . Empty ) . Replace ( ")" , string . Empty );
            portInfo . Description = caption;
            portList . Add ( portInfo );
          }
        }
      }
    }
  }
  return portList;
}

关于c# - 升级到 Windows 10 后 WMI 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34034688/

相关文章:

fonts - 如何强制Win10在C中安装字体 :\Windows\Fonts?

c# - 使用 Regex 匹配多行 C++ 样式注释

c# - "Runtime error Exception has been thrown by the target of an invocation"来自脚本任务

vb.net - Delphi:拦截 SWbemServices.ExecQuery 错误

perl - 使用 Perl 获取 WMI 内存值

node.js - 运行项目后报错: read ENOTCONN: Nodejs,

c# - 在 "inner"用户控件上使用 Caliburn.Micro 绑定(bind)功能

c# - Unity C# - 在完成之前停止执行 IJobParallelFor

powershell - 使用 PowerShell 确定访问共享文件夹的用户

intellij-idea - Intellij Idea Terminal 快捷方式不起作用