虽然c#不是我的主要编程语言,但我现在已经维护了这样一个程序几年了。此程序连接到串行端口上的设备,从Windows XP到8.1。一个特定的"功能"是它使用.NET Framework 2.0。
有些用户升级到Windows 10,我们抱怨程序无法检测/打开设备的COM端口。我们已在我们自己的测试系统上确认了这一点,并安装了干净的Win10。
事实证明,函数SerialPort.GetPortNames()返回了错误的端口名称,并添加了“奇怪的”#39;端口名称后面的字符。 例如:
等。当我刷新列表时,每次在数字后面显示另一个字符(或两个)。 测试代码非常简单:
string[] portNames = System.IO.Ports.SerialPort.GetPortNames();
log("Available ports:");
foreach (string PortAvailable in portNames)
{
log(PortAvailable);
}
其中log函数会在表单上的标准TextBox中添加一行:
txtLog.Text += Msg + Environment.NewLine;
这适用于所有其他Windows版本。 我已经检查了注册表,所有看起来都很好。 有没有人对此有所了解?
我怀疑.NET Framework 2.0不再100%兼容,虽然您可以在Windows功能中启用它,但似乎程序本身运行正常(除了我的串口问题)。我有点害怕升级到新的.NET,更不用说我们的Visual Studio 2008用于c#(max = .NET 3.5)。请注意,程序仍然需要在Windows XP上运行(POS版本仍由Microsoft维护)。
增加: 我已升级" .NET 3.5的测试程序,仍然有完全相同的问题。 下一步是安装一个新的VisualStudio(它现在似乎是免费的吗?我应该检查Studio中的隐私设置吗?; - )。
增加2: 安装了VisualStudio 2015,并使用不同的.NET框架版本进行了多个构建。 v2.0和3.5仍然添加了奇怪的字符。但是在v4.0及以上这个问题似乎已经解决了!现在为原始程序编译并为更新的Framework工作。 但是我发现这个问题非常奇怪,并且预计会遇到更多.NET函数和更多程序。
答案 0 :(得分:7)
我也见过这些奇怪的人物。我的解决方案是使用正则表达式过滤掉通信端口名称的数字部分。
Dim ports As New Devices.Ports
For Each s As String In ports.SerialPortNames
s = Regex.Replace(s, "\D*(\d+)\D*", "$1")
Debug.WriteLine(s)
Next
答案 1 :(得分:2)
我对USB CDC串行设备有同样的问题,由新改写的Windows 10 usbser.sys驱动程序处理。
垃圾字符通常是数字,因此删除非数字并不是解决它的可靠方法。对于我的解决方案,请查看我在此主题上的最后一篇文章:
..那里有代码,通过注册表,找到usbser端口,并返回他们未编码的名称。请注意,它不会返回所有串行端口,只能返回该驱动程序提供的端口。该代码适用于Windows XP到10。
底层问题是usbser.sys驱动程序创建了一个注册表项,而在.NET(至少最多3.5个)上,GetPortNames()函数尝试读取这些注册表项并获取损坏的数据。我已通过该论坛(假设他们已阅读)并使用内置的Windows 10 beta错误报告工具向Microsoft报告此情况。也许有一天会有一个修复。
答案 2 :(得分:1)
如您所说,启用Windows功能后该程序可以运行:
Windows 8 / 8.1 / 10上默认未启用.NET 2.0,3.0,3.5。这些文件不存储在安装介质/ wim上。
可以使用Windows更新中的DISM命令或本地源启用它。
DISM /Online /Enable-Feature /FeatureName:NetFx3 /All
答案 3 :(得分:1)
检查一下:http://forums.radioreference.com/uniden-tech-support/317887-windows-10-uniden-usb-driver-5.html 用于解决端口名称后由奇怪字符引起的Win 10串口无法工作的问题。
它对我有用。 博德
答案 4 :(得分:0)
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;
}