【问题标题】:querying WMI WIN32_SerialPort locks up serial port查询 WMI WIN32_SerialPort 锁定串口
【发布时间】:2014-03-12 16:44:37
【问题描述】:

运行以下代码会锁定我的 com 端口,我很想知道原因。我在 SO 上发现了几个类似的未回答问题...

我正在使用蓝牙适配器 (RN-41) 进行串行连接。适配器 SPP 创建两个虚拟 com 端口(这对我们测试过的所有适配器都是通用的)。 Windows 将它们标记为 Incoming 和 Outgoing,但 Incoming 是唯一实际携带串行数据的。

这给我留下了“额外的”虚拟串行端口。我用可用的 Com 端口填充了一个下拉列表,以便用户可以从列表中选择要连接的端口。

在此之前,我正在过滤该列表以删除“假”com 端口。这是我的代码:

public string checkBluetoothCom()
        {
            string bluetoothComm = "";
            List<string> badComPorts = new List<string>();
            ManagementClass processClass = new ManagementClass("WIN32_SerialPort");

            ManagementObjectCollection Ports = processClass.GetInstances();

            foreach (ManagementObject property in Ports)
            {
                if (property.GetPropertyValue("Name").ToString().Contains("Bluetooth"))
                {
                    string hardwareAddress = property.GetPropertyValue("PNPDeviceID").ToString().Split('&')[4].Split('_')[0];
                    if (!hardwareAddress.All(c => c == '0'))
                    {
                        bluetoothComm = property.GetPropertyValue("DeviceID").ToString();
                    }
                    else
                    {
                        badComPorts.Add(property.GetPropertyValue("DeviceID").ToString());
                    }
                }
            }

            Console.WriteLine("Removing {0} items from comm port list", badComPorts.Count);
            ports.RemoveAll(item => badComPorts.Contains(item));

            return bluetoothComm;
        }

问题是,在此运行后,我的 Com 端口锁定,我无法建立任何连接,直到我移除蓝牙适配器并重新启动远程设备 (RN-41)。有什么想法吗?

【问题讨论】:

  • 可能是因为这是一个同步查询。在查询win32_LogicalDisk 时,USB 安装也会发生同样的情况。您可能需要切换到异步 WQL 查询。 msdn.microsoft.com/en-us/library/cc143292.aspx
  • 这是正确的@David-SkyMesh。如果您将其添加为答案,我会接受。并感谢您的指导,非常有帮助!
  • @MatthewHilgenfeld 您能否提供执行异步查询并解决问题的代码?

标签: c# .net bluetooth serial-port wmi


【解决方案1】:

如果您查询“Win32_PnPEntity”而不是“Win32_SerialPort”并检查 COM 端口 ClassGuid {4d36e978-e325-11ce-bfc1-08002be10318},则该端口未被锁定或访问。

PowerShell 示例:

Get-WmiObject -Query "SELECT Name,DeviceID FROM Win32_PnPEntity WHERE ClassGuid=`"{4d36e978-e325-11ce-bfc1-08002be10318}`""

这给出了设备管理器中所有 COM 端口的列表。

来源:Finding information about all serial devices connected through USB in C#

【讨论】:

  • Synck 的回答暗示了这一点,但我想让它更明显:“Win32_SerialPort”并不总是包含所有串行端口(如您所见,当您点击提供的链接时)
【解决方案2】:

对于某些资源类型(通常是物理端口),使用“同步”(甚至“半同步”)WQL 查询可能会中断(甚至导致拒绝服务)管理这些资源的服务。

例如,如果您在插入 USB 闪存设备时查询win32_LogicalDisk,它可能无法作为逻辑卷挂载。

您可能需要进行“异步”查询。

参考:How to perform Asynchronous WMI WQL queries. (C#)

有两种“异步”WQL 查询消费者:“临时”和“永久”。

“临时”消费者是您只需运行轮询循环、发送带有一定超时(例如 2 秒)的“异步”WQL 查询的程序。如果在超时时间内没有发生任何事情,则查询返回一个空的结果集,然后您重新开始循环(发送另一个查询)。

“永久”消费者自己注册到 WMI 服务。 Windows Powershell 的PowerEvents 是该领域工具的一个很好的例子。

【讨论】:

  • 我非常感谢有关为什么半同步和同步请求在这里受到指责的额外信息。找到这个关于如何使用 WMI 枚举 COM 端口的答案,很担心。谷歌搜索此类信息,一无所获。
  • @Codeguard 我不知道为什么。在尝试为 Firefox 实现 USB 存储插入/弹出/移除观察程序时,我第一次遇到了这个问题。 stackoverflow.com/questions/21399770/… 。不过,它似乎并不局限于 USB 存储和串行设备。我再次经历了同样的事情,监控基于 USB 的视频捕获设备的附件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-25
  • 2013-12-20
  • 1970-01-01
相关资源
最近更新 更多