在真实和虚拟串行端口

时间:2016-12-02 11:27:08

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

我正在开发一个可以自动测试遗留应用程序的实用程序。遗留应用程序在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#app如下:

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();
    }
}

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

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

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

是否可以选择伪造真实串口的输出?

3 个答案:

答案 0 :(得分:1)

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

OLD APP - &gt; COM1 - &gt; COM4 - &gt;您的应用 - &gt; COM7(打印机)

答案 1 :(得分:0)

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

使用crossover cable(&#34; null调制解调器&#34;)将其中一个PC端口(COM6)插入另一个端口(COMx)(交换Tx和Rx)。 您现在可以使用两个使用2个不同应用程序相互连接的端口,在另一个端口上发送的每个字节在另一个端口上接收,反之亦然。

这两个端口都是真实的。

您现在可以使用COMx使用其他应用程序模拟您的设备。

答案 2 :(得分:0)

我设法通过以下方式启动并运行完全自动化的测试系统:

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

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

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

一个小的观察是我需要在修改过的exe中使用“真正的”COM端口名称。我不能用“COMA”作为例子。它需要是COM1到COM9。