1 Star 0 Fork 28

yaongt/SerialPortForward

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
FrmMain.cs 33.45 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979
using DotNet.Utilities;
using ITLDG;
using ITLDG.DataCheck;
using ITLDG.SerialPortExtend;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SerialPortForward
{
public partial class FrmMain : Form
{
private Dictionary<string, byte[]> dicCache = new Dictionary<string, byte[]>();
private string lastSendHex = "";
string iniFile = Application.StartupPath + "\\config.ini";
string pluginDir = Application.StartupPath + "\\plugins\\";
List<IPlugin> listPlugins = new List<IPlugin>();
List<Plugin> listCheckPlugins = new List<Plugin>();
string CheckToolPath = "";
int tipIndex = -1;
string[] tips = new string[] { "本软件主要作用是转发两个串口的数据,搭配虚拟串口更好用", "校验位如果不是增加在末尾,请在HEX中填写一个错误的校验占位", "定时发送时间设置不要过小,否则可能会引起卡顿" };
//插件索引,-1为不使用插件
int pluginIndex = -1;
/// <summary>
/// 记录数据
/// </summary>
bool RecordData = false;
/// <summary>
/// 自动应答
/// </summary>
bool AutoAnswer = false;
public FrmMain()
{
InitializeComponent();
}
SerialPortInfo com1 = new SerialPortInfo(), com2 = new SerialPortInfo(), timerCom;
byte[] timerSendBytes = new byte[0];
string timerSendToName = "";
string com1Name = "", com2Name = "";
bool com1Forward = true, com2Forward = true;
PluginCommon pluginCommon;
void Com2_DataReceived(object sender, byte[] data)
{
DataReceivedHandle(com2Name, false, com2Forward, com2, com1, data);
}
void Com1_DataReceived(object sender, byte[] data)
{
DataReceivedHandle(com1Name, true, com1Forward, com1, com2, data);
}
/// <summary>
/// 串口收到数据
/// </summary>
/// <param name="name">串口名称</param>
/// <param name="isCom1">是否是串口1</param>
/// <param name="openForward">是否勾选了转发</param>
/// <param name="spReceive">收到消息的串口</param>
/// <param name="spSend">准备转发的串口</param>
/// <param name="data">收到的数据</param>
void DataReceivedHandle(string name, bool isCom1, bool openForward, SerialPortInfo spReceive, SerialPortInfo spSend, byte[] data)
{
Task.Run(() =>
{
AddLog(data, name, isCom1, openForward, spReceive, spSend);
});
}
Regex regGetComName = new Regex("^(COM(\\d+))", RegexOptions.Multiline);
public string GetCom(string ComName)
{
//strs.Add(x.COM.PadRight(5, ' ') + " - "
Match match = regGetComName.Match(ComName);
if (match.Success)
{
return match.Groups[1].Value;
}
return ComName;
}
private void btnMoreSerialOption_Click(object sender, EventArgs e)
{
if (!com1.IsOpen && !com2.IsOpen)
{
FrmMoreSerial fms = new FrmMoreSerial(ref com1, ref com2);
if (fms.ShowDialog() == DialogResult.OK)
{
SaveSerialOption();
ReadSerialOption();
}
}
else
{
MessageBox.Show("请先停止串口转发再进行操作", "请先停止", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
void SaveOption()
{
INIFileHelper ini = new INIFileHelper(iniFile);
ini.IniWriteValue("Option", "Plugin", cmbPlugins.Text);
ini.IniWriteValue("Option", "SendTo", cmbSendTo.SelectedIndex.ToString());
ini.IniWriteValue("Option", "SendHex", txtSendHex.Text);
ini.IniWriteValue("Option", "Timer", nudSend.Value.ToString());
ini.IniWriteValue("Option", "CheckPlugin", cmbCheck.Text.ToString());
ini.IniWriteValue("Option", "CheckStart", nudCheckStart.Value.ToString());
ini.IniWriteValue("Option", "CheckEnd", nudCheckEnd.Value.ToString());
ini.IniWriteValue("Option", "CheckToolPath", CheckToolPath);
ini.IniWriteValue("Option", "RecordData", RecordData.ToString());
ini.IniWriteValue("Option", "AutoAnswer", AutoAnswer.ToString());
ini.IniWriteValue("Log", "Enable", serialLog1.LogEnable.ToString());
ini.IniWriteValue("Log", "AutoScroll", serialLog1.LogAutoScroll.ToString());
ini.IniWriteValue("Log", "LogType", ((int)serialLog1.SerialLogType).ToString());
}
void ReadOption()
{
INIFileHelper ini = new INIFileHelper(iniFile);
string plugin = ini.IniReadValue("Option", "Plugin", "");
cmbSendTo.SelectedIndex = Convert.ToInt32(ini.IniReadValue("Option", "SendTo", "0"));
txtSendHex.Text = ini.IniReadValue("Option", "SendHex", "");
for (int i = 0; i < cmbPlugins.Items.Count; i++)
{
if (cmbPlugins.Items[i].ToString() == plugin)
{
cmbPlugins.SelectedIndex = i;
break;
}
}
if (cmbPlugins.SelectedIndex < 0 && cmbPlugins.Items.Count > 0) { cmbPlugins.SelectedIndex = 0; }
CheckToolPath = ini.IniReadValue("Option", "CheckToolPath", "");
nudSend.Value = Convert.ToInt32(ini.IniReadValue("Option", "Timer", "1000"));
nudCheckStart.Value = Convert.ToInt32(ini.IniReadValue("Option", "CheckStart", "1"));
nudCheckEnd.Value = Convert.ToInt32(ini.IniReadValue("Option", "CheckEnd", "0"));
string checkPlugin = ini.IniReadValue("Option", "CheckPlugin", "None");
for (int i = 1; i < cmbCheck.Items.Count; i++)
{
if (cmbCheck.Items[i].ToString() == checkPlugin)
{
cmbCheck.SelectedIndex = i;
break;
}
}
chkRecordData.Checked = ini.IniReadValue("Option", "RecordData", "False") == "True";
chkAutoAnswer.Checked = ini.IniReadValue("Option", "AutoAnswer", "False") == "True";
serialLog1.LogEnable = ini.IniReadValue("Log", "Enable", "True") == "True";
serialLog1.LogAutoScroll = ini.IniReadValue("Log", "AutoScroll", "True") == "True";
serialLog1.SerialLogType = (ITLDG.LogType)Convert.ToInt32(ini.IniReadValue("Log", "LogType", "0"));
}
void SaveSerialOption()
{
INIFileHelper ini = new INIFileHelper(iniFile);
SerialSave(com1, "Com1", ini);
SerialSave(com2, "Com2", ini);
SerialOtherSave(ini);
}
void SerialSave(SerialPortInfo sp, string Name, INIFileHelper ini)
{
ini.IniWriteValue(Name, "PortName", sp.PortName.ToString());
ini.IniWriteValue(Name, "Stop", sp.StopBits.ToString());
ini.IniWriteValue(Name, "Data", sp.DataBits.ToString());
ini.IniWriteValue(Name, "Parity", sp.Parity.ToString());
ini.IniWriteValue(Name, "Dtr", sp.DtrEnable.ToString());
ini.IniWriteValue(Name, "Rts", sp.RtsEnable.ToString());
ini.IniWriteValue(Name, "BaudRate", sp.BaudRate.ToString());
ini.IniWriteValue(Name, "Timer", sp.Timer.ToString());
ini.IniWriteValue(Name, "TimeOut", sp.TimeOut.ToString());
ini.IniWriteValue(Name, "IP", sp.IP.ToString());
ini.IniWriteValue(Name, "Port", sp.Port.ToString());
}
void SerialOtherSave(INIFileHelper ini)
{
ini.IniWriteValue("Com1", "Name", com1Name);
ini.IniWriteValue("Com2", "Name", com2Name);
ini.IniWriteValue("Com1", "Forward", com1Forward.ToString());
ini.IniWriteValue("Com2", "Forward", com2Forward.ToString());
}
void SerialOtherRead(INIFileHelper ini)
{
txtName1.Text = ini.IniReadValue("Com1", "Name", "");
txtName2.Text = ini.IniReadValue("Com2", "Name", "");
chkForward1.Checked = Convert.ToBoolean(ini.IniReadValue("Com1", "Forward", "true"));
chkForward2.Checked = Convert.ToBoolean(ini.IniReadValue("Com2", "Forward", "true"));
}
void ReadSerialOption()
{
INIFileHelper ini = new INIFileHelper(iniFile);
SerialRead(com1, "Com1", cmbBaudRate1, ini);
SerialRead(com2, "Com2", cmbBaudRate2, ini);
SerialOtherRead(ini);
}
void SerialRead(SerialPortInfo sp, string Name, ComboBox cmb, INIFileHelper ini)
{
sp.PortName = ini.IniReadValue(Name, "PortName", sp.PortName.ToString());
sp.StopBits = (StopBits)Enum.Parse(typeof(StopBits), ini.IniReadValue(Name, "Stop", sp.StopBits.ToString()));
sp.DataBits = Convert.ToInt32(ini.IniReadValue(Name, "Data", sp.DataBits.ToString()));
sp.Parity = (Parity)Enum.Parse(typeof(Parity), ini.IniReadValue(Name, "Parity", sp.Parity.ToString()));
sp.DtrEnable = Convert.ToBoolean(ini.IniReadValue(Name, "Dtr", sp.DtrEnable.ToString()));
sp.RtsEnable = Convert.ToBoolean(ini.IniReadValue(Name, "Rts", sp.RtsEnable.ToString()));
sp.BaudRate = Convert.ToInt32(ini.IniReadValue(Name, "BaudRate", "9600"));
sp.Timer = Convert.ToInt32(ini.IniReadValue(Name, "Timer", "0"));
sp.TimeOut = Convert.ToInt32(ini.IniReadValue(Name, "TimeOut", "30"));
sp.IP = IPAddress.Parse(ini.IniReadValue(Name, "IP", "0.0.0.0"));
sp.Port = Convert.ToInt32(ini.IniReadValue(Name, "Port", "8866"));
cmb.Text = sp.BaudRate.ToString();
}
private void btnReload_Click(object sender, EventArgs e)
{
refreshPortList();
}
void LoadPlugins()
{
pluginCommon = new PluginCommon(com1, com2, PluginWrite);
string[] files = Directory.GetFiles(Application.StartupPath + "\\Plugins", "*.dll");
cmbPlugins.Items.Add("不使用");
foreach (string file in files)
{
try
{
Assembly assembly = Assembly.LoadFile(file);
Type[] types = assembly.GetTypes();
foreach (Type type in types)
{
if (type.GetInterface("IPlugin") != null)
{
IPlugin plugin = (IPlugin)Activator.CreateInstance(type);
listPlugins.Add(plugin);
cmbPlugins.Items.Add(plugin.Name);
}
}
}
catch (Exception ex)
{
Console.WriteLine("加载插件失败:" + ex.Message);
}
}
}
private void FrmMain_Shown(object sender, EventArgs e)
{
try
{
ReadSerialOption();
cmbSendTo.Items[0] = com1Name;
cmbSendTo.Items[1] = com2Name;
}
catch (Exception ex)
{
Console.WriteLine("读取配置文件失败:" + ex.Message);
}
refreshPortList();
LoadPlugins();
InitCheckPlugins();
ReadOption();
NextTip();
}
void InitCheckPlugins()
{
listCheckPlugins = Plugin.GePlugins();
listCheckPlugins = listCheckPlugins.OrderBy(x => x.Name).ToList();
cmbCheck.Items.Clear();
cmbCheck.Items.Add("None");
cmbCheck.Items.AddRange(listCheckPlugins.ToArray());
cmbCheck.SelectedIndex = 0;
}
private void cmbBaudRate2_TextChanged(object sender, EventArgs e)
{
ComBaudChange(com2, cmbBaudRate2);
}
private void cmbBaudRate1_TextChanged(object sender, EventArgs e)
{
ComBaudChange(com1, cmbBaudRate1);
}
private void chkForward1_CheckedChanged(object sender, EventArgs e)
{
com1Forward = chkForward1.Checked;
}
private void chkForward2_CheckedChanged(object sender, EventArgs e)
{
com2Forward = chkForward2.Checked;
}
private void txtName1_TextChanged(object sender, EventArgs e)
{
com1Name = txtName1.Text;
cmbSendTo.Items[0] = com1Name;
}
private void txtName2_TextChanged(object sender, EventArgs e)
{
com2Name = txtName2.Text;
cmbSendTo.Items[1] = com2Name;
}
private void FrmMain_Load(object sender, EventArgs e)
{
if (!Directory.Exists(pluginDir))
{
Directory.CreateDirectory(pluginDir);
}
Text += " V" + Application.ProductVersion;
com1.DataReceived += Com1_DataReceived;
com2.DataReceived += Com2_DataReceived;
}
void PluginWrite(IPlugin plugin, bool isCom1, byte[] bytes)
{
string hex = bytes.GetString_HEX("");
Color color = Color.DarkGreen;
if (!isCom1)
{
color = Color.DarkBlue;
}
serialLog1.AddLog(plugin.Name, color, hex);
BitAnalysis(bytes);
SerialPortInfo sp = com1;
if (!isCom1)
{
sp = com2;
}
if (sp == null || !sp.IsOpen)
{
return;
}
sp.Write(bytes, 0, bytes.Length);
}
/// <summary>
/// 串口添加日志并转发
/// </summary>
/// <param name="data">收到的数据</param>
/// <param name="name">串口名称</param>
/// <param name="isCom1">是否是串口1</param>
/// <param name="openForward">是否勾选了转发</param>
/// <param name="spReceive">收到数据的串口</param>
/// <param name="spSend">将转发到的串口</param>
/// <param name="isAuto">这条消息是否来自自动回复</param>
private void AddLog(byte[] data, string name, bool isCom1, bool openForward, SerialPortInfo spReceive, SerialPortInfo spSend, bool isAuto = false)
{
byte[] rep = null;
if (!isAuto && pluginIndex >= 0)
{
try
{
rep = listPlugins[pluginIndex].GetBytes(isCom1, name, ref data);
}
catch (Exception ex)
{
serialLog1.AddLog(listPlugins[pluginIndex].Name + " 插件处理异常", Color.DarkRed, Encoding.Default.GetBytes(ex.Message));
}
}
string hex = data.GetString_HEX("");
Color color = Color.DarkBlue;
if (!isCom1)
{
color = Color.DarkGreen;
}
serialLog1.AddLog(name, color, hex);
BitAnalysis(data);
if (isAuto) { return; }
if (rep != null && rep.Length > 0)
{
BitAnalysis(rep);
spReceive.Write(rep, 0, rep.Length);
AddLog(rep, "插件答复", isCom1: !isCom1, openForward: openForward, spSend, spReceive, true);
return;
}
if (isCom1 && AutoAnswer && dicCache.ContainsKey(hex))
{
spReceive.Write(dicCache[hex], 0, dicCache[hex].Length);
BitAnalysis(dicCache[hex]);
AddLog(dicCache[hex], "自动应答-" + com2Name, isCom1: false, openForward: false, spSend, spReceive, true);
return;
}
//!hex.Contains("0D0D0A") &&
if (isCom1)
{
lastSendHex = hex;
}
else if (RecordData && !string.IsNullOrEmpty(lastSendHex))
{
if (dicCache.ContainsKey(lastSendHex))
{
dicCache[lastSendHex] = data;
}
else
{
dicCache.Add(lastSendHex, data);
}
Invoke((MethodInvoker)delegate
{
UpCacheCount();
});
}
if (openForward && spSend.IsOpen)
{
spSend.Write(data, 0, data.Length);
}
}
void BitAnalysis(byte[] bytes)
{
if (frm != null && !frm.IsDisposed)
{
frm.NewData(bytes);
}
}
void RunUI(Action action)
{
Invoke((MethodInvoker)delegate
{
action();
});
}
void OpenSerial(SerialPortInfo sp, ComboBox cmbCom, ComboBox cmbBaudRate, Button btnCom)
{
if (cmbCom.SelectedIndex < 0)
{
MessageBox.Show("未获取到串口号,不可以打开空的串口", "打开失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
string comNameTemp = GetCom(cmbCom.Text);
if ((sp == com1 ? com2 : com1).IsOpen && cmbCom1.Text == cmbCom2.Text)
{
MessageBox.Show("不可转发两个相同的串口", "打开失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
try
{
sp.PortName = comNameTemp;
sp.BaudRate = Convert.ToInt32(cmbBaudRate.Text);
sp.Open();
SaveSerialOption();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "打开失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
RunUI(() =>
{
cmbCom.Enabled = false;
btnCom.Text = "关闭";
CheckSendEnable();
});
}
void CloseSerial(SerialPortInfo sp)
{
if (sp == com1)
{
CloseSerial(com1, cmbCom1, btnCom1);
}
else
{
CloseSerial(com2, cmbCom2, btnCom2);
}
}
void CloseSerial(SerialPortInfo sp, ComboBox cmbCom, Button btnCom)
{
try
{
sp.Close();
}
catch (Exception)
{
}
RunUI(() =>
{
cmbCom.Enabled = true;
btnCom.Text = "打开";
CheckSendEnable();
});
}
private void btnCom1_Click(object sender, EventArgs e)
{
if (btnCom1.Text == "打开")
{
OpenSerial(com1, cmbCom1, cmbBaudRate1, btnCom1);
}
else
{
CloseSerial(com1, cmbCom1, btnCom1);
}
}
private void btnCom2_Click(object sender, EventArgs e)
{
if (btnCom2.Text == "打开")
{
OpenSerial(com2, cmbCom2, cmbBaudRate2, btnCom2);
}
else
{
CloseSerial(com2, cmbCom2, btnCom2);
}
}
void CheckSendEnable()
{
bool enable = false;
if (cmbSendTo.SelectedIndex == 0 && com1.IsOpen)
{
enable = true;
}
else if (cmbSendTo.SelectedIndex == 1 && com2.IsOpen)
{
enable = true;
}
btnSend.Enabled = enable;
if (!enable)
{
timerSend.Enabled = false;
chkTimer.Checked = false;
}
chkTimer.Enabled = enable;
}
private void serialLog1_Load(object sender, EventArgs e)
{
}
private void timerCom1_Tick(object sender, EventArgs e)
{
DataShow(com1Name, true, com1Forward, com1, com2);
}
private void timerCom2_Tick(object sender, EventArgs e)
{
DataShow(com2Name, false, com2Forward, com2, com1);
}
void DataShow(string name, bool isCom1, bool openForward, SerialPortInfo spReceive, SerialPortInfo spSend)
{
if (!spReceive.IsOpen)
{
return;
}
try
{
int length = spReceive.BytesToRead;
if (length == 0)//没数据,退出去
return;
byte[] rev = new byte[length];
spReceive.Read(rev, 0, length);//读数据
if (rev.Length == 0)
return;
AddLog(rev, name, isCom1, openForward, spReceive, spSend);
}
catch (Exception)
{
return;
}//崩了?
}
private void btnLoadCache_Click(object sender, EventArgs e)
{
Import();
}
private void UpCacheCount()
{
lblDataCount.Text = dicCache.Count.ToString();
}
private void Import()
{
OpenFileDialog ofd = new OpenFileDialog
{
Title = "请选择缓存文件",
Filter = "缓存数据|*.json"
};
if (ofd.ShowDialog() == DialogResult.OK)
{
try
{
dicCache.Clear();
string jsonStr = File.ReadAllText(ofd.FileName);
Dictionary<string, string> dicCacheTemp = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonStr);
foreach (var item in dicCacheTemp)
{
dicCache.Add(item.Key.Replace(" ", ""), item.Value.Replace(" ", "").GetBytes_HEX());
}
UpCacheCount();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "加载失败", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
}
private void Save()
{
SaveFileDialog sfd = new SaveFileDialog
{
Title = "选择保存路径",
Filter = "缓存数据|*.json"
};
if (sfd.ShowDialog() == DialogResult.OK)
{
try
{
Dictionary<string, string> dicJson = new Dictionary<string, string>();
foreach (var item in dicCache)
{
dicJson.Add(item.Key.GetBytes_HEX().GetString_HEX(), item.Value.GetString_HEX());
}
var settings = new JsonSerializerSettings
{
Formatting = Formatting.Indented
};
string jsonStr = JsonConvert.SerializeObject(dicJson, settings);
File.WriteAllText(sfd.FileName, jsonStr);
MessageBox.Show("保存成功");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "保存失败", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
}
private void btnSave_Click(object sender, EventArgs e)
{
Save();
}
private void cmbPlugins_SelectedIndexChanged(object sender, EventArgs e)
{
if (pluginIndex >= 0)
{
try
{
listPlugins[pluginIndex].UnCheck();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "插件错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
pluginIndex = cmbPlugins.SelectedIndex - 1;
if (pluginIndex >= 0)
{
btnPluginOption.Enabled = listPlugins[pluginIndex].HasOption;
listPlugins[pluginIndex].Checked(pluginCommon);
}
else
{
btnPluginOption.Enabled = false;
}
}
private void btnClearCache_Click(object sender, EventArgs e)
{
dicCache.Clear();
UpCacheCount();
}
private void FrmMain_FormClosed(object sender, FormClosedEventArgs e)
{
SaveOption();
}
private void btnSend_Click(object sender, EventArgs e)
{
if (!txtSendHex.IsHex())
{
return;
}
timerSendToName = cmbSendTo.Text;
SerialPortInfo sp = com1;
if (cmbSendTo.SelectedIndex == 1)
{
sp = com2;
}
byte[] bytes = GetSendBytes();
DebugSend(sp, bytes);
}
byte[] GetSendBytes()
{
byte[] bytes = txtSendHex.Text.GetBytes_HEX();
if (cmbCheck.SelectedIndex <= 0)
{
return bytes;
}
int start = (int)nudCheckStart.Value - 1;
int end = (int)nudCheckEnd.Value - 1;
if (start < 0 || end < 0 || start >= bytes.Length || end >= bytes.Length)
{
return bytes;
}
int bytesLength = (bytes.Length - end) - start;
byte[] bytesCheck = new byte[bytesLength];
Array.Copy(bytes, start, bytesCheck, 0, bytesLength);
int checkIndex = cmbCheck.SelectedIndex - 1;
byte[] bytesCheckResult = listCheckPlugins[checkIndex].CheckData(bytesCheck);
List<byte> listBytes = new List<byte>();
listBytes.AddRange(bytes);
if (end == 0)
{
listBytes.AddRange(bytesCheckResult);
}
else
{
end = bytes.Length - end;
listBytes.RemoveRange(end, bytesCheckResult.Length);
listBytes.InsertRange(end, bytesCheckResult);
}
return listBytes.ToArray();
}
private void lblDataCount_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
bool temp = RecordData;
RecordData = false;
FrmDatas frmDatas = new FrmDatas(dicCache);
frmDatas.SaveDatasEvent += FrmDatas_SaveDatasEvent;
frmDatas.ShowDialog();
UpCacheCount();
RecordData = temp;
}
private void FrmDatas_SaveDatasEvent(Dictionary<string, byte[]> dic)
{
dicCache = dic;
}
private void chkTimer_CheckedChanged(object sender, EventArgs e)
{
if (chkTimer.Checked && (txtSendHex.Text == "" || !txtSendHex.IsHex()))
{
MessageBox.Show("请先输入正确的HEX字符串", "发送消息错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
chkTimer.Checked = false;
return;
}
if (chkTimer.Checked)
{
timerSendBytes = GetSendBytes();
timerSend.Interval = (int)nudSend.Value;
timerSendToName = cmbSendTo.Text;
}
txtSendHex.Enabled = cmbCheck.Enabled = nudCheckStart.Enabled = nudCheckEnd.Enabled = cmbSendTo.Enabled = !chkTimer.Checked;
timerSend.Enabled = chkTimer.Checked;
}
private void cmbSendTo_SelectedIndexChanged(object sender, EventArgs e)
{
timerCom = com1;
if (cmbSendTo.SelectedIndex == 1)
{
timerCom = com2;
}
CheckSendEnable();
}
private void nudSend_ValueChanged(object sender, EventArgs e)
{
timerSend.Interval = (int)nudSend.Value;
}
private void timerSend_Tick(object sender, EventArgs e)
{
DebugSend(timerCom, timerSendBytes);
}
private void tsslTip_MouseHover(object sender, EventArgs e)
{
timerTip.Enabled = false;
}
private void tsslTip_MouseLeave(object sender, EventArgs e)
{
timerTip.Enabled = true;
}
private void timerTip_Tick(object sender, EventArgs e)
{
NextTip();
}
void NextTip()
{
tipIndex++;
if (tipIndex >= tips.Length)
{
tipIndex = 0;
}
tsslTip.Text = tips[tipIndex];
}
private void btnCheckTool_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(CheckToolPath) && File.Exists("CheckTool.exe"))
{
Process.Start("CheckTool.exe");
return;
}
if (File.Exists(CheckToolPath))
{
Process.Start(CheckToolPath);
return;
}
if (MessageBox.Show("工具路径未配置或不存在,是否立即配置?", "错误", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
{
return;
}
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "exe文件|*.exe";
openFileDialog.Title = "选择校验工具";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
CheckToolPath = openFileDialog.FileName;
Process.Start(CheckToolPath);
}
}
private void chkRecordData_CheckedChanged(object sender, EventArgs e)
{
RecordData = chkRecordData.Checked;
}
private void chkAutoAnswer_CheckedChanged(object sender, EventArgs e)
{
AutoAnswer = chkAutoAnswer.Checked;
}
private void btnPluginOption_Click(object sender, EventArgs e)
{
listPlugins[pluginIndex].Option();
}
FrmBitAnalysis frm;
private void btnBit_Click(object sender, EventArgs e)
{
if (frm == null || frm.IsDisposed)
{
frm = new FrmBitAnalysis();
}
frm.Show();
frm.Activate();
}
void DebugSend(SerialPortInfo sp, byte[] bytes)
{
if (sp == null)
{
return;
}
if (!sp.IsOpen)
{
CloseSerial(sp);
return;
}
if (sp == com2)
{
lastSendHex = bytes.GetString_HEX("");
}
try
{
sp.Write(bytes, 0, bytes.Length);
}
catch (Exception ex)
{
CloseSerial(sp);
MessageBox.Show(ex.Message, "发送失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
serialLog1.AddLog("串口调试-" + timerSendToName, Color.OrangeRed, bytes);
}
void ComBaudChange(SerialPortInfo sp, ComboBox cmb)
{
if (int.TryParse(cmb.Text, out int baud))
{
sp.BaudRate = baud;
}
}
private bool refreshLock = false;
/// <summary>
/// 刷新设备列表
/// </summary>
private void refreshPortList()
{
if (refreshLock)
return;
refreshLock = true;
cmbCom1.Items.Clear();
cmbCom2.Items.Clear();
List<string> strs = new List<string>();
Task.Run(() =>
{
SerialPortExtensions.GetPortNames().ForEach(x =>
{
strs.Add(x.COM.PadRight(5, ' ') + " - " + x.Name);
});
strs.Add(SerialPortInfo.SERIAL_TCP_SERVER);
strs.Add(SerialPortInfo.SERIAL_TCP_CLIENT);
this.Invoke((MethodInvoker)delegate ()
{
for (int i = 0; i < strs.Count; i++)
{
string name = strs[i];
cmbCom1.Items.Add(name);
cmbCom2.Items.Add(name);
if (name == com1.PortName || name.StartsWith(com1.PortName + " "))
{
cmbCom1.SelectedIndex = i;
}
if (name == com2.PortName || name.StartsWith(com2.PortName + " "))
{
cmbCom2.SelectedIndex = i;
}
}
if (strs.Count >= 1)
{
cmbCom1.SelectedIndex = cmbCom1.SelectedIndex == -1 ? 0 : cmbCom1.SelectedIndex;
cmbCom2.SelectedIndex = cmbCom2.SelectedIndex == -1 ? 0 : cmbCom2.SelectedIndex;
btnCom1.Enabled = btnCom2.Enabled = true;
}
else
{
btnCom1.Enabled = btnCom2.Enabled = false;
}
refreshLock = false;
});
});
}
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C#
1
https://gitee.com/yaongt/serial-port-forward.git
git@gitee.com:yaongt/serial-port-forward.git
yaongt
serial-port-forward
SerialPortForward
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385