【问题标题】:Creating a pair between a real and virtual serial port在真实和虚拟串行端口之间创建一对
【发布时间】:2016-12-02 11:27:07
【问题描述】:

我正在开发一个可以自动测试遗留应用程序的实用程序。旧版应用程序在 Windows 2000 上运行,并使用通过串行 (COM) 端口连接的 3 个设备。

我可以访问应用程序的源代码,但无权进行任何更改。但是,源代码允许我验证设备 COM 端口名称是否已作为 COM1(打印机)、COM2(钞票阅读器)和 COM3(条形码/OMR 阅读器)硬编码到应用程序中。我还可以看到发送到每个设备的字节,以及应用程序如何处理返回。

现在,我想编写有关钞票阅读器的测试。我从这里的各种问题(例如Faking an RS232 Serial Port)中读到我可以使用 com0com 来伪造串行端口。我希望有一种方法可以代表应用程序接收的真实 COM 端口设备发送字节。

安装实用程序后,我将一对配置为“COM2”到“COM6”。 COM2 标签显示为红色,当我按 OK 时,我收到以下消息:

端口名称 COM2 已被其他设备使用 \Device\Serial1

然后我可以按取消、重试或继续。

按继续我得到:

端口名称 COM2 已在 COM 端口数据库中记录为“正在使用”

我再次按继续。

我用 C# 编写了一个小应用程序来测试 COM2 和 COM6 端口配对。当我向 COM2 发送有效字节时,我得到了预期的 11 个字节(这正好反映了遗留应用程序中的一个场景)。 COM6 上没有收到任何内容。当我向 COM6 发送相同的字节时,COM2 或 COM6 都没有响应。

我已尝试重新启动机器,再次设置配对,尝试不同的 COM 端口(COM1 到 COM6,COM3 到 COM6)但从未在这些虚拟端口上得到响应(COM1 和 COM3 也是红色的,给我通过 com0com 出现相同的错误)。

测试C#应用如下:

using System;
using System.IO.Ports;

public class Com
{
    private static byte[] s_pDataSent = new byte[32];
    private static byte[] s_pDataRead = new byte[32];

    private static void port_OnReceivedDatazz(
        object sender,
        SerialDataReceivedEventArgs e)
    {
        var sp = (SerialPort)sender;
        var buffer = new byte[sp.BytesToRead];
        Console.WriteLine("DATA RECEIVED ON " + sp.PortName);
        sp.Read(buffer, 0, buffer.Length);
        foreach(var b in buffer)
        {
            Console.Write(b.ToString() + " ");
        }
        Console.WriteLine();
    }

    public void Do(string portName, string virtualPort)
    {
        var port = new SerialPort(
            portName,
            9600,
            Parity.Even,
            7,
            StopBits.One);
        port.RtsEnable = false;
        port.DtrEnable = false;
        port.DataReceived += port_OnReceivedDatazz;
        port.Open();

        if (!port.IsOpen)
        {
            Console.WriteLine("Port is closed");
        }

        var vport = new SerialPort(
            virtualPort,
            9600,
            Parity.Even,
            7,
            StopBits.One);
                vport.RtsEnable = false;
                vport.DtrEnable = false;
                vport.DataReceived += port_OnReceivedDatazz;
                vport.Open();

        if (!vport.IsOpen)
        {
            Console.WriteLine("VPort is closed");
        }

        for (var i = 0; i < s_pDataSent.Length; ++i)
        {
            s_pDataSent[i] = 0;
        }

        // populate s_pDataSent ...
        // I have left these steps out of this example
        // ...but they do exist in my test app

        port.Write(
            s_pDataSent,
            0,
            8);

        Console.ReadLine();
        Console.WriteLine("Closing");
        port.Close();
    }
}

当我使用超级终端时,我可以看到在 2 个虚拟端口之间发送消息,但在真实端口和虚拟端口之间没有发送任何消息。

是否可以通过 com0com 或其他方式将真实和虚拟 COM 端口配对?

如果是这样,我该如何解决我的问题?

是否有替代真实串行端口的伪造输出的替代方法?

【问题讨论】:

  • 为什么要配对真实和虚拟端口?你到底想做什么?你想嗅出发送到 PC 上某个串行端口的所有消息吗?
  • @Idank - 不,我想代表真实端口向连接的应用程序发送消息。我假设我可以与一个虚拟端口配对,然后写入这个端口(以便它成为真实端口上的输出)。这是错的吗?
  • 在我看来没问题,com0com 的两个配对虚拟端口有什么问题?为什么你需要第二个端口是真实的?
  • @Idank - 这些测试在连接了设备的机器上运行。该应用程序经过硬编码以连接到特定的 COM 端口,并且基本上每 200 毫秒 ping 这些设备。

标签: c# serial-port automated-tests virtual-serial-port com0com


【解决方案1】:

您可以将物理端口更改为 7、8 和 9,并将端口 1 2 3 保留为硬编码,然后您可以安装 3 个虚拟 COM 对,例如 COM1-COM4、COM2-COM5、COM3-COM6 到“旧" 应用程序可以打开,您可以监控然后将读取的字节路由到另一个端口。

旧应用程序 -> COM1 -> COM4 -> 您的应用程序 -> COM7(打印机)

【讨论】:

    【解决方案2】:

    快速而肮脏的解决方案,而不是使用 com0com:

    只需使用crossover cable(“空调制解调器”)将一个 PC 端口 (COM6) 插入另一个端口 (COMx)(交换 Tx 和 Rx)。 您现在可以将两个相互连接的端口用于 2 个不同的应用程序,在一个端口上发送的每个字节都会在另一个端口上接收,反之亦然。

    而且两个端口都是真实的。

    您现在可以使用另一个使用 COMx 的应用程序来模拟您的设备。

    【讨论】:

    • 那么向 COMx 发送字节将被正在侦听 COM2 的原始遗留应用程序读取?
    • 看来 OP 想要保持应用程序的 com 端口连接到真实设备。
    • @camelcase 是的。
    【解决方案3】:

    我设法通过以下方式启动并运行了一个全自动测试系统:

    • 使用 com0com 设置 2 个虚拟端口配对(COM6-COMD 和 COMI-COMJ)。
    • 编写一个简单的应用程序,通过在 COMD 上读取某些内容时将一组字节写回 COMD 来模拟设备。写回的字节将是一组默认的“无事可做”字节,除非在 COMJ 上也读取了测试字节。
    • 为我的自动化测试脚本添加了能够在 COMI 上发送特定字节的功能。例如,表示正在读取 5 英镑纸币或纸币无效的字节。
    • 使用十六进制编辑器修改旧可执行文件,将“COM2:”ascii 字符串(即硬编码端口)替换为“COM6:”。

    我现在可以设置一个测试终端,以使用原始遗留应用程序进行手动测试。所有设备都正常工作。在同一终端上,自动测试脚本链接到修改后的可执行文件。此可执行文件将使用模拟设备。

    我需要维护一个“修改后的”可执行文件,直到完成使 COM 端口在应用程序中可配置的工作。

    一个小的观察是我需要在修改后的 exe 中使用“真实”的 COM 端口名称。例如,我不能使用“COMA”。它必须是 COM1 到 COM9。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-12
      • 2014-05-02
      • 1970-01-01
      • 1970-01-01
      • 2021-01-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多