using HalconDotNet;
|
using LB_SmartVision.Forms.Pages;
|
using LB_SmartVision.Forms.Pages.CameraPage;
|
using LB_SmartVision.Forms.Pages.CommunicatorPage;
|
using LB_SmartVision.Forms.Pages.MESPage;
|
using LB_SmartVision.Forms.Pages.MotionControlPage;
|
using LB_SmartVision.Forms.Pages.ProcessPage;
|
using LB_SmartVision.Forms.Pages.SettingPage;
|
using LB_SmartVision.Forms.Pages.UserManagementPage;
|
using LB_SmartVision.ProcessRun;
|
using LB_SmartVision.Tool;
|
using LB_VisionProcesses;
|
using LB_VisionProcesses.Cameras;
|
using LB_VisionProcesses.Communicators;
|
using LB_VisionProcesses.Communicators.TCom;
|
using Newtonsoft.Json;
|
using Newtonsoft.Json.Serialization;
|
using Sunny.UI;
|
using System;
|
using System.Collections.Concurrent;
|
using System.Collections.Generic;
|
using System.ComponentModel;
|
using System.Data;
|
using System.Diagnostics;
|
using System.Drawing;
|
using System.Linq;
|
using System.Reflection;
|
using System.Text;
|
using System.Text.RegularExpressions;
|
using System.Threading.Tasks;
|
using System.Windows.Forms;
|
|
namespace LB_SmartVision
|
{
|
public partial class VisionForm : Form
|
{
|
AllProcessesPage AllProcessesPage = new AllProcessesPage();
|
CamerasEditPage CamerasEditPage = new CamerasEditPage();
|
CommunicatorsEditPage CommunicatorsEditPage = new CommunicatorsEditPage();
|
SettingEditPage SettingEditPage = new SettingEditPage();
|
MESEditPage MESEditPage = new MESEditPage();
|
MotionControlEditPage MotionControlEditPage = new MotionControlEditPage();
|
UserManagementEditPage UserManagementEditPage = new UserManagementEditPage();
|
|
byte[] Assembly_LB_VisionProcessesBytes = File.ReadAllBytes("LB_VisionProcesses.dll");
|
/// <summary>
|
/// 用于反序列化的程序集引用
|
/// </summary>
|
Assembly Assembly_LB_VisionProcessesDll = null;
|
|
|
public VisionForm()
|
{
|
InitializeComponent();
|
HOperatorSet.SetWindowAttr("background_color", "gray");
|
Assembly_LB_VisionProcessesDll = Assembly.Load(Assembly_LB_VisionProcessesBytes);
|
|
GlobalVar.dicCommunicators.DictionaryChanged += CommunicatorsChanged;
|
GlobalVar.dicProcesses.DictionaryChanged += ProcessRunBllChanged;
|
|
//最开始就清空所有Tab页
|
materialTabControl.TabPages.Clear();
|
materialTabControl.Controls.Add(AllProcessesPage);
|
|
CamerasEditPage.LogInfo += LogInfo;
|
materialTabControl.Controls.Add(new MyPage(CamerasEditPage));
|
|
CommunicatorsEditPage.LogInfo += LogInfo;
|
materialTabControl.Controls.Add(new MyPage(CommunicatorsEditPage));
|
|
SettingEditPage.LogInfo += LogInfo;
|
materialTabControl.Controls.Add(new MyPage(SettingEditPage));
|
|
MESEditPage.LogInfo += LogInfo;
|
materialTabControl.Controls.Add(new MyPage(MESEditPage));
|
|
MotionControlEditPage.LogInfo += LogInfo;
|
materialTabControl.Controls.Add(new MyPage(MotionControlEditPage));
|
|
UserManagementEditPage.LogInfo += LogInfo;
|
materialTabControl.Controls.Add(new MyPage(UserManagementEditPage));
|
|
for (int i = 0; i < materialTabControl.TabPages.Count; i++)
|
{
|
//materialTabControl.TabPages[i].Font= new Font("Microsoft YaHei UI", 18F, FontStyle.Regular, GraphicsUnit.Point, 0);
|
}
|
|
materialTabSelector.BaseTabControl = materialTabControl;
|
//materialTabSelector.Font = new Font("Microsoft YaHei UI", 18F, FontStyle.Regular, GraphicsUnit.Point, 0);
|
}
|
|
private void ProcessRunBllChanged(object? sender, DictionaryChangedEventArgs<string, ProcessRunBll> e)
|
{
|
try
|
{
|
string msg = string.Empty;
|
List<MyPage> removeMyPage = new List<MyPage>();
|
switch (e.ChangeType)
|
{
|
case DictionaryChangeType.Added:
|
string AddProcessName = e.NewKey;
|
GlobalVar.dicProcesses[AddProcessName].LogInfo += LogInfo;
|
if (GlobalVar.dicProcesses[AddProcessName].Load(out msg))
|
{
|
LogInfo($"流程[{AddProcessName}]加载成功", LogInfoType.PASS);
|
IProcess.dicGlobalVars.TryAdd($"{AddProcessName}.Result", false);
|
IProcess.dicGlobalVars.TryAdd($"{AddProcessName}.Msg", "");
|
|
ProcessRunBll processRunBll = GlobalVar.dicProcesses[AddProcessName];
|
ProcessPage ProcessPage = new ProcessPage(processRunBll.Name, processRunBll);
|
ProcessPage.LogInfo += LogInfo;
|
if (materialTabControl.InvokeRequired)
|
{
|
materialTabControl.Invoke(new Action(() =>
|
{
|
materialTabControl.Controls.Add(new MyPage(ProcessPage));
|
}));
|
}
|
else
|
materialTabControl.Controls.Add(new MyPage(ProcessPage));
|
}
|
else
|
LogInfo($"流程[{AddProcessName}]加载失败,原因是{msg}", LogInfoType.ERROR);
|
|
LogInfo($"添加流程[{AddProcessName}]", LogInfoType.INFO);
|
break;
|
case DictionaryChangeType.Removed:
|
string RemoveProcessName = e.OldKey;
|
foreach (var control in materialTabControl.Controls)
|
{
|
if (control != null && control is MyPage && ((MyPage)control).UserControl is ProcessPage processPage)
|
{
|
if (processPage.Text == RemoveProcessName)
|
{
|
IProcess.dicGlobalVars.TryRemove($"{RemoveProcessName}.Result", out _);
|
IProcess.dicGlobalVars.TryRemove($"{RemoveProcessName}.Msg", out _);
|
processPage.LogInfo -= LogInfo;
|
removeMyPage.Add((MyPage)control);
|
}
|
}
|
}
|
|
foreach (var myPage in removeMyPage)
|
{
|
if (materialTabControl.InvokeRequired)
|
{
|
materialTabControl.Invoke(new Action(() =>
|
{
|
materialTabControl.Controls.Remove(myPage);
|
}));
|
}
|
else
|
materialTabControl.Controls.Remove(myPage);
|
}
|
|
LogInfo($"移除流程[{RemoveProcessName}]", LogInfoType.INFO);
|
break;
|
case DictionaryChangeType.Renamed:
|
string OldProcessName = e.OldKey;
|
string NewProcessName = e.NewKey;
|
try
|
{
|
IProcess.dicGlobalVars.TryRemove($"{OldProcessName}.Result", out object obj1);
|
IProcess.dicGlobalVars.TryAdd($"{NewProcessName}.Result", obj1);
|
|
IProcess.dicGlobalVars.TryRemove($"{OldProcessName}.Msg", out object obj2);
|
IProcess.dicGlobalVars.TryAdd($"{NewProcessName}.Msg", obj2);
|
}
|
catch { }
|
|
LB_SmartVision.Tool.Tool.RenameDirectory(GlobalVar.allProcessPath + "\\" + OldProcessName
|
, GlobalVar.allProcessPath + "\\" + NewProcessName);
|
e.NewValue.Name = NewProcessName;
|
|
foreach (var control in materialTabControl.Controls)
|
{
|
if (control != null && control is MyPage && ((MyPage)control).UserControl is ProcessPage)
|
{
|
ProcessPage processPage = ((MyPage)control).UserControl as ProcessPage;
|
if (processPage.Text == OldProcessName)
|
{
|
if (materialTabControl.InvokeRequired)
|
{
|
materialTabControl.Invoke(new Action(() =>
|
{
|
materialTabControl.Controls.Remove((MyPage)control);
|
}));
|
}
|
else
|
materialTabControl.Controls.Remove((MyPage)control);
|
|
|
if (GlobalVar.dicProcesses[NewProcessName].Load(out msg))
|
{
|
LogInfo($"流程[{NewProcessName}]重命名后加载成功", LogInfoType.PASS);
|
|
IProcess.dicGlobalVars.TryAdd($"{NewProcessName}.Result", false);
|
IProcess.dicGlobalVars.TryAdd($"{NewProcessName}.Msg", "");
|
|
ProcessRunBll processRunBll = GlobalVar.dicProcesses[NewProcessName];
|
ProcessPage ProcessPage = new ProcessPage(processRunBll.Name, processRunBll);
|
ProcessPage.LogInfo += LogInfo;
|
if (materialTabControl.InvokeRequired)
|
{
|
materialTabControl.Invoke(new Action(() =>
|
{
|
materialTabControl.Controls.Add(new MyPage(ProcessPage));
|
}));
|
}
|
else
|
materialTabControl.Controls.Add(new MyPage(ProcessPage));
|
}
|
else
|
LogInfo($"流程[{NewProcessName}]重命名后加载失败,原因是{msg}", LogInfoType.ERROR);
|
}
|
}
|
}
|
|
LogInfo(string.Format("重命名流程名[{0}]修改为[{1}]", OldProcessName, NewProcessName), LogInfoType.INFO);
|
break;
|
}
|
}
|
catch { }
|
|
}
|
|
private void CommunicatorsChanged(object? sender, DictionaryChangedEventArgs<string, BaseCommunicator> e)
|
{
|
|
}
|
|
private void LogInfo(string arg1, LogInfoType type)
|
{
|
|
}
|
|
public static bool SaveAllLayout()
|
{
|
try
|
{
|
string strJson = string.Empty;
|
var settings = new JsonSerializerSettings
|
{
|
Formatting = Formatting.Indented,
|
// 自定义缩进(4空格)
|
ContractResolver = new DefaultContractResolver
|
{
|
NamingStrategy = new CamelCaseNamingStrategy()
|
}
|
};
|
|
strJson = JsonConvert.SerializeObject(GlobalVar.dicLayout, settings);
|
//判断文件夹是否存在,防呆输入为文件名称
|
string directoryPath = Path.GetDirectoryName(GlobalVar.allLayoutPath);
|
if (!Directory.Exists(directoryPath))
|
{
|
try
|
{
|
Directory.CreateDirectory(directoryPath);
|
}
|
catch { }
|
}
|
|
File.WriteAllText(GlobalVar.allLayoutPath, strJson, Encoding.UTF8);
|
|
return true;
|
}
|
catch { return false; }
|
}
|
|
public static bool LoadAllCsv(string allCsvPath)
|
{
|
try
|
{
|
if (!File.Exists(allCsvPath))
|
{
|
Debug.WriteLine("文件不存在创建空文件");
|
// 获取不带文件名的目录路径
|
string directoryPath = Path.GetDirectoryName(allCsvPath);
|
SaveAllCsv();
|
return true;
|
}
|
string strJson = string.Empty;
|
using (StreamReader streamReader = new StreamReader(allCsvPath, Encoding.UTF8))
|
{
|
strJson = streamReader.ReadToEnd();
|
streamReader.Close();
|
}
|
|
GlobalVar.dicCsvSetting.Clear();
|
GlobalVar.dicCsvSetting = JsonConvert.DeserializeObject<ConcurrentDictionary<string, CsvSetting>>(strJson);
|
if (GlobalVar.dicCsvSetting == null)
|
{
|
GlobalVar.dicCsvSetting = new ConcurrentDictionary<string, CsvSetting>();
|
return false;
|
}
|
return true;
|
}
|
catch { return false; }
|
}
|
|
public static bool SaveAllCsv()
|
{
|
try
|
{
|
string strJson = string.Empty;
|
var settings = new JsonSerializerSettings
|
{
|
Formatting = Formatting.Indented,
|
// 自定义缩进(4空格)
|
ContractResolver = new DefaultContractResolver
|
{
|
NamingStrategy = new CamelCaseNamingStrategy()
|
}
|
};
|
|
strJson = JsonConvert.SerializeObject(GlobalVar.dicCsvSetting, settings);
|
//判断文件夹是否存在,防呆输入为文件名称
|
string directoryPath = Path.GetDirectoryName(GlobalVar.allCsvPath);
|
if (!Directory.Exists(directoryPath))
|
{
|
try
|
{
|
Directory.CreateDirectory(directoryPath);
|
}
|
catch { }
|
}
|
|
File.WriteAllText(GlobalVar.allCsvPath, strJson, Encoding.UTF8);
|
|
return true;
|
}
|
catch { return false; }
|
}
|
|
public bool LoadAllProcessSetting(string allProcessSettingStringPath)
|
{
|
try
|
{
|
if (!File.Exists(allProcessSettingStringPath))
|
{
|
Debug.WriteLine("文件不存在创建空文件");
|
// 获取不带文件名的目录路径
|
string directoryPath = Path.GetDirectoryName(allProcessSettingStringPath);
|
SaveAllProcessSetting();
|
return true;
|
}
|
string strJson = string.Empty;
|
using (StreamReader streamReader = new StreamReader(allProcessSettingStringPath, Encoding.UTF8))
|
{
|
strJson = streamReader.ReadToEnd();
|
streamReader.Close();
|
}
|
|
GlobalVar.dicProcessSetting = JsonConvert.DeserializeObject<ConcurrentDictionary<int, ConcurrentDictionary<string, string>>>(strJson);
|
|
if (GlobalVar.dicProcessSetting == null)
|
GlobalVar.dicProcessSetting = new ConcurrentDictionary<int, ConcurrentDictionary<string, string>>();
|
|
try
|
{
|
string json = File.ReadAllText(GlobalVar.allRunSettingStringPath);
|
var settings = new JsonSerializerSettings
|
{
|
TypeNameHandling = TypeNameHandling.Auto // 处理多态类型
|
};
|
|
GlobalVar.ControlStates = JsonConvert.DeserializeObject<Dictionary<string, object>>(json, settings);
|
}
|
catch { }
|
|
return true;
|
}
|
catch { return false; }
|
}
|
|
public static bool SaveAllProcessSetting()
|
{
|
try
|
{
|
string strJson = string.Empty;
|
var settings = new JsonSerializerSettings
|
{
|
Formatting = Formatting.Indented,
|
// 自定义缩进(4空格)
|
ContractResolver = new DefaultContractResolver
|
{
|
NamingStrategy = new CamelCaseNamingStrategy()
|
}
|
};
|
|
strJson = JsonConvert.SerializeObject(GlobalVar.dicProcessSetting, settings);
|
//判断文件夹是否存在,防呆输入为文件名称
|
string directoryPath = Path.GetDirectoryName(GlobalVar.allProcessSettingStringPath);
|
if (!Directory.Exists(directoryPath))
|
{
|
try
|
{
|
Directory.CreateDirectory(directoryPath);
|
}
|
catch { }
|
}
|
File.WriteAllText(GlobalVar.allProcessSettingStringPath, strJson, Encoding.UTF8);
|
//LogInfo($"流程设置保存成功", LogInfoType.INFO);
|
return true;
|
}
|
catch { return false; }
|
}
|
|
private void VisionForm_Load(object sender, EventArgs e)
|
{
|
if (!LB_SmartVision.Tool.Tool.ReadStringConfig("数据库名称", out string DateBaseName))
|
{
|
DateBaseName = "产品0";
|
LB_SmartVision.Tool.Tool.WriteConfig("数据库名称", DateBaseName);
|
LB_SmartVision.Tool.Tool.WriteConfig("产品列表", DateBaseName);
|
}
|
LB_SmartVision.Tool.Tool.ReadStringConfig("User ID", out string User_ID);
|
LB_SmartVision.Tool.Tool.ReadStringConfig("Password", out string Password);
|
|
GlobalVar.strProductName = DateBaseName;
|
|
//加载通讯
|
foreach (BaseCommunicator com in GlobalVar.dicCommunicators.Values)
|
com.Disconnect();
|
GlobalVar.dicCommunicators.Clear();
|
if (LoadAllCommunicators(GlobalVar.allCommunicatorsConnectionStringPath))
|
LogInfo("通讯加载成功", LogInfoType.PASS);
|
else
|
LogInfo("通讯加载失败", LogInfoType.ERROR);
|
|
//加载相机
|
foreach (BaseCamera camera in GlobalVar.dicCameras.Values)
|
camera.Dispose();
|
GlobalVar.dicCameras.Clear();
|
if (LoadAllCameras(GlobalVar.allCamerasConnectionStringPath))
|
LogInfo("相机加载成功", LogInfoType.PASS);
|
else
|
LogInfo("相机加载失败", LogInfoType.ERROR);
|
|
//必须先加载相机和通讯端口,因为流程加载过程中会用到相机和通讯口
|
|
//加载全局变量
|
IProcess.dicGlobalVars.Clear();
|
if (LoadAllProcessVars(GlobalVar.allProcessVarsPath))
|
LogInfo("全局变量加载成功", LogInfoType.PASS);
|
else
|
LogInfo("全局变量加载失败", LogInfoType.ERROR);
|
|
//加载流程
|
GlobalVar.dicProcesses.Clear();
|
if (LoadAllProcess(GlobalVar.allProcessConnectionStringPath))
|
LogInfo("流程加载成功", LogInfoType.PASS);
|
else
|
LogInfo("流程加载失败", LogInfoType.ERROR);
|
|
//加载触发设置
|
if (LoadAllProcessSetting(GlobalVar.allProcessSettingStringPath))
|
LogInfo("流程设置加载成功", LogInfoType.PASS);
|
else
|
LogInfo("流程设置加载失败", LogInfoType.ERROR);
|
|
//加载流程布局
|
GlobalVar.dicLayout.Clear();
|
if (LoadAllLayout(GlobalVar.allLayoutPath))
|
LogInfo("流程布局加载成功", LogInfoType.PASS);
|
else
|
LogInfo("流程布局加载失败", LogInfoType.ERROR);
|
|
//加载流程表格
|
GlobalVar.dicCsvSetting.Clear();
|
if (LoadAllCsv(GlobalVar.allCsvPath))
|
LogInfo("流程表格加载成功", LogInfoType.PASS);
|
else
|
LogInfo("流程表格加载失败", LogInfoType.ERROR);
|
|
//显示所有产品
|
com_ProductName.Items.Clear();
|
LB_SmartVision.Tool.Tool.ReadStringConfig("产品列表", out string Products);
|
List<string> lstProduct = (Products.Split(',')).ToList();
|
foreach (string DatabaseName in lstProduct)
|
com_ProductName.Items.Add(DatabaseName);
|
com_ProductName.Items.Add("新增");
|
|
com_ProductName.Text = GlobalVar.strProductName;
|
}
|
|
public void SaveAllSetting()
|
{
|
SaveAllProcess();
|
SaveAllProcessVars();
|
SaveAllCommunicators();
|
SaveAllCameras();
|
SaveAllProcessSetting();
|
SaveAllLayout();
|
SaveAllCsv();
|
}
|
|
public bool LoadAllCameras(string allCamerasConnectionStringPath)
|
{
|
if (!File.Exists(allCamerasConnectionStringPath))
|
{
|
Debug.WriteLine("文件不存在创建空文件");
|
// 获取不带文件名的目录路径
|
string directoryPath = Path.GetDirectoryName(allCamerasConnectionStringPath);
|
SaveAllCameras();
|
return true;
|
}
|
string strJson = string.Empty;
|
using (StreamReader streamReader = new StreamReader(allCamerasConnectionStringPath, Encoding.UTF8))
|
{
|
strJson = streamReader.ReadToEnd();
|
streamReader.Close();
|
}
|
|
GlobalVar.allCamerasConnectionString = JsonConvert.DeserializeObject<ConcurrentDictionary<string, string>>(strJson);
|
if (GlobalVar.allCamerasConnectionString == null)
|
{
|
MessageBox.Show("相机加载失败!", "异常");
|
return false;
|
}
|
BaseCamera camera = null;
|
foreach (var CameraConnectionString in GlobalVar.allCamerasConnectionString)
|
{
|
Enum.TryParse<CameraBrand>(CameraConnectionString.Value, out CameraBrand brand);
|
switch (brand)
|
{
|
case CameraBrand.HRCamera:
|
//camera = new HRCamera();
|
break;
|
case CameraBrand.LBCamera:
|
//camera = new LBCamera();
|
break;
|
default:
|
MessageBox.Show($"[{CameraConnectionString.Key}]品牌不支持!", "异常");
|
continue;
|
}
|
|
camera.SN = CameraConnectionString.Key;
|
if (!camera.InitDevice(CameraConnectionString.Key, this.Handle))
|
{
|
LogInfo($"初始化相机[{CameraConnectionString.Key}]失败", LogInfoType.ERROR);
|
if (camera != null)
|
camera.isGrabbing = false;
|
}
|
|
GlobalVar.dicCameras.TryAdd(CameraConnectionString.Key, camera);
|
}
|
|
return true;
|
}
|
|
public bool SaveAllCameras()
|
{
|
try
|
{
|
string strJson = string.Empty;
|
GlobalVar.allCamerasConnectionString = new ConcurrentDictionary<string, string>();
|
|
foreach (var item in GlobalVar.dicCameras)
|
{
|
string CameraSN = item.Value.SN;// "TCP"
|
string CameraBrand = item.Value.Brand.ToString();//"1111"
|
|
if (string.IsNullOrEmpty(CameraSN) || string.IsNullOrEmpty(CameraBrand))
|
break;
|
|
GlobalVar.allCamerasConnectionString.TryAdd(CameraSN, CameraBrand);
|
}
|
var settings = new JsonSerializerSettings
|
{
|
Formatting = Formatting.Indented,
|
// 自定义缩进(4空格)
|
ContractResolver = new DefaultContractResolver
|
{
|
NamingStrategy = new CamelCaseNamingStrategy()
|
}
|
};
|
|
strJson = JsonConvert.SerializeObject(GlobalVar.allCamerasConnectionString, settings);
|
//判断文件夹是否存在,防呆输入为文件名称
|
string directoryPath = Path.GetDirectoryName(GlobalVar.allCamerasConnectionStringPath);
|
if (!Directory.Exists(directoryPath))
|
{
|
try
|
{
|
Directory.CreateDirectory(directoryPath);
|
}
|
catch (Exception)
|
{ }
|
}
|
File.WriteAllText(GlobalVar.allCamerasConnectionStringPath, strJson, Encoding.UTF8);
|
return true;
|
}
|
catch { return false; }
|
}
|
|
|
public bool LoadAllCommunicators(string allCommunicatorsConnectionStringPath)
|
{
|
try
|
{
|
if (!File.Exists(allCommunicatorsConnectionStringPath))
|
{
|
Debug.WriteLine("文件不存在创建空文件");
|
// 获取不带文件名的目录路径
|
string directoryPath = Path.GetDirectoryName(allCommunicatorsConnectionStringPath);
|
SaveAllCommunicators();
|
return true;
|
}
|
string strJson = string.Empty;
|
using (StreamReader streamReader = new StreamReader(allCommunicatorsConnectionStringPath, Encoding.UTF8))
|
{
|
strJson = streamReader.ReadToEnd();
|
streamReader.Close();
|
}
|
|
GlobalVar.allCommunicatorsConnectionString = JsonConvert.DeserializeObject<ConcurrentDictionary<string, string>>(strJson);
|
if (GlobalVar.allCommunicatorsConnectionString == null)
|
{
|
MessageBox.Show("通讯端口加载失败!", "异常");
|
return false;
|
}
|
|
//清空通讯口会把所有通讯口断开连接
|
GlobalVar.dicCommunicators.Clear();
|
ConcurrentDictionary<string, string> clientsCommunicatorsConnectionString = new ConcurrentDictionary<string, string>();
|
foreach (var CommunicatorConnectionString in GlobalVar.allCommunicatorsConnectionString)
|
{
|
string CommunicatorName = CommunicatorConnectionString.Key;
|
string CommunicatorAddress = CommunicatorConnectionString.Value;
|
|
// 定义正则表达式以提取协议、IP 地址和端口
|
//1. \((.*?)\):\(和 \) 是用于匹配括号的转义字符。
|
// (.*?) 是一个非贪婪的匹配,用来匹配类名(MyProcesses.Communicators.TCPServer 或 MyProcesses.Communicators.UARTPort)。
|
//2. ([^:] +):匹配冒号之前的部分,即地址(127.0.0.1 或 COM5)。这里使用了[^:] 来匹配除了冒号之外的任意字符。
|
//3. (\d +) :匹配端口号,确保它匹配一个或多个数字。
|
|
string pattern = @"^\((?<ClassName>[^)]+)\)\[(?<IP>[^]]+)\]\[(?<PORT>[^]]+)\]$";
|
Match match = Regex.Match(CommunicatorAddress, pattern);
|
|
if (match.Success)
|
{
|
string ClassName = match.Groups["ClassName"].Value; // "TCP"
|
string IP = match.Groups["IP"].Value; // "127.0.0.1"
|
string PORT = match.Groups["PORT"].Value; // "1111"
|
|
if (string.IsNullOrEmpty(ClassName) || string.IsNullOrEmpty(IP) || string.IsNullOrEmpty(PORT))
|
break;
|
|
//利用反射创建实例
|
Type type = IProcess.GetExecutingAssembly().GetType(ClassName);
|
if (type == null)
|
{
|
Debug.WriteLine("Class not found.");
|
return false;
|
}
|
var Communicator = Activator.CreateInstance(type, CommunicatorName) as BaseCommunicator;
|
|
if (Communicator == null)
|
{
|
Debug.WriteLine("BaseCommunicator not found.");
|
return false;
|
}
|
|
//TCP客户端最后再连接
|
if (Communicator is TCPClient)
|
{
|
clientsCommunicatorsConnectionString.TryAdd(CommunicatorConnectionString.Key, CommunicatorConnectionString.Value);
|
continue;
|
}
|
|
Communicator.CommunicatorConnections.Add("地址", IP);
|
Communicator.CommunicatorConnections.Add("端口", PORT);
|
Communicator.CommunicatorName = CommunicatorName;
|
if (!Communicator.Connect())
|
LogInfo($"初始化通讯口[{CommunicatorName}]失败,原因是{Communicator.Msg}", LogInfoType.ERROR);
|
else
|
LogInfo($"初始化通讯口[{CommunicatorName}]成功", LogInfoType.PASS);
|
GlobalVar.dicCommunicators.TryAdd(CommunicatorName, Communicator);
|
}
|
else
|
{
|
Debug.WriteLine("No match found.");
|
}
|
|
}
|
|
//TCP客户端最后连接
|
foreach (var CommunicatorConnectionString in clientsCommunicatorsConnectionString)
|
{
|
string CommunicatorName = CommunicatorConnectionString.Key;
|
string CommunicatorAddress = CommunicatorConnectionString.Value;
|
|
// 定义正则表达式以提取协议、IP 地址和端口
|
//1. \((.*?)\):\(和 \) 是用于匹配括号的转义字符。
|
// (.*?) 是一个非贪婪的匹配,用来匹配类名(MyProcesses.Communicators.TCPServer 或 MyProcesses.Communicators.UARTPort)。
|
//2. ([^:] +):匹配冒号之前的部分,即地址(127.0.0.1 或 COM5)。这里使用了[^:] 来匹配除了冒号之外的任意字符。
|
//3. (\d +) :匹配端口号,确保它匹配一个或多个数字。
|
|
var regex = new Regex(@"^\((?<ClassName>[^)]+)\)\[(?<IP>[^]]+)\]\[(?<PORT>[^]]+)\]$");
|
var match = regex.Match(CommunicatorAddress);
|
|
if (match.Success)
|
{
|
string ClassName = match.Groups[1].Value; // "TCP"
|
string IP = match.Groups[2].Value; // "127.0.0.1"
|
string PORT = match.Groups[3].Value; // "1111"
|
|
if (string.IsNullOrEmpty(ClassName) || string.IsNullOrEmpty(IP) || string.IsNullOrEmpty(PORT))
|
break;
|
|
//利用反射创建实例
|
Type type = IProcess.GetExecutingAssembly().GetType(ClassName);
|
if (type == null)
|
{
|
Debug.WriteLine("Class not found.");
|
return false;
|
}
|
var Communicator = Activator.CreateInstance(type, CommunicatorName) as BaseCommunicator;
|
|
if (Communicator == null)
|
{
|
Debug.WriteLine("BaseCommunicator not found.");
|
return false;
|
}
|
|
Communicator.CommunicatorConnections.Add("地址", IP);
|
Communicator.CommunicatorConnections.Add("端口", PORT);
|
Communicator.CommunicatorName = CommunicatorName;
|
if (!Communicator.Connect())
|
LogInfo($"初始化通讯口[{CommunicatorName}]失败,原因是{Communicator.Msg}", LogInfoType.ERROR);
|
else
|
LogInfo($"初始化通讯口[{CommunicatorName}]成功", LogInfoType.PASS);
|
|
GlobalVar.dicCommunicators.TryAdd(CommunicatorName, Communicator);
|
}
|
else
|
{
|
Debug.WriteLine("No match found.");
|
}
|
|
}
|
|
return true;
|
}
|
catch { return false; }
|
}
|
|
public bool SaveAllCommunicators()
|
{
|
try
|
{
|
string strJson = string.Empty;
|
GlobalVar.allCommunicatorsConnectionString = new ConcurrentDictionary<string, string>();
|
|
foreach (var item in GlobalVar.dicCommunicators)
|
{
|
string ClassName = item.Value.GetType().FullName;// "TCP"
|
string IP = item.Value.CommunicatorConnections["地址"].ToString();//"127.0.0.1"
|
string PORT = item.Value.CommunicatorConnections["端口"].ToString();//"1111"
|
|
if (string.IsNullOrEmpty(ClassName) || string.IsNullOrEmpty(IP) || string.IsNullOrEmpty(PORT))
|
break;
|
|
string CommunicatorConnectionString = $"({ClassName})[{IP}][{PORT}]";
|
GlobalVar.allCommunicatorsConnectionString.TryAdd(item.Key, CommunicatorConnectionString);
|
}
|
|
var settings = new JsonSerializerSettings
|
{
|
Formatting = Formatting.Indented,
|
// 自定义缩进(4空格)
|
ContractResolver = new DefaultContractResolver
|
{
|
NamingStrategy = new CamelCaseNamingStrategy()
|
}
|
};
|
|
strJson = JsonConvert.SerializeObject(GlobalVar.allCommunicatorsConnectionString, settings);
|
//判断文件夹是否存在,防呆输入为文件名称
|
string directoryPath = Path.GetDirectoryName(GlobalVar.allCommunicatorsConnectionStringPath);
|
if (!Directory.Exists(directoryPath))
|
{
|
try
|
{
|
Directory.CreateDirectory(directoryPath);
|
}
|
catch (Exception)
|
{ }
|
}
|
File.WriteAllText(GlobalVar.allCommunicatorsConnectionStringPath, strJson, Encoding.UTF8);
|
return true;
|
}
|
catch { return false; }
|
}
|
|
public bool LoadAllProcess(string allProcessConnectionStringPath)
|
{
|
try
|
{
|
if (!File.Exists(allProcessConnectionStringPath))
|
{
|
Debug.WriteLine("文件不存在创建空文件");
|
// 获取不带文件名的目录路径
|
string directoryPath = Path.GetDirectoryName(allProcessConnectionStringPath);
|
SaveAllProcess();
|
return true;
|
}
|
string strJson = string.Empty;
|
using (StreamReader streamReader = new StreamReader(allProcessConnectionStringPath, Encoding.UTF8))
|
{
|
strJson = streamReader.ReadToEnd();
|
streamReader.Close();
|
}
|
|
List<string> lstProcessName = JsonConvert.DeserializeObject<List<string>>(strJson);
|
|
if (lstProcessName == null)
|
return false;
|
|
// 使用方式
|
var sortedKeys = lstProcessName
|
.OrderBy(k => k, new NaturalStringComparer())
|
.ToList();
|
GlobalVar.dicProcesses.Clear();
|
foreach (var ProcessName in sortedKeys)
|
GlobalVar.dicProcesses.TryAdd(ProcessName
|
, new ProcessRunBll(ProcessName, GlobalVar.dicCameras, GlobalVar.dicCommunicators));
|
|
return true;
|
}
|
catch { return false; }
|
}
|
|
public bool SaveAllProcess()
|
{
|
try
|
{
|
string strJson = string.Empty;
|
var settings = new JsonSerializerSettings
|
{
|
Formatting = Formatting.Indented,
|
// 自定义缩进(4空格)
|
ContractResolver = new DefaultContractResolver
|
{
|
NamingStrategy = new CamelCaseNamingStrategy()
|
}
|
};
|
|
strJson = JsonConvert.SerializeObject(GlobalVar.dicProcesses.Keys.ToList(), settings);
|
//判断文件夹是否存在,防呆输入为文件名称
|
string directoryPath = Path.GetDirectoryName(GlobalVar.allProcessConnectionStringPath);
|
if (!Directory.Exists(directoryPath))
|
{
|
try
|
{
|
Directory.CreateDirectory(directoryPath);
|
}
|
catch { }
|
}
|
File.WriteAllText(GlobalVar.allProcessConnectionStringPath, strJson, Encoding.UTF8);
|
|
foreach (var process in GlobalVar.dicProcesses.Values)
|
{
|
if (!process.Save(out string msg))
|
LogInfo($"流程[{process.Name}]保存失败,原因:{msg}", LogInfoType.NOSHOW);
|
}
|
|
try
|
{
|
string json = JsonConvert.SerializeObject(GlobalVar.ControlStates, settings);
|
File.WriteAllText(GlobalVar.allRunSettingStringPath, json);
|
LogInfo($"流程运行设置保存成功", LogInfoType.INFO);
|
}
|
catch { }
|
|
|
return true;
|
}
|
catch { return false; }
|
}
|
|
public bool LoadAllProcessVars(string allProcessVarsPath)
|
{
|
try
|
{
|
if (!File.Exists(allProcessVarsPath))
|
{
|
Debug.WriteLine("文件不存在创建空文件");
|
// 获取不带文件名的目录路径
|
string directoryPath = Path.GetDirectoryName(allProcessVarsPath);
|
SaveAllProcessVars();
|
return true;
|
}
|
string strJson = string.Empty;
|
using (StreamReader streamReader = new StreamReader(allProcessVarsPath, Encoding.UTF8))
|
{
|
strJson = streamReader.ReadToEnd();
|
streamReader.Close();
|
}
|
|
IProcess.dicGlobalVars.Clear();
|
IProcess.dicGlobalVars = JsonConvert.DeserializeObject<ConcurrentDictionary<string, object>>(strJson);
|
if (IProcess.dicGlobalVars == null)
|
{
|
IProcess.dicGlobalVars = new ConcurrentDictionary<string, object>();
|
return false;
|
}
|
|
return true;
|
}
|
catch { return false; }
|
}
|
|
public bool SaveAllProcessVars()
|
{
|
try
|
{
|
string strJson = string.Empty;
|
var settings = new JsonSerializerSettings
|
{
|
Formatting = Formatting.Indented,
|
// 自定义缩进(4空格)
|
ContractResolver = new DefaultContractResolver
|
{
|
NamingStrategy = new CamelCaseNamingStrategy()
|
}
|
};
|
|
strJson = JsonConvert.SerializeObject(IProcess.dicGlobalVars, settings);
|
//判断文件夹是否存在,防呆输入为文件名称
|
string directoryPath = Path.GetDirectoryName(GlobalVar.allProcessVarsPath);
|
if (!Directory.Exists(directoryPath))
|
{
|
try
|
{
|
Directory.CreateDirectory(directoryPath);
|
}
|
catch { }
|
}
|
|
File.WriteAllText(GlobalVar.allProcessVarsPath, strJson, Encoding.UTF8);
|
LogInfo($"全局变量保存成功", LogInfoType.INFO);
|
|
strJson = JsonConvert.SerializeObject(GlobalVar.dicLayout, settings);
|
//判断文件夹是否存在,防呆输入为文件名称
|
directoryPath = Path.GetDirectoryName(GlobalVar.allLayoutPath);
|
if (!Directory.Exists(directoryPath))
|
{
|
try
|
{
|
Directory.CreateDirectory(directoryPath);
|
}
|
catch { }
|
}
|
|
File.WriteAllText(GlobalVar.allLayoutPath, strJson, Encoding.UTF8);
|
LogInfo($"全局布局保存成功", LogInfoType.INFO);
|
|
return true;
|
}
|
catch { return false; }
|
}
|
|
public bool LoadAllLayout(string allLayoutPath)
|
{
|
try
|
{
|
if (!File.Exists(allLayoutPath))
|
{
|
Debug.WriteLine("文件不存在创建空文件");
|
// 获取不带文件名的目录路径
|
string directoryPath = Path.GetDirectoryName(allLayoutPath);
|
SaveAllLayout();
|
return true;
|
}
|
string strJson = string.Empty;
|
using (StreamReader streamReader = new StreamReader(allLayoutPath, Encoding.UTF8))
|
{
|
strJson = streamReader.ReadToEnd();
|
streamReader.Close();
|
}
|
|
GlobalVar.dicLayout.Clear();
|
GlobalVar.dicLayout = JsonConvert.DeserializeObject<ConcurrentDictionary<int, Forms.Pages.SettingPage.Layout>>(strJson);
|
if (GlobalVar.dicLayout == null)
|
{
|
GlobalVar.dicLayout = new ConcurrentDictionary<int, Forms.Pages.SettingPage.Layout>();
|
return false;
|
}
|
return true;
|
}
|
catch { return false; }
|
}
|
}
|
}
|