如何获取RS232串口与本地笔记本电脑之间的历史命令?

How to have command history between RS232 Serial Port and local laptop?

我正在开发 C# Console app 来与 SAS 扩展卡上的固件交互。

卡已通过 RS232 端口连接。

我已经发送了命令并在控制台应用程序上得到了结果。

现在我想要一个记录命令的功能

当我使用PuTTY发送命令时,

我发现当我按下 UpArrow 键时,它会显示最后一条命令。

这是PuTTY的结果:

按下前UpArrow Key

按下后UpArrow Key

这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.IO.Ports;
using System.Threading;

namespace ConsoleApp3
{
    class Program
    {
        [STAThread]
        static void Main()
        {

            SerialPort mySerialPort = new SerialPort("COM5");

            mySerialPort.BaudRate = 115200;
            mySerialPort.Parity = Parity.None;
            mySerialPort.StopBits = StopBits.One;
            mySerialPort.DataBits = 8;
            mySerialPort.Handshake = Handshake.None;
            mySerialPort.RtsEnable = true;
            mySerialPort.DtrEnable = true;
            mySerialPort.ReadTimeout = 2000;
            mySerialPort.WriteTimeout = 1500;
            mySerialPort.Open();
            if (mySerialPort.IsOpen)
            {

                mySerialPort.Write("\r");

            }
            mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
            while (true)
            {
                
                if (Console.KeyAvailable)
                {
                    ConsoleKeyInfo userResponse = Console.ReadKey(true);
                    List<string> Command = new List<string>();
                    if (userResponse.KeyChar.ToString() == "s")
                    {
                        Command.Add("s");
                        mySerialPort.Write("s");

                    }
                    else if (userResponse.KeyChar.ToString() == "y")
                    {
                        Command.Add("y");
                        mySerialPort.Write("y");

                    }
                    else if (userResponse.Key == ConsoleKey.UpArrow)
                    {

                        for (int i = 0; i < Command.Count; i++)
                        {
                            Console.WriteLine(Command[i]);

                        }
                        Console.ReadLine();
                        Command.Clear();
                    }
                    else
                    {
                        mySerialPort.Write("\r");
                        
                    }
                } 
            }
        }
        private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            string indata = sp.ReadExisting();
            Console.Write(indata);
        }

    }

}

代码的结果是什么:

当我按UpArrow键两次时,应用程序显示两个space进入。

那是图片中的第二个 bp1>

图片看起来像:

我按下enter键后,又出现了bp1>

我开始发送 sys 命令,它没有得到响应,但出现 space 进入。

在我再次按下 EnterUpArrow 键后,sys 命令出现。

我的代码有什么问题?

还有其他改进方法吗?

我的控制台应用程序正在使用 .Net Framework 4.7.2

更好的方法是使用mono/LineEditor,kunif在评论中怎么说的。另一种方式是这样的:

using System;
using System.Collections.Generic;
using System.IO.Ports;

namespace ConsoleApp3
{
    class Program
    {
        static void Main()
        {

            SerialPort mySerialPort = new SerialPort("COM5");

            mySerialPort.BaudRate = 115200;
            mySerialPort.Parity = Parity.None;
            mySerialPort.StopBits = StopBits.One;
            mySerialPort.DataBits = 8;
            mySerialPort.Handshake = Handshake.None;
            mySerialPort.RtsEnable = true;
            mySerialPort.DtrEnable = true;
            mySerialPort.ReadTimeout = 2000;
            mySerialPort.WriteTimeout = 1500;
            // mySerialPort.NewLine = "\r";     // implement this if you use "string indata = sp.ReadLine();" in event handler
            mySerialPort.Open();

            //if (mySerialPort.IsOpen)
            //{
            //    mySerialPort.Write("\r");
            //}

            List<string> Commands = new List<string>();
            string command = "";
            int counter = 0;
            //mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
            while (true)
            {
                ConsoleKeyInfo consoleInput = Console.ReadKey();

                if (consoleInput.KeyChar == '\r')
                {
                    Commands.Add(command);
                    counter = Commands.Count - 1;
                    //mySerialPort.Write(command + "\r");
                    ClearCurrentConsoleLine();
                    command = "";
                }
                else if (consoleInput.Key == ConsoleKey.UpArrow)
                {
                    if ((counter >= 0) && (counter < Commands.Count))
                    {
                        ClearCurrentConsoleLine();
                        Console.Write(Commands[counter]);
                    }

                    if (counter > 0)
                    {
                        counter--;
                    }
                    else 
                    {
                        counter = Commands.Count - 1;
                    }
                }
                else
                {
                    command += consoleInput.KeyChar.ToString();
                }
            }
        }
        private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            string indata = sp.ReadExisting();      // it might be better to use --> string indata = sp.ReadLine();
            Console.Write(indata);
        }

        private static void ClearCurrentConsoleLine()
        {
            int currentLineCursor = Console.CursorTop;
            Console.SetCursorPosition(0, Console.CursorTop);
            Console.Write(new string(' ', Console.WindowWidth));
            Console.SetCursorPosition(0, currentLineCursor);
        }
    }
}

我在没有串行通信的情况下测试了代码。如果您清除我的评论,串行通信应该可以正常工作。