From c414944cd6607a745f52d24efc730d1f63f815aa Mon Sep 17 00:00:00 2001 From: applelon <380149513@qq.com> Date: Mon, 18 Apr 2022 14:07:44 +0800 Subject: [PATCH] init --- .../BPASmartClient.DRCoffee.csproj | 7 + BPASmartClient.DRCoffee/Class1.cs | 8 + .../BPASmartClient.Device.csproj | 7 + BPASmartClient.Device/IDevice.cs | 13 + BPASmartClient.Device/IDeviceStatus.cs | 12 + .../BPASmartClient.DeviceProxy.csproj | 7 + BPASmartClient.DeviceProxy/Class1.cs | 8 + .../BPASmartClient.GSIceCream.csproj | 7 + BPASmartClient.GSIceCream/Class1.cs | 8 + BPASmartClient.Helper/APIHelper.cs | 94 +++++++ BPASmartClient.Helper/ActionManage.cs | 128 +++++++++ .../BPASmartClient.Helper.csproj | 28 ++ BPASmartClient.Helper/DataStorage.cs | 43 ++++ BPASmartClient.Helper/Delay.cs | 75 ++++++ BPASmartClient.Helper/DelayRTrig.cs | 73 ++++++ BPASmartClient.Helper/DelayTTrig.cs | 67 +++++ BPASmartClient.Helper/ExpandMethod.cs | 100 +++++++ BPASmartClient.Helper/Json.cs | 95 +++++++ BPASmartClient.Helper/LocaPath.cs | 26 ++ BPASmartClient.Helper/RTrig.cs | 40 +++ BPASmartClient.Helper/Singleton.cs | 31 +++ BPASmartClient.Helper/SystemHelper.cs | 237 +++++++++++++++++ BPASmartClient.Helper/TTrig.cs | 39 +++ BPASmartClient.Helper/TextHelper.cs | 64 +++++ BPASmartClient.Helper/ThreadManage.cs | 164 ++++++++++++ BPASmartClient.Helper/UniversalHelper.cs | 49 ++++ .../BPASmartClient.Http.csproj | 7 + BPASmartClient.Http/Class1.cs | 8 + BPASmartClient.IoT/BPASmartClient.IoT.csproj | 7 + BPASmartClient.IoT/Class1.cs | 8 + .../BPASmartClient.KLMCoffee.csproj | 7 + BPASmartClient.KLMCoffee/Class1.cs | 8 + .../BPASmartClient.Lebai.csproj | 7 + BPASmartClient.Lebai/Class1.cs | 8 + .../BPASmartClient.MQTT.csproj | 16 ++ BPASmartClient.MQTT/MqttHelper.cs | 183 +++++++++++++ .../BPASmartClient.Message.csproj | 7 + BPASmartClient.Message/MessageLog.cs | 67 +++++ .../BPASmartClient.Modbus.csproj | 7 + BPASmartClient.Modbus/Class1.cs | 8 + .../BPASmartClient.MorkD.csproj | 7 + BPASmartClient.MorkD/Class1.cs | 8 + .../BPASmartClient.MorkS.csproj | 7 + BPASmartClient.MorkS/Class1.cs | 8 + .../BPASmartClient.MorkT.csproj | 7 + .../BPASmartClient.SCChip.csproj | 7 + BPASmartClient.SCChip/Class1.cs | 8 + .../BPASmartClient.SerialPort.csproj | 15 ++ BPASmartClient.SerialPort/SerialParameter.cs | 50 ++++ BPASmartClient.SerialPort/SerialPortClient.cs | 243 ++++++++++++++++++ .../BPASmartClient.Socket.csproj | 7 + BPASmartClient.Socket/Class1.cs | 8 + .../BPASmartClient.Status.csproj | 7 + BPASmartClient.Status/Class1.cs | 8 + .../BPASmartClient.ViewModel.csproj | 9 + BPASmartClient.ViewModel/Class1.cs | 8 + BPASmartClient/App.xaml | 9 + BPASmartClient/App.xaml.cs | 17 ++ BPASmartClient/AssemblyInfo.cs | 10 + BPASmartClient/BPASmartClient.csproj | 10 + BPASmartClient/MainWindow.xaml | 12 + BPASmartClient/MainWindow.xaml.cs | 28 ++ SmartClient.sln | 180 +++++++++++++ 63 files changed, 2451 insertions(+) create mode 100644 BPASmartClient.DRCoffee/BPASmartClient.DRCoffee.csproj create mode 100644 BPASmartClient.DRCoffee/Class1.cs create mode 100644 BPASmartClient.Device/BPASmartClient.Device.csproj create mode 100644 BPASmartClient.Device/IDevice.cs create mode 100644 BPASmartClient.Device/IDeviceStatus.cs create mode 100644 BPASmartClient.DeviceProxy/BPASmartClient.DeviceProxy.csproj create mode 100644 BPASmartClient.DeviceProxy/Class1.cs create mode 100644 BPASmartClient.GSIceCream/BPASmartClient.GSIceCream.csproj create mode 100644 BPASmartClient.GSIceCream/Class1.cs create mode 100644 BPASmartClient.Helper/APIHelper.cs create mode 100644 BPASmartClient.Helper/ActionManage.cs create mode 100644 BPASmartClient.Helper/BPASmartClient.Helper.csproj create mode 100644 BPASmartClient.Helper/DataStorage.cs create mode 100644 BPASmartClient.Helper/Delay.cs create mode 100644 BPASmartClient.Helper/DelayRTrig.cs create mode 100644 BPASmartClient.Helper/DelayTTrig.cs create mode 100644 BPASmartClient.Helper/ExpandMethod.cs create mode 100644 BPASmartClient.Helper/Json.cs create mode 100644 BPASmartClient.Helper/LocaPath.cs create mode 100644 BPASmartClient.Helper/RTrig.cs create mode 100644 BPASmartClient.Helper/Singleton.cs create mode 100644 BPASmartClient.Helper/SystemHelper.cs create mode 100644 BPASmartClient.Helper/TTrig.cs create mode 100644 BPASmartClient.Helper/TextHelper.cs create mode 100644 BPASmartClient.Helper/ThreadManage.cs create mode 100644 BPASmartClient.Helper/UniversalHelper.cs create mode 100644 BPASmartClient.Http/BPASmartClient.Http.csproj create mode 100644 BPASmartClient.Http/Class1.cs create mode 100644 BPASmartClient.IoT/BPASmartClient.IoT.csproj create mode 100644 BPASmartClient.IoT/Class1.cs create mode 100644 BPASmartClient.KLMCoffee/BPASmartClient.KLMCoffee.csproj create mode 100644 BPASmartClient.KLMCoffee/Class1.cs create mode 100644 BPASmartClient.Lebai/BPASmartClient.Lebai.csproj create mode 100644 BPASmartClient.Lebai/Class1.cs create mode 100644 BPASmartClient.MQTT/BPASmartClient.MQTT.csproj create mode 100644 BPASmartClient.MQTT/MqttHelper.cs create mode 100644 BPASmartClient.Message/BPASmartClient.Message.csproj create mode 100644 BPASmartClient.Message/MessageLog.cs create mode 100644 BPASmartClient.Modbus/BPASmartClient.Modbus.csproj create mode 100644 BPASmartClient.Modbus/Class1.cs create mode 100644 BPASmartClient.MorkD/BPASmartClient.MorkD.csproj create mode 100644 BPASmartClient.MorkD/Class1.cs create mode 100644 BPASmartClient.MorkS/BPASmartClient.MorkS.csproj create mode 100644 BPASmartClient.MorkS/Class1.cs create mode 100644 BPASmartClient.MorkT/BPASmartClient.MorkT.csproj create mode 100644 BPASmartClient.SCChip/BPASmartClient.SCChip.csproj create mode 100644 BPASmartClient.SCChip/Class1.cs create mode 100644 BPASmartClient.SerialPort/BPASmartClient.SerialPort.csproj create mode 100644 BPASmartClient.SerialPort/SerialParameter.cs create mode 100644 BPASmartClient.SerialPort/SerialPortClient.cs create mode 100644 BPASmartClient.Socket/BPASmartClient.Socket.csproj create mode 100644 BPASmartClient.Socket/Class1.cs create mode 100644 BPASmartClient.Status/BPASmartClient.Status.csproj create mode 100644 BPASmartClient.Status/Class1.cs create mode 100644 BPASmartClient.ViewModel/BPASmartClient.ViewModel.csproj create mode 100644 BPASmartClient.ViewModel/Class1.cs create mode 100644 BPASmartClient/App.xaml create mode 100644 BPASmartClient/App.xaml.cs create mode 100644 BPASmartClient/AssemblyInfo.cs create mode 100644 BPASmartClient/BPASmartClient.csproj create mode 100644 BPASmartClient/MainWindow.xaml create mode 100644 BPASmartClient/MainWindow.xaml.cs create mode 100644 SmartClient.sln diff --git a/BPASmartClient.DRCoffee/BPASmartClient.DRCoffee.csproj b/BPASmartClient.DRCoffee/BPASmartClient.DRCoffee.csproj new file mode 100644 index 00000000..dbc15171 --- /dev/null +++ b/BPASmartClient.DRCoffee/BPASmartClient.DRCoffee.csproj @@ -0,0 +1,7 @@ + + + + net6.0 + + + diff --git a/BPASmartClient.DRCoffee/Class1.cs b/BPASmartClient.DRCoffee/Class1.cs new file mode 100644 index 00000000..66097ed2 --- /dev/null +++ b/BPASmartClient.DRCoffee/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace BPASmartClient.DRCoffee +{ + public class Class1 + { + } +} diff --git a/BPASmartClient.Device/BPASmartClient.Device.csproj b/BPASmartClient.Device/BPASmartClient.Device.csproj new file mode 100644 index 00000000..dbc15171 --- /dev/null +++ b/BPASmartClient.Device/BPASmartClient.Device.csproj @@ -0,0 +1,7 @@ + + + + net6.0 + + + diff --git a/BPASmartClient.Device/IDevice.cs b/BPASmartClient.Device/IDevice.cs new file mode 100644 index 00000000..620bdfe4 --- /dev/null +++ b/BPASmartClient.Device/IDevice.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.Device +{ + public interface IDevice + { + + } +} diff --git a/BPASmartClient.Device/IDeviceStatus.cs b/BPASmartClient.Device/IDeviceStatus.cs new file mode 100644 index 00000000..6ab5e918 --- /dev/null +++ b/BPASmartClient.Device/IDeviceStatus.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.Device +{ + internal class IDeviceStatus + { + } +} diff --git a/BPASmartClient.DeviceProxy/BPASmartClient.DeviceProxy.csproj b/BPASmartClient.DeviceProxy/BPASmartClient.DeviceProxy.csproj new file mode 100644 index 00000000..dbc15171 --- /dev/null +++ b/BPASmartClient.DeviceProxy/BPASmartClient.DeviceProxy.csproj @@ -0,0 +1,7 @@ + + + + net6.0 + + + diff --git a/BPASmartClient.DeviceProxy/Class1.cs b/BPASmartClient.DeviceProxy/Class1.cs new file mode 100644 index 00000000..9fae3eee --- /dev/null +++ b/BPASmartClient.DeviceProxy/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace BPASmartClient.DeviceProxy +{ + public class Class1 + { + } +} diff --git a/BPASmartClient.GSIceCream/BPASmartClient.GSIceCream.csproj b/BPASmartClient.GSIceCream/BPASmartClient.GSIceCream.csproj new file mode 100644 index 00000000..dbc15171 --- /dev/null +++ b/BPASmartClient.GSIceCream/BPASmartClient.GSIceCream.csproj @@ -0,0 +1,7 @@ + + + + net6.0 + + + diff --git a/BPASmartClient.GSIceCream/Class1.cs b/BPASmartClient.GSIceCream/Class1.cs new file mode 100644 index 00000000..3bf73622 --- /dev/null +++ b/BPASmartClient.GSIceCream/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace BPASmartClient.GSIceCream +{ + public class Class1 + { + } +} diff --git a/BPASmartClient.Helper/APIHelper.cs b/BPASmartClient.Helper/APIHelper.cs new file mode 100644 index 00000000..af029136 --- /dev/null +++ b/BPASmartClient.Helper/APIHelper.cs @@ -0,0 +1,94 @@ +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using System.Web; +using Newtonsoft.Json; +using HBLConsole.Service; + +namespace BPASmartClient.Helper +{ + public class APIHelper + { + + private volatile static APIHelper _Instance; + public static APIHelper GetInstance => _Instance ?? (_Instance = new APIHelper()); + private APIHelper() { } + + public string PostData(string url, string data, string head) + { + byte[] b = Encoding.UTF8.GetBytes(data);//把字符串转换为二进制 + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); + request.Proxy = null; + request.ContentType = "application/json"; + request.Method = "POST"; //设置请求方法 + request.ContentLength = b.Length; //设置长度 + request.Headers["Authorize"] = head; + Stream postStream = request.GetRequestStream(); //requst流 + postStream.Write(b, 0, b.Length); //写入POST数据,二进制类型的 + postStream.Close(); //关闭 + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); //获取response + Stream stream = response.GetResponseStream(); // 得到response响应流 + StreamReader sr = new StreamReader(stream); + string str = sr.ReadToEnd(); //读取流 + + sr.Close(); + stream.Close(); + return str; + } + + public string GetData(string url, string head) + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); + request.Method = "GET"; + request.Accept = "text/html, application/xhtml+xml, */*"; + request.ContentType = "application/json"; + request.Headers["Authorize"] = head; + byte[] buffer = Encoding.UTF8.GetBytes(head); + request.ContentLength = buffer.Length; + request.GetRequestStream().Write(buffer, 0, buffer.Length); + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + using (StreamReader myStreamReader = new StreamReader(response.GetResponseStream(), Encoding.UTF8)) + { + return myStreamReader.ReadToEnd(); + } + } + + public string HttpRequest(string url, string head, object data, RequestType requestType) + { + if (requestType == RequestType.POST) + { + return PostData(url, JsonConvert.SerializeObject(data), head); + } + else + { + StringBuilder sb = new StringBuilder(); + sb.Append("?"); + foreach (System.Reflection.PropertyInfo p in data.GetType().GetProperties()) + { + if (sb.ToString().Last() != '?') + { + sb.Append("&"); + } + sb.Append(p.Name); + sb.Append("="); + sb.Append(p.GetValue(data)); + } + return GetData(url + sb.ToString(), head); + } + } + + } + + public enum RequestType + { + POST, + PUT, + DELETE, + GET + } +} diff --git a/BPASmartClient.Helper/ActionManage.cs b/BPASmartClient.Helper/ActionManage.cs new file mode 100644 index 00000000..d257033d --- /dev/null +++ b/BPASmartClient.Helper/ActionManage.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Collections.Concurrent; + +namespace BPASmartClient.Helper +{ + public class ActionManage + { + + private volatile static ActionManage _Instance; + public static ActionManage GetInstance => _Instance ?? (_Instance = new ActionManage()); + private ActionManage() { } + + private static ConcurrentDictionary actions = new ConcurrentDictionary(); + + static readonly object SendLock = new object(); + static readonly object SendParLock = new object(); + static readonly object RegisterLock = new object(); + + /// + /// 注销委托 + /// + /// + public void CancelRegister(string key) + { + if (actions.ContainsKey(key)) + actions.TryRemove(key, out Delegation t); + } + + /// + /// 执行注册过的委托 + /// + /// 注册委托的key + /// 委托参数 + /// 委托回调 + public void Send(string key, object par, Action Callback = null) + { + lock (SendLock) + if (actions.ContainsKey(key)) actions[key].ActionPar.Invoke(par, Callback); + //if (actions[key].ActionPar != null) + //{ + // actions[key].ActionPar(par); + // if (Callback != null) Callback(); + //} + } + + /// + /// 执行注册过的委托 + /// + /// 注册委托的key + /// 委托回调 + public void Send(string key, Action Callback = null) + { + lock (SendLock) + if (actions.ContainsKey(key)) actions[key].ActionBus?.Invoke(Callback); + } + + public object SendResult(string key, object par = null) + { + lock (SendLock) + if (actions.ContainsKey(key)) + if (par == null) + { + if (actions[key].FuncObj != null) + return actions[key].FuncObj; + } + else + { + if (actions[key].FuncPar != null) + return actions[key].FuncPar(par); + } + return default; + } + + public void Register(T action, string key) + { + lock (RegisterLock) + { + if (action != null) + { + if (!actions.ContainsKey(key)) + { + if (action is Action actionBus) + actions.TryAdd(key, new Delegation() { ActionBus = actionBus }); + + if (action is Action actionObj) + actions.TryAdd(key, new Delegation() { ActionPar = actionObj }); + + if (action is Func funcObj) + actions.TryAdd(key, new Delegation() { FuncObj = funcObj }); + + if (action is Func puncPar) + actions.TryAdd(key, new Delegation() { FuncPar = puncPar }); + } + } + } + + } + + } + + + internal class Delegation + { + /// + /// 带参数的委托 + /// + public Action ActionPar { get; set; } + /// + /// 无参数的委托 + /// + public Action ActionBus { get; set; } + public Action CallBack { get; set; } + /// + /// 有返回值的委托 + /// + public Func FuncObj { get; set; } + /// + /// 有返回值,有参数的委托 + /// + public Func FuncPar { get; set; } + } + + +} diff --git a/BPASmartClient.Helper/BPASmartClient.Helper.csproj b/BPASmartClient.Helper/BPASmartClient.Helper.csproj new file mode 100644 index 00000000..576693a5 --- /dev/null +++ b/BPASmartClient.Helper/BPASmartClient.Helper.csproj @@ -0,0 +1,28 @@ + + + + net6.0 + + + + + tlbimp + 0 + 1 + f935dc20-1cf0-11d0-adb9-00c04fd58a0b + 0 + false + true + + + + + + + + + + + + + diff --git a/BPASmartClient.Helper/DataStorage.cs b/BPASmartClient.Helper/DataStorage.cs new file mode 100644 index 00000000..0bb0d50e --- /dev/null +++ b/BPASmartClient.Helper/DataStorage.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.Helper +{ + /// + /// 数据仓库 + /// + public class DataStorage + { + private ConcurrentQueue cache = new ConcurrentQueue(); + + public void PutData(T data) + { + cache.Enqueue(data); + } + + public void PutData(T[] data) + { + foreach (var item in data) + cache.Enqueue(item); + } + + public T GetData() + { + if (cache.Count >= 0) + { + cache.TryDequeue(out T data); + return data; + } + return default(T); + } + + public int GetSize() + { + return cache.Count; + } + } +} diff --git a/BPASmartClient.Helper/Delay.cs b/BPASmartClient.Helper/Delay.cs new file mode 100644 index 00000000..97d7745a --- /dev/null +++ b/BPASmartClient.Helper/Delay.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Collections.Concurrent; + +namespace BPASmartClient.Helper +{ + /// + /// 延时操作 + /// + public class Delay + { + /// + /// 计时条件 + /// + //public bool IN { get; set; } + + + private volatile static ConcurrentDictionary _Instance; + public static Delay GetInstance(string name) + { + if (_Instance == null) _Instance = new ConcurrentDictionary(); + if (!_Instance.ContainsKey(name)) _Instance.TryAdd(name, new Delay()); + return _Instance[name]; + } + private Delay() { } + + /// + /// 移除指定的定时器 + /// + /// + public static void RemoveDelay(string name) + { + if (_Instance.ContainsKey(name)) + _Instance.TryRemove(name, out Delay delay); + } + + /// + /// 当前时间 + /// + public long ET { get; private set; } = 0; + public bool Q { get; private set; } + + private bool flag; + DateTime startTime = new DateTime(); + + /// + /// 开始计时(时间单位/秒) + /// + /// 计时时间(单位 秒) + /// + public bool Start(bool IN, int PT) + { + if (IN) + { + if (!flag) + { + startTime = DateTime.Now; + flag = true; + } + if (ET < PT) ET = Convert.ToInt64(DateTime.Now.Subtract(startTime).TotalSeconds); + } + else + { + ET = 0; + flag = false; + } + Q = ET >= PT; + return Q; + } + + } +} diff --git a/BPASmartClient.Helper/DelayRTrig.cs b/BPASmartClient.Helper/DelayRTrig.cs new file mode 100644 index 00000000..50113998 --- /dev/null +++ b/BPASmartClient.Helper/DelayRTrig.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections.Concurrent; + +namespace BPASmartClient.Helper +{ + /// + /// 延时上升沿触发 + /// + public class DelayRTrig + { + + private volatile static ConcurrentDictionary _Instance; + public static DelayRTrig GetInstance(string name) + { + if (_Instance == null) _Instance = new ConcurrentDictionary(); + if (!_Instance.ContainsKey(name)) _Instance.TryAdd(name, new DelayRTrig()); + return _Instance[name]; + } + + private DelayRTrig() { } + + /// + /// 计时条件 + /// + //public bool IN { get; set; } + + /// + /// 当前时间 + /// + public long ET { get; private set; } = 0; + + private bool flag1; + public bool Q { get; private set; } + private bool IN1 + { + set + { + Q = value && !flag1; + flag1 = value; + } + } + + private bool flag; + DateTime startTime = new DateTime(); + + /// + /// 开始计时(时间单位/秒) + /// + /// 计时时间(单位 秒) + /// + public bool Start(bool IN, int PT) + { + if (IN) + { + if (!flag) + { + startTime = DateTime.Now; + flag = true; + } + if (ET < PT) ET = Convert.ToInt64(DateTime.Now.Subtract(startTime).TotalSeconds); + } + else + { + ET = 0; + flag = false; + } + IN1 = ET >= PT; + return Q; + } + } +} diff --git a/BPASmartClient.Helper/DelayTTrig.cs b/BPASmartClient.Helper/DelayTTrig.cs new file mode 100644 index 00000000..5c73f631 --- /dev/null +++ b/BPASmartClient.Helper/DelayTTrig.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections.Concurrent; + +namespace BPASmartClient.Helper +{ + /// + /// 延时下降沿触发 + /// + public class DelayTTrig + { + + private volatile static ConcurrentDictionary _Instance; + public static DelayTTrig GetInstance(string name) + { + if (_Instance == null) _Instance = new ConcurrentDictionary(); + if (!_Instance.ContainsKey(name)) _Instance.TryAdd(name, new DelayTTrig()); + return _Instance[name]; + } + private DelayTTrig() { } + + /// + /// 当前时间 + /// + public long ET { get; private set; } = 0; + + private bool flag1; + private bool Q { get; set; } + private bool IN1 + { + set + { + Q = !value && flag1; + flag1 = value; + } + } + + private bool flag; + DateTime startTime = new DateTime(); + + /// + /// 开始计时(时间单位/秒) + /// + /// 计时时间(单位 秒) + /// + public bool Start(bool IN, int PT) + { + if (IN) + { + if (!flag) + { + startTime = DateTime.Now; + flag = true; + } + if (ET < PT) ET = Convert.ToInt64(DateTime.Now.Subtract(startTime).TotalSeconds); + } + else + { + ET = 0; + flag = false; + } + IN1 = ET >= PT; + return Q; + } + } +} diff --git a/BPASmartClient.Helper/ExpandMethod.cs b/BPASmartClient.Helper/ExpandMethod.cs new file mode 100644 index 00000000..e3f65e7d --- /dev/null +++ b/BPASmartClient.Helper/ExpandMethod.cs @@ -0,0 +1,100 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.Helper +{ + public static class ExpandMethod + { + /// + /// 获取布尔数组指定值得索引 + /// + /// 要获取索引的数组 + /// 要获取索引的值 + /// + public static int GetIndex(this bool[] obj, bool value) + { + if (obj == null) return -1; + return Array.FindIndex(obj, p => p == value); + } + + /// + /// 获取字符串数组指定值得索引 + /// + /// 要获取索引的数组 + /// 要获取索引的值 + /// + public static int GetIndex(this string[] obj, string value) + { + if (obj == null || value == null) return -1; + return Array.FindIndex(obj, p => p == value && p.Length > 0); + } + + /// + /// 委托回调 + /// + /// 要执行的委托 + /// 委托回调 + public static void Invoke(this Action action, Action callback) + { + if (action != null) + { + action(); + if (callback != null) callback(); + } + } + + /// + /// 委托回调 + /// + /// 要执行的委托 + /// 要执行的委托的参数 + /// 委托回调 + public static void Invoke(this Action action, object par, Action callback) + { + if (action != null) + { + action(par); + if (callback != null) callback(); + } + } + + + + ///// + ///// 保存数据 + ///// + //public static void Save(this T ot) + //{ + // string outjson = JsonConvert.SerializeObject(ot); + // var str = ot.GetType().GenericTypeArguments; + // if (str != null && str.Length > 0) + // { + // File.WriteAllText(LocaPath.GetInstance.Getpath(str[0].Name), outjson); + // } + + //} + + ///// + ///// 获取保存的数据 + ///// + //public static void Read(this object ot) + //{ + // var str = ot.GetType().GenericTypeArguments; + // if (str != null && str.Length > 0) + // { + // string pa = LocaPath.GetInstance.Getpath(str[0].Name); + // if (File.Exists(pa)) + // { + // string JsonString = File.ReadAllText(pa); + // var result = JsonConvert.DeserializeObject(JsonString); + // if (result != null) { Json.Data = result; } + // } + // } + //} + } +} diff --git a/BPASmartClient.Helper/Json.cs b/BPASmartClient.Helper/Json.cs new file mode 100644 index 00000000..79b49031 --- /dev/null +++ b/BPASmartClient.Helper/Json.cs @@ -0,0 +1,95 @@ +using Newtonsoft.Json; +using System; +using System.IO; +using System.Collections.Concurrent; +using System.Reflection; + +namespace BPASmartClient.Helper +{ + /// + /// Json参数服务类 + /// + public class Json where T : class, new() + { + + //private static string DeviceType = ActionManage.GetInstance.SendResult("GetDeviceType").ToString(); + + //static string path + //{ + // get + // { + // Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"AccessFile\\{DeviceType}\\JSON")); + // return $"{AppDomain.CurrentDomain.BaseDirectory}AccessFile\\{DeviceType}\\JSON\\{typeof(T).Name}.json"; + // } + //} + + static string path + { + get + { + Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"{LocaPath.GetInstance.FilePath}\\JSON")); + return $"{AppDomain.CurrentDomain.BaseDirectory}{LocaPath.GetInstance.FilePath}JSON\\{typeof(T).Name}.json"; + } + } + + public static T Data { get; set; } = new T(); + + /// + /// 保存数据 + /// + public static void Save() + { + string outjson = JsonConvert.SerializeObject(Data); + File.WriteAllText(path, outjson); + } + + + + /// + /// 获取保存的数据 + /// + public static void Read() + { + if (File.Exists(path)) + { + string JsonString = File.ReadAllText(path); + var result = JsonConvert.DeserializeObject(JsonString); + if (result != null) { Data = result; } + } + } + + /// + /// 保存带接口的对象 + /// + public static void SaveInterface() + { + var settings = new JsonSerializerSettings(); + settings.TypeNameHandling = TypeNameHandling.Objects; + string outjson = JsonConvert.SerializeObject(Data, Formatting.Indented, settings); + File.WriteAllText(path, outjson); + } + + /// + /// 获取带接口对象的字符串 + /// + public static void ReadInterface() + { + if (File.Exists(path)) + { + var settings = new JsonSerializerSettings(); + settings.TypeNameHandling = TypeNameHandling.Objects; + string JsonString = File.ReadAllText(path); + var result = JsonConvert.DeserializeObject(JsonString, settings); + if (result != null) { Data = result; } + } + } + + /* + 使用反序列化接口对象的方法 + 一、使用 SaveInterface 方法保存成字符串,使用 ReadInterface 方法获取对象 + 二、在接口属性上加一个特性 [JsonProperty(TypeNameHandling = TypeNameHandling.Auto)] + */ + + + } +} diff --git a/BPASmartClient.Helper/LocaPath.cs b/BPASmartClient.Helper/LocaPath.cs new file mode 100644 index 00000000..d9edef46 --- /dev/null +++ b/BPASmartClient.Helper/LocaPath.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.Helper +{ + public class LocaPath + { + + private volatile static LocaPath _Instance; + public static LocaPath GetInstance => _Instance ?? (_Instance = new LocaPath()); + private LocaPath() { } + + public string FilePath { get; set; } = string.Empty; + + public string Getpath(string name) + { + Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"{FilePath}\\JSON")); + return $"{AppDomain.CurrentDomain.BaseDirectory}{FilePath}JSON\\{name}.json"; + } + + } +} diff --git a/BPASmartClient.Helper/RTrig.cs b/BPASmartClient.Helper/RTrig.cs new file mode 100644 index 00000000..86cd4ea4 --- /dev/null +++ b/BPASmartClient.Helper/RTrig.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.Helper +{ + /// + /// 上升沿操作类 + /// + public class RTrig + { + private volatile static ConcurrentDictionary _Instance; + public static RTrig GetInstance(string name) + { + if (_Instance == null) _Instance = new ConcurrentDictionary(); + if (!_Instance.ContainsKey(name)) _Instance.TryAdd(name, new RTrig()); + return _Instance[name]; + } + private RTrig() { } + + private bool flag1; + public bool Q { get; private set; } + private bool IN1 + { + set + { + Q = value && !flag1; + flag1 = value; + } + } + public bool Start(bool IN) + { + IN1 = IN; + return Q; + } + } +} diff --git a/BPASmartClient.Helper/Singleton.cs b/BPASmartClient.Helper/Singleton.cs new file mode 100644 index 00000000..3aa01035 --- /dev/null +++ b/BPASmartClient.Helper/Singleton.cs @@ -0,0 +1,31 @@ +using System; + +/* *********************************************** + * subject 单例对象基类 + * author 张原川 + * date   2019/6/3 9:49:03 + * ***********************************************/ + +namespace BPASmartClient.Helper +{ + /// + /// 单例对象基类 + /// + /// + public class Singleton where T : new() + { + private static object _async = new object(); + + private static T _instance; + + static readonly Lazy instance = new(); + /// + /// 获取实例 + /// + /// + public static T GetInstance() + { + return instance.Value; + } + } +} \ No newline at end of file diff --git a/BPASmartClient.Helper/SystemHelper.cs b/BPASmartClient.Helper/SystemHelper.cs new file mode 100644 index 00000000..3fcab17b --- /dev/null +++ b/BPASmartClient.Helper/SystemHelper.cs @@ -0,0 +1,237 @@ +using IWshRuntimeLibrary; +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.Helper +{ + /// + /// 系统操作类 + /// + public class SystemHelper + { + private volatile static SystemHelper _Instance; + public static SystemHelper GetInstance => _Instance ?? (_Instance = new SystemHelper()); + private SystemHelper() { } + + /// + /// 获取当前应用程序名称,包括后缀名 + /// + public string GetApplicationName => $"{AppDomain.CurrentDomain.FriendlyName}.exe"; + + /// + /// 获取当前应用程序完整路径 + /// + public string GetApplicationPath => $"{AppDomain.CurrentDomain.BaseDirectory}{GetApplicationName}"; + + /// + /// 创建桌面快捷方式 + /// + /// 成功或失败 + public bool CreateDesktopShortcut() + { + //1、在COM对象中找到 Windows Script Host Object Model + //2、添加引用 using IWshRuntimeLibrary; + string deskTop = string.Empty; + try + { + deskTop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\"; + if (System.IO.File.Exists(deskTop + GetApplicationName + ".lnk")) // + { + return true; + //System.IO.File.Delete(deskTop + FileName + ".lnk");//删除原来的桌面快捷键方式 + } + WshShell shell = new WshShell(); + //快捷键方式创建的位置、名称 + IWshShortcut shortcut = shell.CreateShortcut(deskTop + GetApplicationName + ".lnk") as IWshShortcut; + shortcut.TargetPath = GetApplicationPath; //目标文件 + //该属性指定应用程序的工作目录,当用户没有指定一个具体的目录时,快捷方式的目标应用程序将使用该属性所指定的目录来装载或保存文件。 + shortcut.WorkingDirectory = System.Environment.CurrentDirectory; + shortcut.WindowStyle = 1; //目标应用程序的窗口状态分为普通、最大化、最小化【1,3,7】 + shortcut.Description = GetApplicationName; //描述 + //shortcut.IconLocation = exePath + "\\logo.ico"; //快捷方式图标 + shortcut.Arguments = ""; + //shortcut.Hotkey = "CTRL+ALT+F11"; // 快捷键 + shortcut.Save(); //必须调用保存快捷才成创建成功 + return true; + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx(ex.ToString()); + return false; + } + } + + /// + /// 设置开机自启动 + /// + /// true:开机启动,false:不开机自启 + public void AutoStart(bool isAuto = true) + { + if (isAuto == true) + { + RegistryKey R_local = Registry.CurrentUser; + RegistryKey R_run = R_local.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); + R_run.SetValue(GetApplicationName, GetApplicationPath); + R_run.Close(); + R_local.Close(); + } + else + { + RegistryKey R_local = Registry.CurrentUser; + RegistryKey R_run = R_local.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); + R_run.DeleteValue(GetApplicationName, false); + R_run.Close(); + R_local.Close(); + } + } + + /// + /// 判断是否是自动启动 + /// + /// + public bool IsAutoStart() + { + RegistryKey R_local = Registry.CurrentUser; + RegistryKey R_run = R_local.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); + bool res = R_run.GetValueNames().Contains(GetApplicationName); + R_run.Close(); + R_local.Close(); + return res; + } + + #region U盘,串口插拔信息 + private const int WM_DEVICECHANGE = 0x219; //设备改变 + private const int DBT_DEVICEARRIVAL = 0x8000; //检测到新设备 + private const int DBT_DEVICEREMOVECOMPLETE = 0x8004; //移除设备 + public const int DBT_DEVTYP_PORT = 0x00000003; + public const int DBT_DEVTYP_VOLUME = 0x00000002; + + public IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) + { + if (msg == WM_DEVICECHANGE) + { + //插入 + if (wParam.ToInt32() == DBT_DEVICEARRIVAL) + { + var volume = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(lParam, typeof(DEV_BROADCAST_HDR)); + + switch (volume.dbch_devicetype) + { + case DBT_DEVTYP_PORT://串口设备 + string portName = Marshal.PtrToStringUni(lParam + Marshal.SizeOf(typeof(DEV_BROADCAST_PORT))); + MessageLog.GetInstance.Show($"插入串口:[{portName}]"); + break; + case DBT_DEVTYP_VOLUME: + var drive = GetDrive(lParam); + MessageLog.GetInstance.Show($"usb插入:[{drive}]"); + break; + default: + break; + } + } + + //拔出 + if (wParam.ToInt32() == DBT_DEVICEREMOVECOMPLETE) + { + var volume = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(lParam, typeof(DEV_BROADCAST_HDR)); + switch (volume.dbch_devicetype) + { + case DBT_DEVTYP_PORT://串口设备 + string portName = Marshal.PtrToStringUni(lParam + Marshal.SizeOf(typeof(DEV_BROADCAST_PORT))); + MessageLog.GetInstance.Show($"拔出串口:[{portName}]"); + break; + case DBT_DEVTYP_VOLUME: + var drive = GetDrive(lParam); + MessageLog.GetInstance.Show($"usb拔出:[{drive}]"); + break; + default: + break; + } + } + } + return IntPtr.Zero; + } + + private static string GetDrive(IntPtr lParam) + { + var volume = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(lParam, typeof(DEV_BROADCAST_VOLUME)); + var letter = GetLetter(volume.dbcv_unitmask); + return string.Format("{0}:\\", letter); + } + + /// + /// 获得盘符 + /// + /// + /// 1 = A + /// 2 = B + /// 4 = C... + /// + /// 结果是A~Z的任意一个字符或者为'?' + private static char GetLetter(uint dbcvUnitmask) + { + const char nona = '?'; + const string drives = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if (dbcvUnitmask == 0) return nona; + var i = 0; + var pom = dbcvUnitmask >> 1; + while (pom != 0) + { + pom = pom >> 1; + i++; + } + if (i < drives.Length) + return drives[i]; + return nona; + } + + + #endregion + } + + [StructLayout(LayoutKind.Sequential)] + struct DEV_BROADCAST_HDR + { + public UInt32 dbch_size; + public UInt32 dbch_devicetype; + public UInt32 dbch_reserved; + } + + [StructLayout(LayoutKind.Sequential)] + struct DEV_BROADCAST_PORT + { + public uint dbcp_size; + public uint dbcp_devicetype; + public uint dbcp_reserved; + } + + [StructLayout(LayoutKind.Sequential)] + struct DEV_BROADCAST_PORT_A + { + public uint dbcp_size; + public uint dbcp_devicetype; + public uint dbcp_reserved; + //public string dbcp_name; + } + + [StructLayout(LayoutKind.Sequential)] + struct DEV_BROADCAST_VOLUME + { + /// DWORD->unsigned int + public uint dbcv_size; + /// DWORD->unsigned int + public uint dbcv_devicetype; + /// DWORD->unsigned int + public uint dbcv_reserved; + /// DWORD->unsigned int + public uint dbcv_unitmask; + /// WORD->unsigned short + public ushort dbcv_flags; + } +} diff --git a/BPASmartClient.Helper/TTrig.cs b/BPASmartClient.Helper/TTrig.cs new file mode 100644 index 00000000..0b047c86 --- /dev/null +++ b/BPASmartClient.Helper/TTrig.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Text; + +namespace BPASmartClient.Helper +{ + /// + /// 下降沿操作 + /// + public class TTrig + { + private volatile static ConcurrentDictionary _Instance; + public static TTrig GetInstance(string name) + { + if (_Instance == null) _Instance = new ConcurrentDictionary(); + if (!_Instance.ContainsKey(name)) _Instance.TryAdd(name, new TTrig()); + return _Instance[name]; + } + private TTrig() { } + + private bool flag1; + public bool Q { get; private set; } + private bool IN1 + { + set + { + Q = !value && flag1; + flag1 = value; + } + } + public bool Start(bool IN) + { + IN1 = IN; + return Q; + } + + } +} diff --git a/BPASmartClient.Helper/TextHelper.cs b/BPASmartClient.Helper/TextHelper.cs new file mode 100644 index 00000000..3f4407f2 --- /dev/null +++ b/BPASmartClient.Helper/TextHelper.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.Helper +{ + public class TextHelper + { + + private volatile static TextHelper _Instance; + public static TextHelper GetInstance => _Instance ?? (_Instance = new TextHelper()); + private TextHelper() { } + + /// + /// 保存日志信息 + /// + /// + public void SaveLogInfo(string info, string name, string DicrectoryName = "Log") + { + if (info?.Length > 0) + { + Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"{LocaPath.GetInstance.FilePath}\\{DicrectoryName}")); + string path = $"{AppDomain.CurrentDomain.BaseDirectory}{LocaPath.GetInstance.FilePath}\\{DicrectoryName}\\{DateTime.Now.ToString("yyyy-MM-dd") + " " + name}.txt"; + StringBuilder sb = new StringBuilder(); + sb.Append($"****************************************** {DateTime.Now} ******************************************" + "\n"); + sb.Append(info); + sb.Append("**********************************************************************************************************" + "\n\n"); + FileStream fs = new FileStream($"{path}", FileMode.Append); + StreamWriter sw = new StreamWriter(fs); + sw.WriteLine(sb.ToString()); + sw.Close(); + fs.Close(); + } + } + + public string ReadTextInfo(string fileName, string DicrectoryName = "") + { + Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"AccessFile\\{DicrectoryName}")); + string path = $"{AppDomain.CurrentDomain.BaseDirectory}AccessFile\\{DicrectoryName}\\{fileName}.txt"; + FileStream fs = new FileStream(path, FileMode.OpenOrCreate); + StreamReader sr = new StreamReader(fs); + string GetStr = sr.ReadLine(); + if (GetStr == null) GetStr = string.Empty; + sr.Close(); + fs.Close(); + return GetStr; + } + + public void WriteTextInfo(string info, string fileName, string DicrectoryName = "") + { + Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"AccessFile\\{DicrectoryName}")); + string path = $"{AppDomain.CurrentDomain.BaseDirectory}AccessFile\\{DicrectoryName}\\{fileName}.txt"; + FileStream fs = new FileStream(path, FileMode.Create); + StreamWriter sw = new StreamWriter(fs); + sw.WriteLine(info); + sw.Close(); + fs.Close(); + } + + } +} diff --git a/BPASmartClient.Helper/ThreadManage.cs b/BPASmartClient.Helper/ThreadManage.cs new file mode 100644 index 00000000..f1bbb3f8 --- /dev/null +++ b/BPASmartClient.Helper/ThreadManage.cs @@ -0,0 +1,164 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Collections.Concurrent; +using System.Diagnostics; +using System.Threading; + +namespace BPASmartClient.Helper +{ + /// + /// 线程管理 + /// + public class ThreadManage + { + private volatile static ThreadManage _Instance; + public static ThreadManage GetInstance => _Instance ?? (_Instance = new ThreadManage()); + private ThreadManage() { } + string guid = "871d7e28-c413-4675-8d28-64e4dca4c2d3-"; + private static readonly object _lock = new object(); + StringBuilder callbackKey = new StringBuilder(); + List keys = new List(); + ConcurrentDictionary Threads = new ConcurrentDictionary(); + ConcurrentDictionary CancellationTokenSources = new ConcurrentDictionary(); + + /// + /// 停止指定任务 + /// + /// 任务名 + /// 任务结束的回调 + public void StopTask(string key, Action ExitCallback = null) + { + if (CancellationTokenSources.ContainsKey(guid + key)) + CancellationTokenSources[guid + key]?.Cancel(); + ActionManage.GetInstance.Register(ExitCallback, guid + key); + } + + /// + /// 长任务,带 while true 的循环 + /// + /// + /// + public void StartLong(Action action, string key, bool IsRestart = false, Action RunComplete = null) + { + CancellationTokenSources.TryAdd(guid + key, new CancellationTokenSource()); + bool result = Threads.TryAdd(guid + key, Task.Factory.StartNew(new Action(() => + { + ReStart: + try + { + while (!CancellationTokenSources[guid + key].IsCancellationRequested) + { + if (action != null) action(); + } + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx(ex.ToString()); + if (IsRestart) + { + Thread.Sleep(2000); + MessageLog.GetInstance.Show($"线程 【{key}】运行发生异常,已重启"); + goto ReStart; + } + else + { + CancellationTokenSources.TryRemove(guid + key, out CancellationTokenSource temp); + Threads.TryRemove(guid + key, out Task temp1); + MessageLog.GetInstance.Show($"线程 【{key}】运行发生异常,已退出"); + } + } + }), CancellationTokenSources[guid + key].Token).ContinueWith(new Action((t, o) => + { + ThreadStatus(t, o.ToString()); + if (RunComplete != null) RunComplete(); + }), guid + key)); + MessageLog.GetInstance.Show($"启动线程 【{key}】"); + if (!result) MessageLog.GetInstance.Show($"【{key}】任务已存在,请检查 TaskName"); + + } + + + /// + /// 不带 while true 的循环任务 + /// + /// + /// + public void Start(Action action, string key) + { + CancellationTokenSources.TryAdd(guid + key, new CancellationTokenSource()); + bool result = Threads.TryAdd(guid + key, Task.Factory.StartNew(new Action(() => + { + if (action != null) action(); + }), CancellationTokenSources[guid + key].Token).ContinueWith(new Action((t, o) => + { + ThreadStatus(t, o.ToString()); + }), guid + key)); + if (!result) MessageLog.GetInstance.Show($"【{key}】任务已存在,请检查 TaskName"); + } + + private void ThreadStatus(Task task, string key) + { + bool IsRemove = false; + string name = key.Substring(key.LastIndexOf('-') + 1); + switch (task.Status) + { + case TaskStatus.RanToCompletion: + MessageLog.GetInstance.Show($"线程【{name}】执行完成"); + IsRemove = true; + break; + case TaskStatus.Faulted: + MessageLog.GetInstance.Show($"线程【{name}】执行异常,{task.Exception}"); + IsRemove = true; + break; + case TaskStatus.Canceled: + MessageLog.GetInstance.Show($"线程【{name}】已取消"); + IsRemove = true; + break; + default: + break; + } + + if (IsRemove) + { + if (Threads.ContainsKey(key)) + Threads.TryRemove(key, out Task t); + //Threads.TryRemove(Threads.FirstOrDefault(p => p.Key == TaskName)); + + + if (CancellationTokenSources.ContainsKey(key)) + CancellationTokenSources.TryRemove(key, out CancellationTokenSource cts); + //CancellationTokenSources.TryRemove(CancellationTokenSources.FirstOrDefault(p => p.Key == TaskName)); + //keys.Remove(key); + //if (keys != null && keys.Count == 0) ActionManage.GetInstance.Send(callbackKey.ToString()); + ActionManage.GetInstance.Send(key); + } + } + + /// + /// 释放所有线程资源 + /// + public void Dispose() + { + for (int i = 0; i < CancellationTokenSources.Count; i++) + { + CancellationTokenSources.ElementAt(i).Value.Cancel(); + } + } + + /// + /// 判断指定线程是否完成 + /// + /// + /// + public bool IsComplete(string key) + { + if (Threads.ContainsKey(guid + key)) return Threads[guid + key].IsCompleted; + return false; + } + + } + +} diff --git a/BPASmartClient.Helper/UniversalHelper.cs b/BPASmartClient.Helper/UniversalHelper.cs new file mode 100644 index 00000000..c201fde5 --- /dev/null +++ b/BPASmartClient.Helper/UniversalHelper.cs @@ -0,0 +1,49 @@ +//using GVL; +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace BPASmartClient.Helper +{ + /// + /// 其它通用库 + /// + public class UniversalHelper:Singleton + { + + [DllImport("wininet")] + //判断网络状况的方法,返回值true为连接,false为未连接 + public extern static bool InternetGetConnectedState(out int conState, int reder); + + /// + /// 获取当前网络连接状态 + /// + /// 成功连接网络返回 true,未连接返回 false + public bool GetNetworkState() + { + return InternetGetConnectedState(out int i, 0); + } + + public void Init() + { + //while (!GVL_VAR.GetInstance.NetworkConnectState) + //{ + // //GVL_VAR.GetInstance.NetworkConnectState = GetNetworkState(); + // Thread.Sleep(1000); + //} + //ThreadManagerment.GetInstance.StartLong(new Action(() => + //{ + // //GVL_VAR.GetInstance.NetworkConnectState = GetNetworkState(); + // Thread.Sleep(1000); + //}), "网络监听状态"); + } + + + + } +} diff --git a/BPASmartClient.Http/BPASmartClient.Http.csproj b/BPASmartClient.Http/BPASmartClient.Http.csproj new file mode 100644 index 00000000..dbc15171 --- /dev/null +++ b/BPASmartClient.Http/BPASmartClient.Http.csproj @@ -0,0 +1,7 @@ + + + + net6.0 + + + diff --git a/BPASmartClient.Http/Class1.cs b/BPASmartClient.Http/Class1.cs new file mode 100644 index 00000000..904d626d --- /dev/null +++ b/BPASmartClient.Http/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace BPASmartClient.Http +{ + public class Class1 + { + } +} diff --git a/BPASmartClient.IoT/BPASmartClient.IoT.csproj b/BPASmartClient.IoT/BPASmartClient.IoT.csproj new file mode 100644 index 00000000..dbc15171 --- /dev/null +++ b/BPASmartClient.IoT/BPASmartClient.IoT.csproj @@ -0,0 +1,7 @@ + + + + net6.0 + + + diff --git a/BPASmartClient.IoT/Class1.cs b/BPASmartClient.IoT/Class1.cs new file mode 100644 index 00000000..1aa0de8c --- /dev/null +++ b/BPASmartClient.IoT/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace BPASmartClient.IoT +{ + public class Class1 + { + } +} diff --git a/BPASmartClient.KLMCoffee/BPASmartClient.KLMCoffee.csproj b/BPASmartClient.KLMCoffee/BPASmartClient.KLMCoffee.csproj new file mode 100644 index 00000000..dbc15171 --- /dev/null +++ b/BPASmartClient.KLMCoffee/BPASmartClient.KLMCoffee.csproj @@ -0,0 +1,7 @@ + + + + net6.0 + + + diff --git a/BPASmartClient.KLMCoffee/Class1.cs b/BPASmartClient.KLMCoffee/Class1.cs new file mode 100644 index 00000000..0e9d2ac1 --- /dev/null +++ b/BPASmartClient.KLMCoffee/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace BPASmartClient.KLMCoffee +{ + public class Class1 + { + } +} diff --git a/BPASmartClient.Lebai/BPASmartClient.Lebai.csproj b/BPASmartClient.Lebai/BPASmartClient.Lebai.csproj new file mode 100644 index 00000000..dbc15171 --- /dev/null +++ b/BPASmartClient.Lebai/BPASmartClient.Lebai.csproj @@ -0,0 +1,7 @@ + + + + net6.0 + + + diff --git a/BPASmartClient.Lebai/Class1.cs b/BPASmartClient.Lebai/Class1.cs new file mode 100644 index 00000000..7960d771 --- /dev/null +++ b/BPASmartClient.Lebai/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace BPASmartClient.Lebai +{ + public class Class1 + { + } +} diff --git a/BPASmartClient.MQTT/BPASmartClient.MQTT.csproj b/BPASmartClient.MQTT/BPASmartClient.MQTT.csproj new file mode 100644 index 00000000..5f95ecae --- /dev/null +++ b/BPASmartClient.MQTT/BPASmartClient.MQTT.csproj @@ -0,0 +1,16 @@ + + + + net6.0 + + + + + + + + + + + + diff --git a/BPASmartClient.MQTT/MqttHelper.cs b/BPASmartClient.MQTT/MqttHelper.cs new file mode 100644 index 00000000..4976b40c --- /dev/null +++ b/BPASmartClient.MQTT/MqttHelper.cs @@ -0,0 +1,183 @@ +using BPASmartClient.Helper; +using HBLConsole.Service; +using MQTTnet; +using MQTTnet.Client; +using MQTTnet.Client.Options; +using System; +using System.Threading; + +namespace HBLConsole.Communication +{ + public class MqttHelper + { + + private volatile static MqttHelper _Instance; + public static MqttHelper GetInstance => _Instance ?? (_Instance = new MqttHelper()); + private MqttHelper() { } + + private IMqttClient client; + IMqttClientOptions options; + + /// + /// MQTT 接收消息 + /// + public Action MqttReceive { get; set; } + + /// + /// MQTT 连接成功 + /// + public Action ConnectOk { get; set; } + + /// + /// 重连成功 + /// + public Action Reconnection { get; set; } + + Action UseDisconnectedAction; + + + public async void MqttInitAsync(string UserName, string pass, string IP, int port, string clientID) + { + options = new MqttClientOptionsBuilder().WithTcpServer(IP, port).WithClientId(clientID).WithCredentials(UserName, pass).Build(); + client = new MqttFactory().CreateMqttClient(); + client.UseDisconnectedHandler(c => + { + if (UseDisconnectedAction == null) + { + Reconnect(); + UseDisconnectedAction(); + } + + }).UseApplicationMessageReceivedHandler(c => + { + MqttReceive(c); + }).UseConnectedHandler((e) => + { + MessageLog.GetInstance.Show($"连接成功"); + }); + + try + { + await client.ConnectAsync(options); + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx(ex.Message); + MessageLog.GetInstance.Show("mqtt连接失败!重连执行中"); + } + + if (client.IsConnected) + { + MessageLog.GetInstance.Show("MQTT连接成功!"); + if (ConnectOk != null) ConnectOk(); + } + + } + + private void Reconnect() + { + UseDisconnectedAction = new Action(() => + { + Thread.Sleep(2000); + while (!UniversalHelper.GetInstance().GetNetworkState()) + { + Thread.Sleep(2000); + } + MessageLog.GetInstance.Show($"断开连接"); + bool ErrorFlag = false; + while (!client.IsConnected) + { + try + { + MessageLog.GetInstance.Show($"重连中"); + client.ConnectAsync(options).Wait(); + } + catch (Exception ex) + { + if (!ErrorFlag) + { + MessageLog.GetInstance.ShowEx(ex.ToString()); + ErrorFlag = true; + } + } + Thread.Sleep(3000); + } + + if (client.IsConnected) + { + MessageLog.GetInstance.Show("MQTT重连成功!"); + if (Reconnection != null) Reconnection(); + } + UseDisconnectedAction = null; + }); + } + + /// + /// Mqtt 订阅 + /// + /// 需要订阅的主题 + public async void MqttSubscriptionAsync(string topic) + { + if (client != null) + { + if (client.IsConnected) + { + try + { + var result = await client.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic(topic).WithExactlyOnceQoS().Build()); + } + catch { } + } + } + } + + /// + /// Mqtt 订阅 + /// + /// 需要订阅的主题 + public async void MqttSubscriptionAsync(string[] topic) + { + if (client != null) + { + if (client.IsConnected) + { + try + { + foreach (var item in topic) + { + var result = await client.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic(item).WithExactlyOnceQoS().Build()); + } + + } + catch { } + } + } + } + + /// + /// Mqtt 发布 + /// + /// 需要发布的主题 + /// 需要发布的内容 + public async void MqttPublishAsync(string topic, string content) + { + if (client != null) + { + if (client.IsConnected) + { + + var msg = new MqttApplicationMessageBuilder().WithTopic(topic).WithPayload(content).WithExactlyOnceQoS().Build(); + try + { + var result = await client.PublishAsync(msg); + } + catch { } + } + } + } + + + + + } +} diff --git a/BPASmartClient.Message/BPASmartClient.Message.csproj b/BPASmartClient.Message/BPASmartClient.Message.csproj new file mode 100644 index 00000000..dbc15171 --- /dev/null +++ b/BPASmartClient.Message/BPASmartClient.Message.csproj @@ -0,0 +1,7 @@ + + + + net6.0 + + + diff --git a/BPASmartClient.Message/MessageLog.cs b/BPASmartClient.Message/MessageLog.cs new file mode 100644 index 00000000..acb7c136 --- /dev/null +++ b/BPASmartClient.Message/MessageLog.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HBLConsole.Service +{ + public class MessageLog + { + private volatile static MessageLog _Instance; + public static MessageLog GetInstance => _Instance ?? (_Instance = new MessageLog()); + private MessageLog() { } + + #region 普通消息日志 + /// + /// 日志显示委托 + /// + public Action InfoNotify { get; set; } + + /// + /// 日志信息 + /// + public string LogInfo { get; set; } = string.Empty; + + /// + /// 普通日志输出 + /// + /// + public void Show(string info) + { + Debug.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")}:{info}"); + LogInfo = $"{DateTime.Now.ToString("HH:mm:ss")}:{info} \n\r {LogInfo}"; + if (InfoNotify != null) InfoNotify(info); + } + #endregion + + #region 异常消息日志 + /// + /// 异常日志委托 + /// + public Action ExInfoNotify { get; set; } + + /// + /// 异常日志信息 + /// + public string ExLogInfo { get; set; } = string.Empty; + + /// + /// 异常日志输出 + /// + /// + public void ShowEx(string info) + { + Debug.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")}:{info}"); + ExLogInfo = $"{DateTime.Now.ToString("HH:mm:ss")}:{info} \n\r {ExLogInfo}"; + if (ExInfoNotify != null) ExInfoNotify(info); + } + #endregion + + + + + + } +} diff --git a/BPASmartClient.Modbus/BPASmartClient.Modbus.csproj b/BPASmartClient.Modbus/BPASmartClient.Modbus.csproj new file mode 100644 index 00000000..dbc15171 --- /dev/null +++ b/BPASmartClient.Modbus/BPASmartClient.Modbus.csproj @@ -0,0 +1,7 @@ + + + + net6.0 + + + diff --git a/BPASmartClient.Modbus/Class1.cs b/BPASmartClient.Modbus/Class1.cs new file mode 100644 index 00000000..1f270a73 --- /dev/null +++ b/BPASmartClient.Modbus/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace BPASmartClient.Modbus +{ + public class Class1 + { + } +} diff --git a/BPASmartClient.MorkD/BPASmartClient.MorkD.csproj b/BPASmartClient.MorkD/BPASmartClient.MorkD.csproj new file mode 100644 index 00000000..dbc15171 --- /dev/null +++ b/BPASmartClient.MorkD/BPASmartClient.MorkD.csproj @@ -0,0 +1,7 @@ + + + + net6.0 + + + diff --git a/BPASmartClient.MorkD/Class1.cs b/BPASmartClient.MorkD/Class1.cs new file mode 100644 index 00000000..34c1a5d3 --- /dev/null +++ b/BPASmartClient.MorkD/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace BPASmartClient.MorkD +{ + public class Class1 + { + } +} diff --git a/BPASmartClient.MorkS/BPASmartClient.MorkS.csproj b/BPASmartClient.MorkS/BPASmartClient.MorkS.csproj new file mode 100644 index 00000000..dbc15171 --- /dev/null +++ b/BPASmartClient.MorkS/BPASmartClient.MorkS.csproj @@ -0,0 +1,7 @@ + + + + net6.0 + + + diff --git a/BPASmartClient.MorkS/Class1.cs b/BPASmartClient.MorkS/Class1.cs new file mode 100644 index 00000000..b763bb63 --- /dev/null +++ b/BPASmartClient.MorkS/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace BPASmartClient.MorkS +{ + public class Class1 + { + } +} diff --git a/BPASmartClient.MorkT/BPASmartClient.MorkT.csproj b/BPASmartClient.MorkT/BPASmartClient.MorkT.csproj new file mode 100644 index 00000000..dbc15171 --- /dev/null +++ b/BPASmartClient.MorkT/BPASmartClient.MorkT.csproj @@ -0,0 +1,7 @@ + + + + net6.0 + + + diff --git a/BPASmartClient.SCChip/BPASmartClient.SCChip.csproj b/BPASmartClient.SCChip/BPASmartClient.SCChip.csproj new file mode 100644 index 00000000..dbc15171 --- /dev/null +++ b/BPASmartClient.SCChip/BPASmartClient.SCChip.csproj @@ -0,0 +1,7 @@ + + + + net6.0 + + + diff --git a/BPASmartClient.SCChip/Class1.cs b/BPASmartClient.SCChip/Class1.cs new file mode 100644 index 00000000..9e542251 --- /dev/null +++ b/BPASmartClient.SCChip/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace BPASmartClient.SCChip +{ + public class Class1 + { + } +} diff --git a/BPASmartClient.SerialPort/BPASmartClient.SerialPort.csproj b/BPASmartClient.SerialPort/BPASmartClient.SerialPort.csproj new file mode 100644 index 00000000..2b322195 --- /dev/null +++ b/BPASmartClient.SerialPort/BPASmartClient.SerialPort.csproj @@ -0,0 +1,15 @@ + + + + net6.0 + + + + + + + + + + + diff --git a/BPASmartClient.SerialPort/SerialParameter.cs b/BPASmartClient.SerialPort/SerialParameter.cs new file mode 100644 index 00000000..1a9dd03c --- /dev/null +++ b/BPASmartClient.SerialPort/SerialParameter.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.SerialPort +{ + #region 波特率、数据位的枚举 + /// + /// 串口数据位列表(5,6,7,8) + /// + public enum DataBits : int + { + Five = 5, + Six = 6, + Sevent = 7, + Eight = 8 + } + + /// + /// 串口波特率列表。 + /// 75,110,150,300,600,1200,2400,4800,9600,14400,19200,28800,38400,56000,57600, + /// 115200,128000,230400,256000 + /// + public enum BaudRates : int + { + BR_75 = 75, + BR_110 = 110, + BR_150 = 150, + BR_300 = 300, + BR_600 = 600, + BR_1200 = 1200, + BR_2400 = 2400, + BR_4800 = 4800, + BR_9600 = 9600, + BR_14400 = 14400, + BR_19200 = 19200, + BR_28800 = 28800, + BR_38400 = 38400, + BR_56000 = 56000, + BR_57600 = 57600, + BR_115200 = 115200, + BR_128000 = 128000, + BR_230400 = 230400, + BR_256000 = 256000 + } + #endregion + +} diff --git a/BPASmartClient.SerialPort/SerialPortClient.cs b/BPASmartClient.SerialPort/SerialPortClient.cs new file mode 100644 index 00000000..7ca8541a --- /dev/null +++ b/BPASmartClient.SerialPort/SerialPortClient.cs @@ -0,0 +1,243 @@ +using BPASmartClient.Helper; +using System; +using System.IO.Ports; +using System.Linq; + +namespace BPASmartClient.SerialPort +{ + public class SerialPortClient + { + #region 变量属性 + private DataStorage dataStorage; + public event SerialErrorReceivedEventHandler ErrorReceived; + + private System.IO.Ports.SerialPort comPort = new System.IO.Ports.SerialPort(); + private string portName = "COM1";//串口号,默认COM1 + private BaudRates baudRate = BaudRates.BR_9600;//波特率 + private Parity parity = Parity.None;//校验位 + private StopBits stopBits = StopBits.One;//停止位 + private DataBits dataBits = DataBits.Eight;//数据位 + + /// + /// 串口号 + /// + public string PortName + { + get { return portName; } + set { portName = value; } + } + + /// + /// 波特率 + /// + public BaudRates BaudRate + { + get { return baudRate; } + set { baudRate = value; } + } + #endregion + + #region 构造函数 + /// + /// 无参构造函数 + /// + public SerialPortClient(string name, BaudRates baud) + { + this.portName = name; + this.baudRate = baud; + BoundEvents(); + } + + void BoundEvents() + { + comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived); + comPort.ErrorReceived += new SerialErrorReceivedEventHandler(comPort_ErrorReceived); + } + + /// + /// 参数构造函数(使用枚举参数构造) + /// + /// 波特率 + /// 奇偶校验位 + /// 停止位 + /// 数据位 + /// 串口号 + public SerialPortClient(string name, BaudRates baud, Parity par, DataBits dBits, StopBits sBits) + { + this.portName = name; + this.baudRate = baud; + this.parity = par; + this.dataBits = dBits; + this.stopBits = sBits; + BoundEvents(); + } + + /// + /// 参数构造函数(使用字符串参数构造) + /// + /// 波特率 + /// 奇偶校验位 + /// 停止位 + /// 数据位 + /// 串口号 + public SerialPortClient(string name, string baud, string par, string dBits, string sBits) + { + this.portName = name; + this.baudRate = (BaudRates)Enum.Parse(typeof(BaudRates), baud); + this.parity = (Parity)Enum.Parse(typeof(Parity), par); + this.dataBits = (DataBits)Enum.Parse(typeof(DataBits), dBits); + this.stopBits = (StopBits)Enum.Parse(typeof(StopBits), sBits); + BoundEvents(); + } + #endregion + + #region 事件处理函数 + /// + /// 数据接收处理 + /// + void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e) + { + if (comPort.IsOpen) //判断是否打开串口 + { + + byte[] receivedData = new byte[comPort.BytesToRead]; //创建接收字节数组 + comPort.Read(receivedData, 0, receivedData.Length); //读取数据 + + //触发整条记录的处理 + if (dataStorage != null) + { + dataStorage.PutData(receivedData); + } + + } + else + { + Console.WriteLine("请打开某个串口", "Error"); + } + } + /// + /// 错误处理函数 + /// + void comPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e) + { + if (ErrorReceived != null) + { + ErrorReceived(sender, e); + } + } + #endregion + + #region 串口关闭/打开 + /// + /// 端口是否已经打开 + /// + public bool IsOpen + { + get + { + return comPort.IsOpen; + } + } + + /// + /// 判断是否有这个串口 + /// + public bool IsHavePort => System.IO.Ports.SerialPort.GetPortNames().Contains(PortName); + + /// + /// 打开端口 + /// + /// + public void Open() + { + lock (lck4Serial) + { + if (!IsHavePort) return; + if (comPort.IsOpen) comPort.Close(); + comPort.PortName = portName; + comPort.BaudRate = (int)baudRate; + comPort.Parity = parity; + comPort.DataBits = (int)dataBits; + comPort.StopBits = stopBits; + comPort.Open(); + } + } + + /// + /// 关闭端口 + /// + public void Close() + { + if (!IsHavePort) return; + if (comPort.IsOpen) comPort.Close(); + } + + /// + /// 丢弃来自串行驱动程序的接收和发送缓冲区的数据 + /// + public void DiscardBuffer() + { + comPort.DiscardInBuffer(); + comPort.DiscardOutBuffer(); + } + #endregion + + private object lck4Serial = new object(); + #region 写入数据 + /// + /// 写入数据 + /// + /// + public void Write(byte[] buffer, int offset, int count) + { + lock (lck4Serial) + { + if (!IsHavePort) return; + if (!(comPort.IsOpen)) comPort.Open(); + comPort.Write(buffer, offset, count); + } + } + + + /// + /// 读取数据 + /// + /// + public byte[] Read() + { + lock (lck4Serial) + { + if (!IsHavePort) return new byte[0]; + if (!(comPort.IsOpen)) comPort.Open(); + byte[] buffer = new byte[1024]; + comPort.Read(buffer, 0, buffer.Length); + return buffer; + } + } + public void Start() + { + Open(); + } + + public void Stop() + { + Close(); + } + + /// + /// 发送数据 + /// + /// 发送数据 + public void SendData(byte[] data) + { + Write(data, 0, data.Length); + } + + public void SetDataStorage(DataStorage dataStorage) + { + this.dataStorage = dataStorage; + } + #endregion + + } +} diff --git a/BPASmartClient.Socket/BPASmartClient.Socket.csproj b/BPASmartClient.Socket/BPASmartClient.Socket.csproj new file mode 100644 index 00000000..dbc15171 --- /dev/null +++ b/BPASmartClient.Socket/BPASmartClient.Socket.csproj @@ -0,0 +1,7 @@ + + + + net6.0 + + + diff --git a/BPASmartClient.Socket/Class1.cs b/BPASmartClient.Socket/Class1.cs new file mode 100644 index 00000000..0ecd9194 --- /dev/null +++ b/BPASmartClient.Socket/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace BPASmartClient.Socket +{ + public class Class1 + { + } +} diff --git a/BPASmartClient.Status/BPASmartClient.Status.csproj b/BPASmartClient.Status/BPASmartClient.Status.csproj new file mode 100644 index 00000000..dbc15171 --- /dev/null +++ b/BPASmartClient.Status/BPASmartClient.Status.csproj @@ -0,0 +1,7 @@ + + + + net6.0 + + + diff --git a/BPASmartClient.Status/Class1.cs b/BPASmartClient.Status/Class1.cs new file mode 100644 index 00000000..be4f8f1f --- /dev/null +++ b/BPASmartClient.Status/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace BPASmartClient.Status +{ + public class Class1 + { + } +} diff --git a/BPASmartClient.ViewModel/BPASmartClient.ViewModel.csproj b/BPASmartClient.ViewModel/BPASmartClient.ViewModel.csproj new file mode 100644 index 00000000..9a7c06f1 --- /dev/null +++ b/BPASmartClient.ViewModel/BPASmartClient.ViewModel.csproj @@ -0,0 +1,9 @@ + + + + net6.0-windows + enable + true + + + diff --git a/BPASmartClient.ViewModel/Class1.cs b/BPASmartClient.ViewModel/Class1.cs new file mode 100644 index 00000000..fa56f097 --- /dev/null +++ b/BPASmartClient.ViewModel/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace BPASmartClient.ViewModel +{ + public class Class1 + { + } +} diff --git a/BPASmartClient/App.xaml b/BPASmartClient/App.xaml new file mode 100644 index 00000000..c8f91fc8 --- /dev/null +++ b/BPASmartClient/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/BPASmartClient/App.xaml.cs b/BPASmartClient/App.xaml.cs new file mode 100644 index 00000000..06675a79 --- /dev/null +++ b/BPASmartClient/App.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace BPASmartClient +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + } +} diff --git a/BPASmartClient/AssemblyInfo.cs b/BPASmartClient/AssemblyInfo.cs new file mode 100644 index 00000000..8b5504ec --- /dev/null +++ b/BPASmartClient/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/BPASmartClient/BPASmartClient.csproj b/BPASmartClient/BPASmartClient.csproj new file mode 100644 index 00000000..4106cb0f --- /dev/null +++ b/BPASmartClient/BPASmartClient.csproj @@ -0,0 +1,10 @@ + + + + WinExe + net6.0-windows + enable + true + + + diff --git a/BPASmartClient/MainWindow.xaml b/BPASmartClient/MainWindow.xaml new file mode 100644 index 00000000..c6423776 --- /dev/null +++ b/BPASmartClient/MainWindow.xaml @@ -0,0 +1,12 @@ + + + + + diff --git a/BPASmartClient/MainWindow.xaml.cs b/BPASmartClient/MainWindow.xaml.cs new file mode 100644 index 00000000..4e8aca8a --- /dev/null +++ b/BPASmartClient/MainWindow.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BPASmartClient +{ + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class MainWindow : Window + { + public MainWindow() + { + InitializeComponent(); + } + } +} diff --git a/SmartClient.sln b/SmartClient.sln new file mode 100644 index 00000000..6b900df6 --- /dev/null +++ b/SmartClient.sln @@ -0,0 +1,180 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32002.185 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.DRCoffee", "BPASmartClient.DRCoffee\BPASmartClient.DRCoffee.csproj", "{31E9DC70-5889-4BA5-A5BA-FFDE66AFF314}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "4.Driver", "4.Driver", "{666CB1A9-562E-453A-A2C7-FD9D77CFDFDD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.KLMCoffee", "BPASmartClient.KLMCoffee\BPASmartClient.KLMCoffee.csproj", "{BA543940-3C97-410D-B66C-1B928FCBB567}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.GSIceCream", "BPASmartClient.GSIceCream\BPASmartClient.GSIceCream.csproj", "{51E93537-DE9A-460C-B2B6-5FCB7A616A94}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.SCChip", "BPASmartClient.SCChip\BPASmartClient.SCChip.csproj", "{F57AF771-8514-4020-BBF3-1708388DD4B3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Lebai", "BPASmartClient.Lebai\BPASmartClient.Lebai.csproj", "{69F90530-ADA4-4A0C-8068-AAC5584072D7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "5.Communication", "5.Communication", "{3D1D0E04-03FD-480A-8CF8-6E01A2E28625}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.SerialPort", "BPASmartClient.SerialPort\BPASmartClient.SerialPort.csproj", "{2344EB60-1760-4DF0-961A-FA5BE5BC47CC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Http", "BPASmartClient.Http\BPASmartClient.Http.csproj", "{202763AA-4C4C-4738-B530-93A9A1ECE578}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Modbus", "BPASmartClient.Modbus\BPASmartClient.Modbus.csproj", "{13C86146-CD3C-4CD3-AB7F-7A155E222832}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3.Device", "3.Device", "{9FB27073-61A0-4FE3-94DB-5FDDE062332F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MorkS", "BPASmartClient.MorkS\BPASmartClient.MorkS.csproj", "{0827FA85-8180-4A85-BE58-9483AC4BB3BA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MorkD", "BPASmartClient.MorkD\BPASmartClient.MorkD.csproj", "{8878BCFD-AC5E-4D84-8C63-CA99DDE036EE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MorkT", "BPASmartClient.MorkT\BPASmartClient.MorkT.csproj", "{B399BCFF-82E8-4940-9CE5-B7DCDDFDC696}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2.Business", "2.Business", "{6CEA3385-6F62-452A-8275-033A6037235D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "1.UI", "1.UI", "{8712125E-14CD-4E1B-A1CE-4BDE03805942}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "6.Uitility", "6.Uitility", "{1A9920BA-7C8D-4BDC-8D7D-6544A71AF3CF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Helper", "BPASmartClient.Helper\BPASmartClient.Helper.csproj", "{A2A5CB83-11C7-4534-A65D-6F957B60EEFF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Message", "BPASmartClient.Message\BPASmartClient.Message.csproj", "{C517D33F-8800-405E-9D59-E1F6CA201431}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.DeviceProxy", "BPASmartClient.DeviceProxy\BPASmartClient.DeviceProxy.csproj", "{9D26C2D6-CF32-4FB6-A15E-8A1455DACD69}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Status", "BPASmartClient.Status\BPASmartClient.Status.csproj", "{2C8DAB92-D5EB-4462-87C1-0BED75B26C54}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.IoT", "BPASmartClient.IoT\BPASmartClient.IoT.csproj", "{D3DBCC2D-086E-4E3A-B70A-22A79FB295CF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient", "BPASmartClient\BPASmartClient.csproj", "{2BA531E8-7F85-4EBF-AE97-811CD7C83EF2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.ViewModel", "BPASmartClient.ViewModel\BPASmartClient.ViewModel.csproj", "{4E393E60-D39A-4118-8BD5-427DC72E9ACE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Device", "BPASmartClient.Device\BPASmartClient.Device.csproj", "{FFECD10B-FE66-4331-A915-409F5BE04480}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MQTT", "BPASmartClient.MQTT\BPASmartClient.MQTT.csproj", "{7D290C8E-ACA7-4F03-91DF-D507FB3E2E87}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Socket", "BPASmartClient.Socket\BPASmartClient.Socket.csproj", "{F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {31E9DC70-5889-4BA5-A5BA-FFDE66AFF314}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {31E9DC70-5889-4BA5-A5BA-FFDE66AFF314}.Debug|Any CPU.Build.0 = Debug|Any CPU + {31E9DC70-5889-4BA5-A5BA-FFDE66AFF314}.Release|Any CPU.ActiveCfg = Release|Any CPU + {31E9DC70-5889-4BA5-A5BA-FFDE66AFF314}.Release|Any CPU.Build.0 = Release|Any CPU + {BA543940-3C97-410D-B66C-1B928FCBB567}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BA543940-3C97-410D-B66C-1B928FCBB567}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BA543940-3C97-410D-B66C-1B928FCBB567}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BA543940-3C97-410D-B66C-1B928FCBB567}.Release|Any CPU.Build.0 = Release|Any CPU + {51E93537-DE9A-460C-B2B6-5FCB7A616A94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {51E93537-DE9A-460C-B2B6-5FCB7A616A94}.Debug|Any CPU.Build.0 = Debug|Any CPU + {51E93537-DE9A-460C-B2B6-5FCB7A616A94}.Release|Any CPU.ActiveCfg = Release|Any CPU + {51E93537-DE9A-460C-B2B6-5FCB7A616A94}.Release|Any CPU.Build.0 = Release|Any CPU + {F57AF771-8514-4020-BBF3-1708388DD4B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F57AF771-8514-4020-BBF3-1708388DD4B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F57AF771-8514-4020-BBF3-1708388DD4B3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F57AF771-8514-4020-BBF3-1708388DD4B3}.Release|Any CPU.Build.0 = Release|Any CPU + {69F90530-ADA4-4A0C-8068-AAC5584072D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {69F90530-ADA4-4A0C-8068-AAC5584072D7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {69F90530-ADA4-4A0C-8068-AAC5584072D7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {69F90530-ADA4-4A0C-8068-AAC5584072D7}.Release|Any CPU.Build.0 = Release|Any CPU + {2344EB60-1760-4DF0-961A-FA5BE5BC47CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2344EB60-1760-4DF0-961A-FA5BE5BC47CC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2344EB60-1760-4DF0-961A-FA5BE5BC47CC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2344EB60-1760-4DF0-961A-FA5BE5BC47CC}.Release|Any CPU.Build.0 = Release|Any CPU + {202763AA-4C4C-4738-B530-93A9A1ECE578}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {202763AA-4C4C-4738-B530-93A9A1ECE578}.Debug|Any CPU.Build.0 = Debug|Any CPU + {202763AA-4C4C-4738-B530-93A9A1ECE578}.Release|Any CPU.ActiveCfg = Release|Any CPU + {202763AA-4C4C-4738-B530-93A9A1ECE578}.Release|Any CPU.Build.0 = Release|Any CPU + {13C86146-CD3C-4CD3-AB7F-7A155E222832}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {13C86146-CD3C-4CD3-AB7F-7A155E222832}.Debug|Any CPU.Build.0 = Debug|Any CPU + {13C86146-CD3C-4CD3-AB7F-7A155E222832}.Release|Any CPU.ActiveCfg = Release|Any CPU + {13C86146-CD3C-4CD3-AB7F-7A155E222832}.Release|Any CPU.Build.0 = Release|Any CPU + {0827FA85-8180-4A85-BE58-9483AC4BB3BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0827FA85-8180-4A85-BE58-9483AC4BB3BA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0827FA85-8180-4A85-BE58-9483AC4BB3BA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0827FA85-8180-4A85-BE58-9483AC4BB3BA}.Release|Any CPU.Build.0 = Release|Any CPU + {8878BCFD-AC5E-4D84-8C63-CA99DDE036EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8878BCFD-AC5E-4D84-8C63-CA99DDE036EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8878BCFD-AC5E-4D84-8C63-CA99DDE036EE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8878BCFD-AC5E-4D84-8C63-CA99DDE036EE}.Release|Any CPU.Build.0 = Release|Any CPU + {B399BCFF-82E8-4940-9CE5-B7DCDDFDC696}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B399BCFF-82E8-4940-9CE5-B7DCDDFDC696}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B399BCFF-82E8-4940-9CE5-B7DCDDFDC696}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B399BCFF-82E8-4940-9CE5-B7DCDDFDC696}.Release|Any CPU.Build.0 = Release|Any CPU + {A2A5CB83-11C7-4534-A65D-6F957B60EEFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A2A5CB83-11C7-4534-A65D-6F957B60EEFF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A2A5CB83-11C7-4534-A65D-6F957B60EEFF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A2A5CB83-11C7-4534-A65D-6F957B60EEFF}.Release|Any CPU.Build.0 = Release|Any CPU + {C517D33F-8800-405E-9D59-E1F6CA201431}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C517D33F-8800-405E-9D59-E1F6CA201431}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C517D33F-8800-405E-9D59-E1F6CA201431}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C517D33F-8800-405E-9D59-E1F6CA201431}.Release|Any CPU.Build.0 = Release|Any CPU + {9D26C2D6-CF32-4FB6-A15E-8A1455DACD69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D26C2D6-CF32-4FB6-A15E-8A1455DACD69}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D26C2D6-CF32-4FB6-A15E-8A1455DACD69}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D26C2D6-CF32-4FB6-A15E-8A1455DACD69}.Release|Any CPU.Build.0 = Release|Any CPU + {2C8DAB92-D5EB-4462-87C1-0BED75B26C54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2C8DAB92-D5EB-4462-87C1-0BED75B26C54}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2C8DAB92-D5EB-4462-87C1-0BED75B26C54}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2C8DAB92-D5EB-4462-87C1-0BED75B26C54}.Release|Any CPU.Build.0 = Release|Any CPU + {D3DBCC2D-086E-4E3A-B70A-22A79FB295CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D3DBCC2D-086E-4E3A-B70A-22A79FB295CF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D3DBCC2D-086E-4E3A-B70A-22A79FB295CF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D3DBCC2D-086E-4E3A-B70A-22A79FB295CF}.Release|Any CPU.Build.0 = Release|Any CPU + {2BA531E8-7F85-4EBF-AE97-811CD7C83EF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2BA531E8-7F85-4EBF-AE97-811CD7C83EF2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2BA531E8-7F85-4EBF-AE97-811CD7C83EF2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2BA531E8-7F85-4EBF-AE97-811CD7C83EF2}.Release|Any CPU.Build.0 = Release|Any CPU + {4E393E60-D39A-4118-8BD5-427DC72E9ACE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4E393E60-D39A-4118-8BD5-427DC72E9ACE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4E393E60-D39A-4118-8BD5-427DC72E9ACE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4E393E60-D39A-4118-8BD5-427DC72E9ACE}.Release|Any CPU.Build.0 = Release|Any CPU + {FFECD10B-FE66-4331-A915-409F5BE04480}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FFECD10B-FE66-4331-A915-409F5BE04480}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FFECD10B-FE66-4331-A915-409F5BE04480}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FFECD10B-FE66-4331-A915-409F5BE04480}.Release|Any CPU.Build.0 = Release|Any CPU + {7D290C8E-ACA7-4F03-91DF-D507FB3E2E87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7D290C8E-ACA7-4F03-91DF-D507FB3E2E87}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7D290C8E-ACA7-4F03-91DF-D507FB3E2E87}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7D290C8E-ACA7-4F03-91DF-D507FB3E2E87}.Release|Any CPU.Build.0 = Release|Any CPU + {F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {31E9DC70-5889-4BA5-A5BA-FFDE66AFF314} = {666CB1A9-562E-453A-A2C7-FD9D77CFDFDD} + {BA543940-3C97-410D-B66C-1B928FCBB567} = {666CB1A9-562E-453A-A2C7-FD9D77CFDFDD} + {51E93537-DE9A-460C-B2B6-5FCB7A616A94} = {666CB1A9-562E-453A-A2C7-FD9D77CFDFDD} + {F57AF771-8514-4020-BBF3-1708388DD4B3} = {666CB1A9-562E-453A-A2C7-FD9D77CFDFDD} + {69F90530-ADA4-4A0C-8068-AAC5584072D7} = {666CB1A9-562E-453A-A2C7-FD9D77CFDFDD} + {2344EB60-1760-4DF0-961A-FA5BE5BC47CC} = {3D1D0E04-03FD-480A-8CF8-6E01A2E28625} + {202763AA-4C4C-4738-B530-93A9A1ECE578} = {3D1D0E04-03FD-480A-8CF8-6E01A2E28625} + {13C86146-CD3C-4CD3-AB7F-7A155E222832} = {3D1D0E04-03FD-480A-8CF8-6E01A2E28625} + {0827FA85-8180-4A85-BE58-9483AC4BB3BA} = {9FB27073-61A0-4FE3-94DB-5FDDE062332F} + {8878BCFD-AC5E-4D84-8C63-CA99DDE036EE} = {9FB27073-61A0-4FE3-94DB-5FDDE062332F} + {B399BCFF-82E8-4940-9CE5-B7DCDDFDC696} = {9FB27073-61A0-4FE3-94DB-5FDDE062332F} + {A2A5CB83-11C7-4534-A65D-6F957B60EEFF} = {1A9920BA-7C8D-4BDC-8D7D-6544A71AF3CF} + {C517D33F-8800-405E-9D59-E1F6CA201431} = {1A9920BA-7C8D-4BDC-8D7D-6544A71AF3CF} + {9D26C2D6-CF32-4FB6-A15E-8A1455DACD69} = {6CEA3385-6F62-452A-8275-033A6037235D} + {2C8DAB92-D5EB-4462-87C1-0BED75B26C54} = {6CEA3385-6F62-452A-8275-033A6037235D} + {D3DBCC2D-086E-4E3A-B70A-22A79FB295CF} = {6CEA3385-6F62-452A-8275-033A6037235D} + {2BA531E8-7F85-4EBF-AE97-811CD7C83EF2} = {8712125E-14CD-4E1B-A1CE-4BDE03805942} + {4E393E60-D39A-4118-8BD5-427DC72E9ACE} = {8712125E-14CD-4E1B-A1CE-4BDE03805942} + {FFECD10B-FE66-4331-A915-409F5BE04480} = {9FB27073-61A0-4FE3-94DB-5FDDE062332F} + {7D290C8E-ACA7-4F03-91DF-D507FB3E2E87} = {3D1D0E04-03FD-480A-8CF8-6E01A2E28625} + {F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0} = {3D1D0E04-03FD-480A-8CF8-6E01A2E28625} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9AEC9B81-0222-4DE9-B642-D915C29222AC} + EndGlobalSection +EndGlobal