升级到Windows 10后,WMI无法正常工作 [英] WMI not working after upgrading to Windows 10
问题描述
我一直在使用下面的代码在Windows 8在Visual Studio控制台应用程序返回连接的串行设备的描述和设备ID。我是用这个修改后的版本在应用程序中,我创建自动检测一个Arduino的COM端口。因为我已经做了新鲜与Windows 10安装我有一个USB转串口的AVR编程器,仍然显示了但是使用此代码它不再返回任何东西。我查了注册表和Arduino是在SERIALCOMM上市,Arduino是显示为下USB串行端口(COM6)''端口(COM和放大器; LPT)在设备管理器,我可以使用Arduino的软件程序Arduino的。我不知道为什么它不工作更多的
使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;使用System.Threading.Tasks
;
使用System.Management;使用System.IO.Ports
;使用System.Diagnostics程序
;
命名ConsoleApplication1
{
类节目
{
静态无效的主要()
{
管理范围connectionScope =新的管理范围();
SelectQuery serialQuery =新SelectQuery(SELECT * FROM Win32_SerialPort);
ManagementObjectSearcher搜索=新ManagementObjectSearcher(connectionScope,serialQuery);
试
{
的foreach
{
desc字符串=项目[说明(中searcher.Get()的ManagementObject项目)的ToString( );
串的DeviceID =项目[的DeviceID]的ToString();
Console.WriteLine(DESC);
Console.WriteLine(DEVICEID);
}
}
赶上(ManagementException E)
{
Console.WriteLine(e.Message);
}
Console.ReadKey();
}
}
}
这也可能是相关的而试图找到一个解决方案,我发现了以下实施,以寻找使用MSSerial_PortName端口名称,并收到拒绝访问错误。
使用系统;
使用System.Management;
命名ConsoleApplication1
{
类节目
{
静态无效的主要()
{
试
{
ManagementObjectSearcher MOSearcher =新ManagementObjectSearcher(root\\WMI,SELECT * FROM MSSerial_PortName);
的foreach(的ManagementObject MOject在MOSearcher.Get())
{
Console.WriteLine(MOject [端口名称]);
}
}
赶上(ManagementException我)
{
Console.WriteLine(在查询WMI数据时出现错误:+ me.Message);
}
Console.ReadKey();
}
}
}
好吧,我想我现在看到的问题(我将添加一个新的答案,但不会取代的情况下,有人发现有用的信息的旧)。
Win32_SerialPort
仅检测硬件串行端口(如RS232)。
Win32_PnPEntity
标识插件和播放设备,包括硬件和虚拟串行端口(如COM由FTDI驱动程序创建端口)。
要使用 Win32_PnPEntity
来识别驱动器需要一些额外的工作。下面的代码标识系统上的所有的COM端口,并产生所述端口的列表。从这个列表中,您可能确定适当的COM端口号来创建你的SerialPort对象。
//类包含的端口信息。
公共类PortInfo
{
字符串名称;
字符串描述;
}
//法制备WMI查询连接选项。
公共静态ConnectionOptions PrepareOptions()
{
ConnectionOptions选项=新ConnectionOptions();
选项。 ImpersonationLevel = ImpersonationLevel。模仿;
选项。 AuthenticationLevel = AuthenticationLevel。默认;
选项。 EnablePriveleges = TRUE;
返回选项;
}
//法制备WMI查询管理范围。
公共静态管理范围PrepareScope(字符串计算机名,ConnectionOptions选项字符串路径)
{
管理范围范围=新的管理范围();
范围。路径=新ManagementPath(@\\+计算机名+路径);
范围。选项=选择;
范围。连接();
返回范围;
}
//方法来检索所有COM端口的列表。
公共静态列表< PortInfo> FindComPorts()
{
名单,LT; PortInfo> portList =新的List< PortInfo> ();
ConnectionOptions选项= PrepareConnectionOptions();
管理范围范围= ProcessConnection。 (环境计算机名,期权@\root\CIMV2)PrepareScope;
//准备的查询和搜索对象。
的ObjectQuery的ObjectQuery =新的ObjectQuery(SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 0);
ManagementObjectSearcher portSearcher =新ManagementObjectSearcher(范围的ObjectQuery);使用(portSearcher)
{
字符串标题= NULL
;
//调用搜索,并通过一个COM口每个管理对象进行搜索。
的foreach(的ManagementObject currentObject在portSearcher获得())
{
如果(currentObject!= NULL)
{
对象currentObjectCaption = currentObject [标题];
如果(currentObjectCaption!= NULL)
{
标题= currentObjectCaption。的ToString();
如果(标题包含((COM))
{
PortInfo portInfo =新PortInfo();
portInfo名称=标题子串(标题LastIndexOf(。 (COM))更换。((,串空。)更换。(),串空);
portInfo说明=标题;
portInfoList加入(portInfo);
}
}
}
}
}
返回portInfoList;
}
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();
}
}
}
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
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).
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
{
string Name;
string Description;
}
// Method to prepare the WMI query connection options.
public static ConnectionOptions PrepareOptions ( )
{
ConnectionOptions options = new ConnectionOptions ( );
options . ImpersonationLevel = ImpersonationLevel . Impersonate;
options . AuthenticationLevel = AuthenticationLevel . Default;
options . EnablePriveleges = 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 = PrepareConnectionOptions ( );
ManagementScope scope = ProcessConnection . 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;
portInfoList . Add ( portInfo );
}
}
}
}
}
return portInfoList;
}
这篇关于升级到Windows 10后,WMI无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!