C#winform上位机开发学习笔记3-串口助手的信息保存功能添加

发布时间:2024年01月20日

1.功能描述

下次开启串口助手时会存留上次的发送框信息,以及选择的串口号(备份串口号与发送栏内容

原理:将文本信息保存在,ini文件中,下次打开软件时读取文件信息刷新对应控件文本

注意:在窗口关闭事件函数中也可进行信息备份工作,但不稳定,因此用本篇中的方法进行较为可靠

2.代码部分

2.1 创建文件与编辑写入信息存储代码

2.1.1?public partial class Form1 : Form初始化程序中加入以下代码

using System.Runtime.InteropServices;//应用空间变量声明,未声明则出现[DllImport("kernel32")]报错

public partial class Form1 : Form
    {
        //信息保存功能
        [DllImport("kernel32")]
        //写文件函数
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);//系统dll导入ini写函数
        [DllImport("kernel32")]
        //读文件函数
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);//系统dll导入ini读函数
        //创建文件,文件名为:Backup.ini
        string FileName = System.AppDomain.CurrentDomain.BaseDirectory + "Backup.ini";
    }

?#存储的文件保存在bin文件中,文件名为创建时编辑的名称“Backup.ini”

2.1.2 串口发送栏函数

备份发送栏

 //串口发送栏函数
        private void textBox5_TextChanged(object sender, EventArgs e)
        {
            //备份发送栏
            WritePrivateProfileString("串口1", "发送栏", textBox5.Text, FileName);//保存文件:其中串口1与发送栏为文本内的标识,将发送栏的信息存储在filename文件中
        }

2.1.3 手动扫描并添加串口号函数中添加备份串口号程序

备份串口号

 //备份端口号
            WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);//保存文件:其中串口1与端口号为文本内的标识,将COM组合框的信息存储在filename文件中

手动扫描并添加串口号函数完整代码如下:

        //自定义函数1-手动扫描并添加可用串口
        private void SearchAndAddSerialToComboBox(SerialPort MyPort, ComboBox MyBox)
        {
            string[] ComputerPortName = SerialPort.GetPortNames();  //获取本机串口列表
            //string BackupPort;//定义字符串备份端口号

            bool MyBackupPortFlag = false;  //备份端口号可用标志位

            //恢复端口号
            GetPrivateProfileString("串口1", "端口号", "", BackupBuf, 100, FileName);  //获取备份的端口号
            string MyBackupPortName = BackupBuf.ToString();//定义字符串备份端口号

            //添加端口号
            MyBox.Items.Clear();  //清空ComboBox内容
            for (int i = 0; i < ComputerPortName.Length; i++) //循环
            {
                if (MyBackupPortName == ComputerPortName[i])  //之前的端口号可用,置位标志位
                {
                    MyBackupPortFlag = true;
                }

                try  //核心原理是依靠try和catch完成遍历
                {
                    MyPort.PortName = ComputerPortName[i];
                    MyPort.Open();                          //如果失败,后面的代码不会执行          
                    MyBox.Items.Add(MyPort.PortName);       //打开成功,添加至下拉列表
                    MyPort.Close();                         //关闭

                    //检测备份端口号是否有效,端口号初始化为备份端口号
                    if (MyBackupPortName == MyPort.PortName)
                    {
                        comboBox1.Text = MyBackupPortName;
                    }
                    //如果备份端口号无效,端口号初始化为第一个可用端口号
                    if (comboBox1.Text == " ")
                        comboBox1.Text = MyPort.PortName;
                }
                catch
                {

                }
            }
            //端口号赋初值
            if (MyBackupPortFlag == true)
            {
                MyBox.Text = MyBackupPortName; //添加备份的端口号
            }
            else
            {
                if (ComputerPortName.Length > 0)
                {
                    MyBox.Text = ComputerPortName[ComputerPortName.Length - 1]; //添加数值大的端口号
                }
                else
                {
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("没有检测到串口工具!\r\n");
                }
            }
            //备份端口号
            WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);//保存文件:其中串口1与端口号为文本内的标识,将COM组合框的信息存储在filename文件中
        }

复选框函数中也添加此程序代码

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {//备份端口号
            WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);//保存文件:其中串口1与端口号为文本内的标识,将COM组合框的信息存储在filename文件中
        }

复选框函数万整改代码如下:

        //串口开启状态下切换串口号
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) //串口已打开,此时关闭串口 
            {
                serialPort1.Close();                       //打开端口
                try
                {
                    serialPort1.PortName = comboBox1.Text;    //端口号
                    serialPort1.Open();                       //打开端口
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("串口更换成功!\r\n");

                    WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);
                }
                catch
                {
                    serialPort1.Close();
                    button2.BackgroundImage = Properties.Resources.Image_CloseSerial;
                    button2.Tag = "OFF";
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("串口更换失败!\r\n");
                }
            }
            //备份端口号
            WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);//保存文件:其中串口1与端口号为文本内的标识,将COM组合框的信息存储在filename文件中
        }

