1 Star 0 Fork 24

momozhufu/SerialPortForward

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
FrmMain.cs 36.21 KB
一键复制 编辑 原始数据 按行查看 历史
老大哥 提交于 2023-09-11 08:37 . fix: 调整引用,分离HEX编辑框
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043
using DotNet.Utilities;
using ITLDG;
using ITLDG.DataCheck;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
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.Management;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
namespace SerialPortForward
{
public partial class FrmMain : Form
{
private Dictionary<string, string> dicCache = new Dictionary<string, string>();
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中填写一个错误的校验占位", "定时发送时间设置不要过小,否则可能会引起卡顿" };
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;
bool SerialCheck()
{
string com1NameTemp = GetCom(cmbCom1.Text);
string com2NameTemp = GetCom(cmbCom2.Text);
if (string.IsNullOrEmpty(com1NameTemp) || string.IsNullOrEmpty(com2NameTemp))
{
MessageBox.Show("未获取到串口号,不可以打开空的串口", "打开失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
return true;
}
private void Com2_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
DataReceivedHandle(com2Name, false, com2Forward, com2, com1);
}
private void Com1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
DataReceivedHandle(com1Name, true, com1Forward, com1, com2);
}
/// <summary>
/// 串口收到数据
/// </summary>
/// <param name="name">串口名称</param>
/// <param name="isCom1">是否是串口1</param>
/// <param name="openForward">是否勾选了转发</param>
/// <param name="spReceive">收到消息的串口</param>
/// <param name="spSend">准备转发的串口</param>
void DataReceivedHandle(string name, bool isCom1, bool openForward, SerialPortInfo spReceive, SerialPortInfo spSend)
{
if (spReceive.CloseIng) { return; }
try
{
spReceive.Listening = true;
if (spReceive.TimeOut > 0)
{
System.Threading.Thread.Sleep(spReceive.TimeOut);
}
//分包写法
List<byte> result = new List<byte>();
while (true)//循环读
{
if (spReceive.CloseIng || !spReceive.IsOpen)//串口被关了,不读了
{
break;
}
try
{
int length = spReceive.BytesToRead;
if (length == 0)//没数据,退出去
break;
byte[] rev = new byte[length];
spReceive.Read(rev, 0, length);//读数据
if (rev.Length == 0)
break;
result.AddRange(rev);//加到list末尾
if (result.Count > 1024)
{
break;
}
}
catch (Exception)
{
break;
}//崩了?
if (spReceive.TimeOut > 0)
{
System.Threading.Thread.Sleep(spReceive.TimeOut);
}
}
if (result.Count == 0)
{
return;
}
byte[] byteRead = result.ToArray();
AddLog(byteRead, name, isCom1, openForward, spReceive, spSend);
}
finally
{
spReceive.Listening = false;
}
}
Regex regGetComName = new Regex("\\((COM(\\d+))\\)");
public string GetCom(string ComName)
{
Match match = regGetComName.Match(ComName);
if (match.Success)
{
return match.Groups[1].Value;
}
return "";
}
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());
}
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"));
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");
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;
}
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, SerialPort spReceive, SerialPort 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))
{
byte[] array = dicCache[hex].GetBytes_HEX();
spReceive.Write(array, 0, array.Length);
BitAnalysis(array);
AddLog(array, "自动应答-" + 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] = hex;
}
else
{
dicCache.Add(lastSendHex, hex);
}
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);
}
}
private void btnCom1_Click(object sender, EventArgs e)
{
if (btnCom1.Text == "打开")
{
if (SerialCheck())
{
string com1NameTemp = GetCom(cmbCom1.Text);
if (com2.IsOpen && cmbCom1.Text == cmbCom2.Text)
{
MessageBox.Show("不可转发两个相同的串口", "打开失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
try
{
com1.PortName = com1NameTemp;
com1.BaudRate = Convert.ToInt32(cmbBaudRate1.Text);
if (com1.Timer > 0)
{
timerCom1.Interval = com1.Timer;
timerCom1.Enabled = true;
}
else
{
com1.DataReceived += Com1_DataReceived;
}
com1.Open();
SaveSerialOption();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "打开失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
cmbCom1.Enabled = false;
btnCom1.Text = "关闭";
}
}
else
{
timerCom1.Enabled = false;
try
{
com1.Close();
}
catch (Exception)
{
}
cmbCom1.Enabled = true;
btnCom1.Text = "打开";
}
CheckSendEnable();
}
private void btnCom2_Click(object sender, EventArgs e)
{
if (btnCom2.Text == "打开")
{
if (SerialCheck())
{
if (com1.IsOpen && cmbCom1.Text == cmbCom2.Text)
{
MessageBox.Show("不可转发两个相同的串口", "打开失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
string com2NameTemp = GetCom(cmbCom2.Text);
try
{
com2.PortName = com2NameTemp;
com2.BaudRate = Convert.ToInt32(cmbBaudRate2.Text);
if (com2.Timer > 0)
{
timerCom2.Interval = com2.Timer;
timerCom2.Enabled = true;
}
else
{
com2.DataReceived += Com2_DataReceived;
}
com2.Open();
SaveSerialOption();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "打开失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
cmbCom2.Enabled = false;
btnCom2.Text = "关闭";
}
}
else
{
timerCom2.Enabled = false;
try
{
com2.Close();
}
catch (Exception)
{
}
cmbCom2.Enabled = true;
btnCom2.Text = "打开";
}
CheckSendEnable();
}
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);
dicCache = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonStr);
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
{
string jsonStr = JsonConvert.SerializeObject(dicCache);
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;
btnPluginOption.Enabled = listPlugins[pluginIndex].HasOption;
listPlugins[pluginIndex].Checked(pluginCommon);
}
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;
int end = (int)nudCheckEnd.Value;
if (start < 0 || end < 0 || start > bytes.Length || end >= bytes.Length)
{
return bytes;
}
int bytesLength = (bytes.Length - end) - start + 1;
byte[] bytesCheck = new byte[bytesLength];
Array.Copy(bytes, start - 1, 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, string> 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 || !sp.IsOpen)
{
return;
}
if (sp == com2)
{
lastSendHex = bytes.GetString_HEX("");
}
sp.Write(bytes, 0, bytes.Length);
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(() =>
{
while (true)
{
try
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_PnPEntity");
Regex regExp = new Regex("\\(COM\\d+\\)");
foreach (ManagementObject queryObj in searcher.Get().Cast<ManagementObject>())
{
if ((queryObj["Caption"] != null) && regExp.IsMatch(queryObj["Caption"].ToString()))
{
strs.Add(queryObj["Caption"].ToString());
}
}
break;
}
catch
{
Task.Delay(500).Wait();
}
//MessageBox.Show("fail了");
}
try
{
foreach (string p in SerialPort.GetPortNames())//加上缺少的com口
{
bool notMatch = true;
foreach (string n in strs)
{
if (n.Contains($"({p})"))//如果和选中项目匹配
{
notMatch = false;
break;
}
}
if (notMatch)
strs.Add($"Serial Port {p} ({p})");//如果列表中没有,就自己加上
}
}
catch { }
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.Contains($"({com1.PortName})"))
{
cmbCom1.SelectedIndex = i;
}
if (name.Contains($"({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/ccqin/serial-port-forward.git
git@gitee.com:ccqin/serial-port-forward.git
ccqin
serial-port-forward
SerialPortForward
master

搜索帮助