SerialPort.GetPortNames() returns 不正确的端口名称

SerialPort.GetPortNames() returns incorrect port names

虽然 c# 不是我的主要编程语言,但我已经维护这样的程序几年了。该程序连接到串行端口上的设备,适用于 Windows XP 到 8.1。一个具体的 "feature" 是它使用 .NET Framework 2.0。

随着一些用户升级到 Windows 10,我们收到抱怨程序无法 detect/open 设备的 COM 端口。我们已经在我们自己的测试系统上通过干净的 Win10 安装确认了这一点。

事实证明,函数SerialPort.GetPortNames() returns 错误的端口名称,并在端口名称后添加了'strange' 个字符。 例如:

等当我刷新列表时,每次数字后面都会出现另一个(或两个)字符。 测试代码超级简单:

  string[] portNames = System.IO.Ports.SerialPort.GetPortNames();
  log("Available ports:");
  foreach (string PortAvailable in portNames)
  {
    log(PortAvailable);
  }

其中日志函数只是向表单上的标准文本框添加一行:

  txtLog.Text += Msg + Environment.NewLine;

这适用于所有其他 Windows 版本。 我检查了注册表,那里看起来也很好。 有人对此有想法吗?

我怀疑 .NET Framework 2.0 不再是 100% 兼容的,尽管您可以在 Windows 功能中启用它并且程序本身 运行 似乎很好(除了我的串口问题)。我有点害怕升级到更新的 .NET,更不用说我们有 VisualStudio 2008 for c# (max=.NET 3.5)。请注意,该程序仍然需要 运行 在 Windows XP 上也同样(POS 版本仍由 Microsoft 维护)。

添加: 我有 "upgraded" .NET 3.5 的测试程序,但仍然有完全相同的问题。 下一步是安装一个新的 VisualStudio(现在看来它是免费的??我是否也应该检查 Studio 中的隐私设置?;-)。

添加 2: 安装了 VisualStudio 2015 并使用不同的 .NET 框架版本进行了多次构建。 v2.0 和 3.5 仍然添加了奇怪的字符。但在 v4.0 及更高版本中,这个问题似乎得到了解决!现在让原始程序编译并为更新的框架工作。 但我发现这个问题真的很奇怪,并希望这会影响更多的 .NET 功能和更多的程序。

如您所说,程序在启用 windows 功能后运行:

.NET 2.0,3.0,3.5 在 Windows 8/8.1/10 上默认未启用。文件未存储在安装 media/wim.

可以使用来自 windows 更新或本地源的 DISM 命令启用它。

DISM /Online /Enable-Feature /FeatureName:NetFx3 /All

我也见过奇怪的人物。我的解决方案是使用正则表达式过滤掉 comm 端口名称的数字部分。

Dim ports As New Devices.Ports
For Each s As String In ports.SerialPortNames
    s = Regex.Replace(s, "\D*(\d+)\D*", "")
    Debug.WriteLine(s)
Next

看看这个:http://forums.radioreference.com/uniden-tech-support/317887-windows-10-uniden-usb-driver-5.html 解决因端口名称后的奇怪字符导致的 Win 10 串口不工作的变通方法。

  1. 使用 regedit.exe 进入注册表。
  2. 导航到 "HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALC OMM"
  3. 记下通信端口名称。
  4. 在 comm 端口名称后附加一个“0”或任何字符。
  5. 将 comm 端口名称改回步骤 3 中的名称。

它对我有用。 博德

string[] ports = SerialPort.GetPortNames();

        for (int i = 0; i<ports.Length;i++)
        {
            string mystr = ports[i];
            if (((mystr[mystr.Length-1]) >= 0x30) & ((mystr[mystr.Length-1]) <= 0x39))
            {

            }
            else
            {
                mystr = mystr.Remove(mystr.Length-1);
            }
            ports[i] = mystr;
        }

我在使用 USB CDC 串行设备时遇到了完全相同的问题,由新重写的 Windows 10 usbser.sys 驱动程序处理。

垃圾字符通常是数字,因此删除非数字并不是解决此问题的可靠方法。对于我的解决方案,请在此处查看我在此线程上的最后一个 post:

https://social.msdn.microsoft.com/Forums/vstudio/en-US/a78b4668-ebb6-46aa-9985-ec41667abdde/ioportsserialportgetportnames-registrykeygetvalue-corruption-with-usbsersys-driver-on-windows?forum=netfxbcl

..那里有代码会通过注册表,找到 usbser 端口,然后 return 它们未损坏的名称。请注意,它不是 return 所有 串行端口,只是该驱动程序提供的串行端口。该代码适用于 Windows XP 到 10。

潜在的问题是 usbser.sys 驱动程序创建了一个注册表项,并且在 .NET(至少高达 3.5)上,GetPortNames() 函数尝试读取这些注册表项并获取损坏的数据。我已经通过该论坛(假设他们阅读了)和使用内置的 Windows 10 beta 错误报告工具向 Microsoft 报告了此问题。也许有一天会有一个修复。