2.2 编写读取文件赋值文本代码

2.2.1 恢复发送栏

2.2.1.1?初始化函数中加入下述代码
    public partial class Form1 : Form
    {
        //定义字符串用于存储读出的.ini文件中的内容变量,大小为100个字节
        StringBuilder BackupBuf = new StringBuilder(100);
    }
2.2.1.2?窗体装载函数中加入下述代码
        //窗体装载函数
        private void Form1_Load(object sender, EventArgs e)
        {
            //恢复发送栏
            //获取FileName中存储在BackupBuf中内存为100字节的标识为"串口1", "发送栏"的变量,恢复内容若没有则获取空字符
            GetPrivateProfileString("串口1", "发送栏", "", BackupBuf, 100, FileName);
            textBox5.Text = BackupBuf.ToString();//获取后将其转换为字符串赋值给发送栏
        }
2.2.3?恢复时判断存储的端口号是否有效,有效则恢复存储文件的端口号,无效则恢复为首端口号
        //自定义函数1-手动扫描并添加可用串口
        private void SearchAndAddSerialToComboBox(SerialPort MyPort, ComboBox MyBox)
        {
             //恢复端口号
            GetPrivateProfileString("串口1", "端口号", "", BackupBuf, 100, FileName);  //获取备份的端口号
            string MyBackupPortName = BackupBuf.ToString();//定义字符串备份端口号
        
            //检测备份端口号是否有效,端口号初始化为备份端口号
            if (MyBackupPortName == MyPort.PortName)
             {
                 comboBox1.Text = MyBackupPortName;
             }
            //如果备份端口号无效,端口号初始化为第一个可用端口号
            if (comboBox1.Text == " ")
                 comboBox1.Text = MyPort.PortName;   
        }         

手动扫描并添加串口号函数完整代码如下:

        //自定义函数1-手动扫描并添加可用串口
        private void SearchAndAddSerialToComboBox(SerialPort MyPort, ComboBox MyBox)
        {
            string[] ComputerPortName = SerialPort.GetPortNames();  //获取本机串口列表
            //string BackupPort;//定义字符串备份端口号

            bool MyBackupPortFlag = false;  //备份端口号可用标志位

            //恢复端口号
            GetPrivateProfileString("串口1", "端口号", "", BackupBuf, 100, FileName);  //获取备份的端口号
            string MyBackupPortName = BackupBuf.ToString();//定义字符串备份端口号

            //添加端口号
            MyBox.Items.Clear();  //清空ComboBox内容
            for (int i = 0; i < ComputerPortName.Length; i++) //循环
            {
                if (MyBackupPortName == ComputerPortName[i])  //之前的端口号可用,置位标志位
                {
                    MyBackupPortFlag = true;
                }

                try  //核心原理是依靠try和catch完成遍历
                {
                    MyPort.PortName = ComputerPortName[i];
                    MyPort.Open();                          //如果失败,后面的代码不会执行          
                    MyBox.Items.Add(MyPort.PortName);       //打开成功,添加至下拉列表
                    MyPort.Close();                         //关闭

                    //检测备份端口号是否有效,端口号初始化为备份端口号
                    if (MyBackupPortName == MyPort.PortName)
                    {
                        comboBox1.Text = MyBackupPortName;
                    }
                    //如果备份端口号无效,端口号初始化为第一个可用端口号
                    if (comboBox1.Text == " ")
                        comboBox1.Text = MyPort.PortName;
                }
                catch
                {

                }
            }
            //端口号赋初值
            if (MyBackupPortFlag == true)
            {
                MyBox.Text = MyBackupPortName; //添加备份的端口号
            }
            else
            {
                if (ComputerPortName.Length > 0)
                {
                    MyBox.Text = ComputerPortName[ComputerPortName.Length - 1]; //添加数值大的端口号
                }
                else
                {
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("没有检测到串口工具!\r\n");
                }
            }
            //备份端口号
            WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);//保存文件:其中串口1与端口号为文本内的标识,将COM组合框的信息存储在filename文件中
        }

