问题描述
我一直在 Windows 8 上的 Visual Studio 中为控制台应用程序使用以下代码,以返回连接的串行设备的描述和设备 ID.我在我正在创建的应用程序中使用它的修改版本来自动检测 Arduino 的 COM 端口.自从我使用 Windows 10 进行全新安装后,它不再返回任何内容.我有一个 USB 转串行 AVR 编程器,但是仍然使用此代码显示.我检查了注册表,Arduino 列在 SERIALCOMM 中,Arduino 在设备管理器的端口(COM 和 LPT)"下显示为USB 串行端口(COM6)",我可以使用 Arduino 软件对 Arduino 进行编程.我不知道为什么它不再工作了.
I had been using the code below for a console application in Visual Studio on Windows 8 to return the description and device ID of connected serial devices. I was using a modified version of this in an application I'm creating to automatically detect the COM port of an Arduino. It no longer returns anything since I've done a fresh install with Windows 10. I have a USB to serial AVR programmer that still shows up using this code however. I checked the registry and the Arduino is listed in SERIALCOMM, the Arduino is showing as 'USB Serial Port (COM6)' under 'Ports (COM & LPT)' in Device Manager and I can program the Arduino using the Arduino software. I have no idea why it isn't working any more.
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 查找端口名称,但我收到了拒绝访问错误.
It might also be relevant that while trying to find a solution I found the following implementation to find port names using MSSerial_PortName and I got an Access Denied error.
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();
}
}
}
推荐答案
好的,我想我现在看到了问题(我会添加一个新答案,但不会替换旧答案,以防有人发现信息有用).
Ok, I think I see the issue now (I will add a new answer, but won't replace the old in case someone finds the information useful).
Win32_SerialPort
仅检测硬件串行端口(例如 RS232).Win32_PnPEntity
识别即插即用设备,包括硬件和虚拟串行端口(例如由 FTDI 驱动程序创建的 COM 端口).
Win32_SerialPort
only detects hardware serial ports (e.g. RS232).
Win32_PnPEntity
identifies plug-and-play devices including hardware and virtual serial ports (e.g. COM port created by the FTDI driver).
要使用 Win32_PnPEntity
来识别驱动程序需要一些额外的工作.以下代码识别系统上的所有 COM 端口并生成所述端口的列表.从这个列表中,您可以确定合适的 COM 端口号来创建您的 SerialPort 对象.
To use Win32_PnPEntity
to identify a driver requires a little extra work. The following code identifies all COM ports on the system and produces a list of said ports. From this list, you may identify the appropriate COM port number to create your SerialPort object.
// 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 , @"
ootCIMV2" );
// 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;
}
这篇关于升级到 Windows 10 后 WMI 无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!