3.涉及到的相关完整代码

    public partial class Form1 : Form
    {
        //信息保存功能
        [DllImport("kernel32")]
        //写文件函数
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);//系统dll导入ini写函数
        [DllImport("kernel32")]
        //读文件函数
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);//系统dll导入ini读函数
        //创建文件,文件名为:Backup.ini
        string FileName = System.AppDomain.CurrentDomain.BaseDirectory + "Backup.ini";
        //定义字符串用于存储读出的.ini文件中的内容变量,大小为100个字节
        StringBuilder BackupBuf = new StringBuilder(100);
         public Form1()
        {
            InitializeComponent();
            //串口接收支持中文显示
            serialPort1.Encoding = Encoding.GetEncoding("GB2312");  //串口1的解码支持GB2312汉字
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;//检查跨线程出错解决方法
        }
        //窗体装载函数
        private void Form1_Load(object sender, EventArgs e)
        {
            SearchAndAddSerialToComboBox(serialPort1, comboBox1);//扫描端口号,并将可用端口添加至下拉列表
            comboBox14.Text = "115200";                           //默认显示值
            this.button2.PerformClick();                         //自动打开串口

            //恢复发送栏
            //获取FileName中存储在BackupBuf中内存为100字节的标识为"串口1", "发送栏"的变量,恢复内容若没有则获取空字符
            GetPrivateProfileString("串口1", "发送栏", "", BackupBuf, 100, FileName);
            textBox5.Text = BackupBuf.ToString();//获取后将其转换为字符串赋值给发送栏
      
        }

         //自定义函数1-手动扫描并添加可用串口
        private void SearchAndAddSerialToComboBox(SerialPort MyPort, ComboBox MyBox)
        {
            string[] ComputerPortName = SerialPort.GetPortNames();  //获取本机串口列表
            //string BackupPort;//定义字符串备份端口号

            bool MyBackupPortFlag = false;  //备份端口号可用标志位

            //恢复端口号
            GetPrivateProfileString("串口1", "端口号", "", BackupBuf, 100, FileName);  //获取备份的端口号
            string MyBackupPortName = BackupBuf.ToString();//定义字符串备份端口号

            //添加端口号
            MyBox.Items.Clear();  //清空ComboBox内容
            for (int i = 0; i < ComputerPortName.Length; i++) //循环
            {
                if (MyBackupPortName == ComputerPortName[i])  //之前的端口号可用,置位标志位
                {
                    MyBackupPortFlag = true;
                }

                try  //核心原理是依靠try和catch完成遍历
                {
                    MyPort.PortName = ComputerPortName[i];
                    MyPort.Open();                          //如果失败,后面的代码不会执行          
                    MyBox.Items.Add(MyPort.PortName);       //打开成功,添加至下拉列表
                    MyPort.Close();                         //关闭

                    //检测备份端口号是否有效,端口号初始化为备份端口号
                    if (MyBackupPortName == MyPort.PortName)
                    {
                        comboBox1.Text = MyBackupPortName;
                    }
                    //如果备份端口号无效,端口号初始化为第一个可用端口号
                    if (comboBox1.Text == " ")
                        comboBox1.Text = MyPort.PortName;
                }
                catch
                {

                }
            }
            //端口号赋初值
            if (MyBackupPortFlag == true)
            {
                MyBox.Text = MyBackupPortName; //添加备份的端口号
            }
            else
            {
                if (ComputerPortName.Length > 0)
                {
                    MyBox.Text = ComputerPortName[ComputerPortName.Length - 1]; //添加数值大的端口号
                }
                else
                {
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("没有检测到串口工具!\r\n");
                }
            }
            //扫描后写入备份端口号
            WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);//保存文件:其中串口1与端口号为文本内的标识,将COM组合框的信息存储在filename文件中
        }
        //自定义函数2-CRC校验
        private UInt16 Crc_Check(byte[] Data, byte DataLEN)
        {
            UInt16 CRC = 0xFFFF;

            for (byte i = 0; i < DataLEN; i++)
            { 
                CRC ^= Data[i];
                for(byte j = 0; j < 8; j++)
                {
                    if((CRC & 0x0001) == 0x0001)
                    {
                        CRC = (UInt16)((CRC >> 1) ^ 0xA001);
                    }
                    else
                    {
                        CRC = (UInt16)(CRC >> 1);
                    }
                }
            }
            CRC = (UInt16)((CRC >> 8) + (CRC<<8));
            return CRC;
        }
        //串口开启状态下切换串口号
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) //串口已打开,此时关闭串口 
            {
                serialPort1.Close();                       //打开端口
                try
                {
                    serialPort1.PortName = comboBox1.Text;    //端口号
                    serialPort1.Open();                       //打开端口
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("串口更换成功!\r\n");

                    WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);
                }
                catch
                {
                    serialPort1.Close();
                    button2.BackgroundImage = Properties.Resources.Image_CloseSerial;
                    button2.Tag = "OFF";
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("串口更换失败!\r\n");

                    timer1.Stop();
                }
            }
            //复选框选择后备份端口号
            WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);//保存文件:其中串口1与端口号为文本内的标识,将COM组合框的信息存储在filename文件中
        }
        //串口发送栏函数
        private void textBox5_TextChanged(object sender, EventArgs e)
        {
            //备份发送栏
            WritePrivateProfileString("串口1", "发送栏", textBox5.Text, FileName);//保存文件:其中串口1与发送栏为文本内的标识,将发送栏的信息存储在filename文件中
        }
}

4.测试结果

关闭软件后重新打开发送框与com口选择框出现关闭前输入的信息,功能添加成功

此功能涉及到的代码较多,且多与其他功能函数相关,总体的逻辑为创建文件->将需要备份的信息存储在文件内->下次开启软件后自动从备份的文件中读取信息并赋值到相关的文本中,从而达到信息保存的目的

注:参考自B站硬件家园

文章来源:https://blog.csdn.net/weixin_49048045/article/details/135691865
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。