From ef52fd6fd07508883dce4eb002acda59f0169e59 Mon Sep 17 00:00:00 2001
From: alielie <alielie@git.com>
Date: 星期四, 23 四月 2026 10:19:33 +0800
Subject: [PATCH] 优化;

---
 Plugin.TsExecution/TsExecution.xaml.cs | 1530 ++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 1,273 insertions(+), 257 deletions(-)

diff --git a/Plugin.TsExecution/TsExecution.xaml.cs b/Plugin.TsExecution/TsExecution.xaml.cs
index 5239693..4578fdb 100644
--- a/Plugin.TsExecution/TsExecution.xaml.cs
+++ b/Plugin.TsExecution/TsExecution.xaml.cs
@@ -1,14 +1,17 @@
 锘縰sing HMI.Base;
 using HMI.Core;
+using HMI.Core.Api;
 using HMI.Core.Entity;
 using HMI.Core.Manager;
+using HMI.Core.Setting;
 using HMI.Core.Util;
-using HMI.UI;
+using HMI.MQUtil;
 using HMI.UI.Util;
 using HMI.Util;
+using log4net;
 using NationalInstruments.TestStand.Interop.API;
 using NationalInstruments.TestStand.Interop.UI.Ax;
-using Panuon.WPF.UI;
+using Plugin.TsSupport;
 using ScottPlot;
 using ScottPlot.Plottables;
 using System;
@@ -17,6 +20,7 @@
 using System.ComponentModel;
 using System.IO;
 using System.Linq;
+using System.Runtime.InteropServices;
 using System.Timers;
 using System.Windows;
 using System.Windows.Controls;
@@ -27,9 +31,8 @@
     /// <summary>
     /// UserControl1.xaml 鐨勪氦浜掗�昏緫
     /// </summary>
-    public partial class TsExecution : PluginControl
+    public partial class TsExecution : PluginMaskControl
     {
-        //private OpcInterface.OpcInterface OpcHandle = new OpcInterface.OpcInterface();
         #region TestStand浜嬩欢
         /// <summary>
         /// TS 寮曟搸
@@ -49,9 +52,12 @@
         public AxApplicationMgr AxApplicationMgr;
         private Execution execution = null;
 
+        private SequenceContext sequenceContext = null;
+
         private Chart chart;
         #endregion
 
+        public static ILog logger { get; private set; }
         private List<SingleControl> tsSockets = new List<SingleControl>();
         /// <summary>
         /// 鏍蜂欢妯″紡鐘舵��
@@ -67,6 +73,15 @@
             }
         }
 
+        private string _currentUserCode;
+
+        public string CurrentUserCode
+        {
+            get { return _currentUserCode; }
+            set { Set(ref _currentUserCode, value); }
+        }
+
+
         private bool isLoadOK = false;
         private Timer GCTimer;
 
@@ -80,14 +95,40 @@
 
         private ProductData selectedProduct;
 
+        private MSMQHelper mSMQHelper = new MSMQHelper("HMI_Alarm");
+
         public ProductData SelectedProduct
         {
             get { return selectedProduct; }
             set
             {
                 Set(ref selectedProduct, value);
+                CurrentProductModel = value?.Name;
+                if (tsSockets != null)
+                {
+                    foreach (SingleControl socket in tsSockets)
+                    {
+                        socket.RefreshProduct(value);
+                    }
+                }
                 SetTestSeqFile(value);
             }
+        }
+
+        private string currentProductModel;
+        public string CurrentProductModel
+        {
+            get => currentProductModel;
+            set
+            {
+                Set(ref currentProductModel, value);
+            }
+        }
+
+        public override void SetLogger(ILog logger)
+        {
+            base.SetLogger(logger);
+            TsExecution.logger = logger;
         }
 
         private ObservableCollection<ProductData> products;
@@ -101,8 +142,13 @@
             }
         }
 
+        public List<double> FontSizeSource { get; set; } = new List<double> {
+            10,11,12,13,14,15,16,17,18,19,20
+        };
+
         private Pie pie;
         private string CountIniPath;
+        private bool IsOptRequirePassword;
 
         private bool alarmVisiable;
         public bool AlarmVisiable
@@ -114,16 +160,150 @@
             }
         }
 
+        private bool _enableMes;
+        public bool EnableMes
+        {
+            get => _enableMes;
+            set
+            {
+                if (RequirePassword() == true)
+                {
+                    if (WriteConfig("EnableMes", value))
+                    {
+                        Set(ref _enableMes, value);
+                    }
+                }
+            }
+        }
+
+        private bool _enableCanLog;
+        public bool EnableCanLog
+        {
+            get => _enableCanLog;
+            set
+            {
+                if (WriteConfig("EnableCanLog", value))
+                {
+                    Set(ref _enableCanLog, value);
+                }
+            }
+        }
+
+        private bool _enableDebugMode;
+        public bool EnableDebugMode
+        {
+            get => _enableDebugMode;
+            set
+            {
+                if (RequirePassword() == true)
+                {
+                    if (WriteConfig("EnableDebugMode", value))
+                    {
+                        Set(ref _enableDebugMode, value);
+                    }
+                }
+            }
+        }
+
+        private bool _enableNGPause;
+        public bool EnableNGPause
+        {
+            get => _enableNGPause;
+            set
+            {
+                if (RequirePassword() == true)
+                {
+                    if (WriteConfig("EnableNGPause", value))
+                    {
+                        Set(ref _enableNGPause, value);
+                    }
+                }
+            }
+        }
+
+        private bool _enableSimpleMode;
+        public bool EnableSimpleMode
+        {
+            get => _enableSimpleMode;
+            set
+            {
+                if (WriteConfig("EnableSimpleMode", value))
+                {
+                    Set(ref _enableSimpleMode, value);
+                    foreach (var cell in tsSockets) cell.SetSimpleUI(value);
+                }
+            }
+        }
+
+        private bool _ui_showInfoDock;
+        public bool UI_ShowInfoDock
+        {
+            get => _ui_showInfoDock;
+            set
+            {
+                if (WriteConfig("UI_ShowInfoDock", value))
+                {
+                    Set(ref _ui_showInfoDock, value);
+                    detailPanel.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
+                }
+            }
+        }
+
+        private bool autoExecuteSeq;
+        public bool AutoExecuteSeq
+        {
+            get => autoExecuteSeq;
+            set
+            {
+                Set(ref autoExecuteSeq, value);
+            }
+        }
+
+        private string currentWorkorder;
+        public string CurrentWorkorder
+        {
+            get => currentWorkorder;
+            set
+            {
+                if (WriteIni("UI_CurrentWorkorder", value))
+                {
+                    Set(ref currentWorkorder, value);
+                    engine?.Globals.SetValString("StationState.WorkOrder", 1, value);
+                    engine?.CommitGlobalsToDisk(promptOnSaveConflicts: false);
+                }
+            }
+        }
+
+        private bool _DisableScanner;
+        public bool DisableScanner
+        {
+            get => _DisableScanner;
+            set
+            {
+                if (WriteConfig("DisableScanner", value))
+                {
+                    Set(ref _DisableScanner, value);
+                }
+            }
+        }
+
+        private string tsModelPath;
+        private string dataLogPath;
+        private SqliteHelper sqliteHelper;
+
+        private MQConnector mqConnector;
+        private int probeWarn;
+
         public TsExecution()
         {
             DataContext = this;
             GCTimer = new Timer();
             InitializeComponent();
+
             InitChart();
             InitTsEngine();
             //鍒濆鍖朤estStand寮曟搸
             this.InitTestStandEngine();
-
         }
 
         public override void SetBaseFolder(string folder)
@@ -132,13 +312,92 @@
             base.SetBaseFolder(folder);
         }
 
+        private void CheckSqlHelper()
+        {
+            string today = DateTime.Now.ToString("yyyyMMdd");
+            string dbPath = Path.Combine(dataLogPath, $"Data_{today}.db");
+            if (!File.Exists(dbPath))
+            {
+                SqliteHelper.CreateDatabase(dbPath);
+            }
+            if (sqliteHelper == null || sqliteHelper.DataBaseFile != dbPath)
+            {
+                sqliteHelper?.Dispose();
+                sqliteHelper = new SqliteHelper(dbPath);
+                sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS serialData (
+                    id INTEGER PRIMARY KEY AUTOINCREMENT,
+                    sn TEXT NOT NULL,
+                    model TEXT,
+                    station TEXT NOT NULL,
+                    step TEXT NOT NULL,
+                    position TEXT,
+                    limitDown TEXT,
+                    limitUp TEXT,
+                    unit TEXT,
+                    offset TEXT,
+                    value TEXT,
+                    status TEXT,
+                    finalStatus TEXT,
+                    consumeTime TEXT, 
+                    totalConsumeTime TEXT, 
+                    time DATETIME NOT NULL);");
+                sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS testResult (
+                    id INTEGER PRIMARY KEY AUTOINCREMENT,
+                    sn TEXT NOT NULL,
+                    model TEXT,
+                    station TEXT NOT NULL,
+                    position TEXT,
+                    status TEXT,
+                    result TEXT NOT NULL, 
+                    time DATETIME NOT NULL);");
+            }
+        }
+
         public override void InitFinish()
         {
             this.ReadCount(out int pass, out int fail);
             this.DisplayCount(pass, fail);
-            UpdateChart(pass, fail);
+            ReadConfig();
             InitProducts();
+            CheckSqlHelper();
             base.InitFinish();
+
+            if (ParamSetting.EnableAutoModel)
+            {
+                selectModelPanel.Visibility = Visibility.Collapsed;
+                autoModelPanel.Visibility = Visibility.Visible;
+                CurrentProductModel = string.Empty;
+            }
+
+            try
+            {
+                UserInfo user = UserInfo.User;
+                CurrentUserCode = user?.Code;
+                engine?.Globals.SetValString("StationState.OPID", 1, CurrentUserCode);
+                engine?.CommitGlobalsToDisk(promptOnSaveConflicts: false);
+            }
+            catch (Exception ex)
+            {
+                log.Warn("Get Login User Failed.", ex);
+            }
+        }
+
+        private void InitMQ()
+        {
+            mqConnector = new MQConnector("UI");
+            mqConnector.BeginReceive(HandleMQUI);
+        }
+
+        void HandleMQUI(string msg)
+        {
+            string[] arr = msg.Split('|');
+            int eventCode = int.Parse(arr[0]);
+            int index = int.Parse(arr[1]);
+            string strData = arr[2];
+            Dispatcher.BeginInvoke(new Action(() =>
+            {
+                HandleUIMessage(eventCode, index, strData);
+            }));
         }
 
         /// <summary>
@@ -148,25 +407,35 @@
         {
             pieChart.Plot.Axes.Frameless();
             pieChart.Plot.HideGrid();
-            pieChart.Plot.DataBackground.Color = Colors.Transparent;
+            pieChart.Plot.DataBackground.Color = ScottPlot.Colors.Transparent;
 
             var legend = pieChart.Plot.ShowLegend(Alignment.UpperRight);
             legend.Alignment = Alignment.UpperRight;
             legend.Padding = new PixelPadding(0);
-            legend.FontSize = (float)CustomFontSizeConverter.CountFontSize(20, 300, 300);
+            legend.FontSize = (float)WidthSizeConverter.CountFontSize(20, 300, 300);
             pieChart.UserInputProcessor.Disable();
             pieChart.Plot.Font.Automatic();
 
             List<PieSlice> slices = new List<PieSlice> {
-    new PieSlice() { Value = 5, FillColor = Colors.Green,
-        LabelFontSize = (float)CustomFontSizeConverter.CountFontSize(20,300,300),
+    new PieSlice() { Value = 5, FillColor = ScottPlot.Colors.Green,
+        LabelFontSize = (float)WidthSizeConverter.CountFontSize(20,300,300),
         Label = "Pass",LegendText="Pass" },
-    new PieSlice() { Value = 2, FillColor = Colors.Red,
-        LabelFontSize = (float)CustomFontSizeConverter.CountFontSize(20,300,300),
+    new PieSlice() { Value = 2, FillColor = ScottPlot.Colors.Red,
+        LabelFontSize = (float)WidthSizeConverter.CountFontSize(20,300,300),
         Label = "Fail",LegendText="Fail" } };
 
 
             pie = pieChart.Plot.Add.Pie(slices);
+        }
+
+        private bool? RequirePassword()
+        {
+            if (!IsOptRequirePassword) return true;
+            var win = new RequirePasswordWindow
+            {
+                Owner = Window.GetWindow(this)
+            };
+            return win.ShowDialog();
         }
 
         private void InitProducts()
@@ -174,17 +443,43 @@
             Products = ProductManager.GetProducts<ObservableCollection<ProductData>>();
             if (Products != null && Products.Count > 0)
             {
-                List<ParameterData> parameters =
-                    ParameterManager.GetCommonParameter<List<ParameterData>>();
-                string tmpNum = parameters?.FirstOrDefault(p => p.Name == "SocketNum")?.Value?.ToString();
-                if (!string.IsNullOrEmpty(tmpNum))
+                string lastModel = engine?.Globals.GetValString("StationState.ProductModel", 1);
+                var tempProduct = Products[0];
+                if (!string.IsNullOrEmpty(lastModel))
                 {
-                    this.socketNum = Convert.ToInt32(tmpNum);
+                    var product = Products.FirstOrDefault(p => p.Name == lastModel);
+                    if (product != null)
+                    {
+                        tempProduct = product;
+                    }
                 }
-                SelectedProduct = Products[0];
-                RefershUI();
+                SelectedProduct = tempProduct;
+            }
+            RefershUI();
+            if (tsSockets != null)
+            {
+                foreach (SingleControl socket in tsSockets)
+                {
+                    socket.RefreshProduct(SelectedProduct);
+                }
             }
             SampleStatus = false;
+        }
+
+        private bool _isTesting = false;
+        public bool IsTesting
+        {
+            get { return _isTesting; }
+            set
+            {
+                Set(ref _isTesting, value);
+                Dispatcher.Invoke(() =>
+                {
+                    BtnStartSeq.IsEnabled = !value;
+                    BtnStopSeq.IsEnabled = value;
+                    CbProduct.IsEnabled = !value;
+                });
+            }
         }
 
         /// <summary>
@@ -192,71 +487,164 @@
         /// </summary>
         private void InitTsEngine()
         {
-            AxApplicationMgr = new AxApplicationMgr();
-            AxApplicationMgr.ExitApplication += new EventHandler(this.AxApplicationMgr_ExitApplication);
-            AxApplicationMgr.UIMessageEvent +=
-                new _ApplicationMgrEvents_UIMessageEventEventHandler(this.AxApplicationMgr_UIMessageEvent);
-            AxApplicationMgr.ExecutionClosed +=
-                new _ApplicationMgrEvents_ExecutionClosedEventHandler(this.AxApplicationMgr_ExecutionClosed);
+            AxApplicationMgr = TestAppManager.GetAxApplicationMgr();
+
+
+            //AxApplicationMgr. += AxApplicationMgr_EndExecution;
+            AxApplicationMgr.EndExecution += AxApplicationMgr_EndExecution;
+
+            AxApplicationMgr.ExitApplication += this.AxApplicationMgr_ExitApplication;
+            AxApplicationMgr.UIMessageEvent += this.AxApplicationMgr_UIMessageEvent;
+            AxApplicationMgr.ExecutionClosed += this.AxApplicationMgr_ExecutionClosed;
+
             ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).BeginInit();
             host.Child = AxApplicationMgr;
             ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).EndInit();
         }
 
+        private volatile bool canSwitchModel = false;
+        private volatile Action switchAction = null;
+
+        private void AxApplicationMgr_EndExecution(object sender, _ApplicationMgrEvents_EndExecutionEvent e)
+        {
+            log.Info("AxApplicationMgr_EndExecution");
+            if (ReleaseSequenceFile())
+            {
+                IsTesting = false;
+                log.Info("Release SeqFile Success!");
+                if (canSwitchModel) switchAction?.Invoke();
+            }
+            else
+            {
+                log.Warn("Release SeqFile Fail!");
+            }
+        }
+
+        /// <summary>
+        /// 杩涚▼缁撴潫浜嬩欢
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void AxApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e)
+        {
+            //ReleaseSequenceFile();
+        }
+
         private void PluginControl_Loaded(object sender, RoutedEventArgs e)
         {
-            new MaskWindow((WindowX)Window.GetWindow(this),
-                (win) =>
+            ShowMask(() =>
+            {
+                try
                 {
-                    Dispatcher.Invoke(() =>
-                    {
-                        try
-                        {
-                            //杩炴帴OPChandle
-                            //this.OpcHandle.Connect2("127.0.0.1", 6543, 18081, out string ErrMsg, null);
-                            //鍚姩娴嬭瘯杩涚▼
-                            StartSequence();
-                            isLoadOK = true;
-                        }
-                        catch (Exception ex)
-                        {
-                            log.Error("TsExecution Loaded Failed.", ex);
-                            MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.UserControlLoadFailed")}: {ex.Message}");
-                        }
+                    //Dispatcher.Invoke(() =>
+                    //{
 
-                        try
-                        {
-                            if (Environment.Version.ToString() != this.AxApplicationMgr.GetEngine().DotNetCLRVersion)
-                                this.GCTimer.Enabled = true;
-                        }
-                        catch (Exception ex)
-                        {
-                            log.Error("TsExecution GCTimer Start Failed", ex);
-                            MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.LoadFailed")}: {ex.Message}");
-                        }
-                        finally
-                        {
-                            win.Close();
-                        }
-                        if (isLoadOK) Loaded -= PluginControl_Loaded;
-                    });
+                    //});
+                    isLoadOK = true;
+                    if (AutoExecuteSeq) StartSequence();
                 }
-                ).Info(LangUtil.Get("App.UsercontrolIsLoading"));
+                catch (Exception ex)
+                {
+                    log.Error("TsExecution Loaded Failed.", ex);
+                    MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.UserControlLoadFailed")}: {ex.Message}");
+                }
+
+                try
+                {
+                    if (Environment.Version.ToString() != this.AxApplicationMgr.GetEngine().DotNetCLRVersion)
+                        this.GCTimer.Enabled = true;
+                }
+                catch (Exception ex)
+                {
+                    log.Error("TsExecution GCTimer Start Failed", ex);
+                    MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.LoadFailed")}: {ex.Message}");
+                }
+
+                Dispatcher.Invoke(() =>
+                {
+                    if (isLoadOK) Loaded -= PluginControl_Loaded;
+                });
+            }, (ex) =>
+            {
+                ToastHelper.Error("Loaded Failed.");
+                log.Error("Loaded Error.", ex);
+            }, null, LangUtil.Get("App.UsercontrolIsLoading"));
+
+            //new MaskWindow((WindowX)Window.GetWindow(this),
+            //    (win) =>
+            //    {
+            //        try
+            //        {
+            //            Dispatcher.Invoke(() =>
+            //            {
+            //                try
+            //                {
+            //                    UserInfo user = UserInfo.User;
+            //                    CurrentUserCode = user?.Code;
+            //                }
+            //                catch (Exception ex)
+            //                {
+            //                    log.Warn("Get Login User Failed.", ex);
+            //                }
+            //            });
+            //            isLoadOK = true;
+            //            if (AutoExecuteSeq) StartSequence();
+            //        }
+            //        catch (Exception ex)
+            //        {
+            //            log.Error("TsExecution Loaded Failed.", ex);
+            //            MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.UserControlLoadFailed")}: {ex.Message}");
+            //        }
+
+            //        try
+            //        {
+            //            if (Environment.Version.ToString() != this.AxApplicationMgr.GetEngine().DotNetCLRVersion)
+            //                this.GCTimer.Enabled = true;
+            //        }
+            //        catch (Exception ex)
+            //        {
+            //            log.Error("TsExecution GCTimer Start Failed", ex);
+            //            MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.LoadFailed")}: {ex.Message}");
+            //        }
+
+            //        Dispatcher.Invoke(() =>
+            //        {
+            //            if (isLoadOK) Loaded -= PluginControl_Loaded;
+            //        });
+            //    }
+            //    ).Info(LangUtil.Get("App.UsercontrolIsLoading"));
         }
 
         private void RefershUI()
         {
             panel.Children.Clear();
+            string[] names = ParamSetting.SocketNames.Split(',');
+
             //閲嶆柊鐢熸垚瀛愰潰鏉�
             for (int i = 0; i < this.socketNum; i++)
             {
-                SingleControl control = new SingleControl(i, CountIniPath);
+                string name = string.Empty;
+                if (i < names.Length)
+                {
+                    name = names[i];
+                }
+
+                SingleControl control = new SingleControl(i, CountIniPath, this.probeWarn)
+                {
+                    SocketName = name
+                };
                 panel.Children.Add(control);
                 tsSockets.Add(control);
+
+                //createChildInNewThread(i, CountIniPath, ProbeWarn);
             }
             if (tsSockets.Count == 1)
             {
                 panel.Columns = 1;
+            }
+            else if (tsSockets.Count > 0 && (tsSockets.Count % 3) == 0)
+            {
+                panel.Columns = 3;
             }
             else
             {
@@ -276,7 +664,7 @@
                 this.AxApplicationMgr.IsEditor = true;
                 this.AxApplicationMgr.LoginOnStart = false;
                 this.AxApplicationMgr.Start();
-                this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq");
+                //this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq");
             }
             catch (Exception ex)
             {
@@ -291,11 +679,324 @@
         /// <param name="fail">涓嶅悎鏍兼暟</param>
         private void ReadCount(out int pass, out int fail)
         {
-            pass = Convert.ToInt32(IniFileHelper.ReadIniData("Count", "Pass", "", CountIniPath));
-            fail = Convert.ToInt32(IniFileHelper.ReadIniData("Count", "Fail", "", CountIniPath));
+            pass = Convert.ToInt32(IniFileHelper.ReadIniData("Count", "Pass", "0", CountIniPath));
+            fail = Convert.ToInt32(IniFileHelper.ReadIniData("Count", "Fail", "0", CountIniPath));
+            var fontSize = Convert.ToDouble(IniFileHelper.ReadIniData("Config", "TableFontSize", "12", CountIniPath));
+            this.Resources["tableFontSize"] = 20d;
+            //CbFontSize.SelectedItem = fontSize;
         }
 
-        private void WriteCount(int pass, int fail)
+        private string csvDir;
+
+        /// <summary>
+        /// 璇诲彇閰嶇疆鏂囦欢閲岀殑鍑犱釜灞炴��
+        /// </summary>
+        /// <param name="pass"></param>
+        /// <param name="fail"></param>
+        private void ReadConfig()
+        {
+            ParameterData value;
+
+
+            bool flag = false;
+            try
+            {
+                value = ParameterManager.GetCommonParameterByName("DefaultEnableMes");
+                if (value != null)
+                {
+                    flag = bool.Parse(value.Value);
+                }
+            }
+            catch
+            {
+                flag = false;
+            }
+
+            try
+            {
+                value = ParameterManager.GetCommonParameterByName("SocketNum");
+                if (value != null)
+                {
+                    this.socketNum = int.Parse(value.Value);
+                }
+            }
+            catch
+            {
+                this.socketNum = 2;
+            }
+
+            if (flag)
+            {
+                EnableMes = true;
+            }
+            else
+            {
+                try
+                {
+                    value = ParameterManager.GetCommonParameterByName("EnableMes");
+                    if (value == null)
+                    {
+                        CbEnableMes.Visibility = Visibility.Collapsed;
+                    }
+                    else
+                    {
+                        _enableMes = bool.Parse(value.Value);
+                        Set("EnableMes");
+                    }
+                }
+                catch
+                {
+                    _enableMes = false;
+                    Set("EnableMes");
+                }
+            }
+
+
+            try
+            {
+                value = ParameterManager.GetCommonParameterByName("EnableNGPause");
+                if (value == null)
+                {
+                    CbEnableNGPause.Visibility = Visibility.Collapsed;
+                }
+                else
+                {
+                    _enableNGPause = bool.Parse(value.Value);
+                    Set("EnableNGPause");
+                }
+            }
+            catch
+            {
+                _enableNGPause = false;
+                Set("EnableNGPause");
+            }
+
+            try
+            {
+                value = ParameterManager.GetCommonParameterByName("EnableDebugMode");
+                if (value == null)
+                {
+                    CbEnableDebugMode.Visibility = Visibility.Collapsed;
+                }
+                else
+                {
+                    _enableDebugMode = bool.Parse(value.Value);
+                    Set("EnableDebugMode");
+                }
+            }
+            catch
+            {
+                _enableDebugMode = false;
+                Set("EnableDebugMode");
+            }
+
+            try
+            {
+                value = ParameterManager.GetCommonParameterByName("DisableScanner");
+                if (value == null)
+                {
+                    CbDisableScanner.Visibility = Visibility.Collapsed;
+                }
+                else
+                {
+                    _DisableScanner = bool.Parse(value.Value);
+                    Set("DisableScanner");
+                }
+            }
+            catch
+            {
+                _DisableScanner = false;
+                Set("DisableScanner");
+            }
+
+            try
+            {
+                value = ParameterManager.GetCommonParameterByName("EnableCanLog");
+                _enableCanLog = bool.Parse(value.Value);
+                Set("EnableCanLog");
+            }
+            catch
+            {
+                _enableCanLog = false;
+                Set("EnableCanLog");
+            }
+
+
+            try
+            {
+                value = ParameterManager.GetCommonParameterByName("EnableSimpleMode");
+                if (value == null)
+                {
+                    CbEnableSimpleMode.Visibility = Visibility.Collapsed;
+                }
+                else
+                {
+                    EnableSimpleMode = bool.Parse(value.Value);
+                }
+            }
+            catch
+            {
+                EnableSimpleMode = false;
+            }
+
+            try
+            {
+                value = ParameterManager.GetCommonParameterByName("UI_ShowInfoDock");
+                if (value == null)
+                {
+                    CbUI_ShowInfoDock.Visibility = Visibility.Collapsed;
+                }
+                else
+                {
+                    UI_ShowInfoDock = bool.Parse(value.Value);
+                }
+            }
+            catch
+            {
+                UI_ShowInfoDock = false;
+            }
+
+            try
+            {
+                value = ParameterManager.GetCommonParameterByName("AutoExecuteSeq");
+                AutoExecuteSeq = bool.Parse(value.Value);
+            }
+            catch
+            {
+                AutoExecuteSeq = true;
+            }
+
+            try
+            {
+
+                value = ParameterManager.GetCommonParameterByName("TestReportFolder");
+                csvDir = value.Value;
+                if (!Directory.Exists(csvDir))
+                {
+                    Directory.CreateDirectory(csvDir);
+                }
+            }
+            catch
+            {
+                csvDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestReport");
+            }
+
+            try
+            {
+
+                value = ParameterManager.GetCommonParameterByName("IsOptRequirePassword");
+                IsOptRequirePassword = bool.Parse(value.Value);
+            }
+            catch
+            {
+                IsOptRequirePassword = false;
+            }
+
+            try
+            {
+
+                value = ParameterManager.GetCommonParameterByName("UI_CurrentWorkorder");
+                CurrentWorkorder = value.Value;
+            }
+            catch
+            {
+                CurrentWorkorder = string.Empty;
+            }
+
+            try
+            {
+
+                value = ParameterManager.GetCommonParameterByName("TS_ShowTitleWorkorder");
+                var boo = bool.Parse(value.Value);
+                if (boo)
+                {
+                    workorderPanel.Visibility = Visibility.Visible;
+                }
+            }
+            catch
+            {
+            }
+
+            dataLogPath = ParamSetting.DataLogFolder;
+
+            try
+            {
+
+                value = ParameterManager.GetCommonParameterByName("TsModelPath");
+                tsModelPath = value?.Value ?? @"C:\Users\Public\Documents\National Instruments\TestStand 2020 (64-bit)\Components\Models\ParallelModel.seq";
+            }
+            catch
+            {
+                //@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq"
+                tsModelPath = @"C:\Users\Public\Documents\National Instruments\TestStand 2020 (64-bit)\Components\Models\ParallelModel.seq";
+            }
+
+            try
+            {
+
+                value = ParameterManager.GetCommonParameterByName("ProbeWarn");
+                probeWarn = int.Parse(value?.Value);
+            }
+            catch
+            {
+                probeWarn = 0;
+            }
+            //Convert.ToBoolean(IniFileHelper.ReadIniData("Config", "EnableMes", "true", CountIniPath));
+            //EnableCanLog = Convert.ToBoolean(IniFileHelper.ReadIniData("Config", "EnableCanLog", "true", CountIniPath));
+            //EnableDebugMode = Convert.ToBoolean(IniFileHelper.ReadIniData("Config", "EnableDebugMode", "true", CountIniPath));
+        }
+
+        private bool WriteConfig(string name, bool value)
+        {
+            try
+            {
+                if (ParameterManager.UpdateCommonParameter(name, value, out string errMsg))
+                {
+                    foreach (var ts in tsSockets)
+                    {
+                        ts?.SequenceFileContext?.StationGlobals.SetValBoolean($"SystemSetting.{name}", 1, value);
+                        if (ts?.SequenceFileContext?.Sequence != null)
+                        {
+                            ts.SequenceFileContext.Sequence.FailureAction =
+                                value ? FailureActions.FailureAction_None : FailureActions.FailureAction_GotoCleanup;
+                        }
+                    }
+                    return true;
+                }
+                else
+                {
+                    throw new Exception(errMsg);
+                }
+            }
+            catch (Exception ex)
+            {
+                MsgBoxHelper2.Error(ex.Message);
+                return false;
+            }
+        }
+
+        private bool WriteIni(string name, object value)
+        {
+            //IniFileHelper.WriteIniData("Config", name, value.ToString(), CountIniPath);
+            try
+            {
+                if (ParameterManager.UpdateCommonParameter(name, value, out string errMsg))
+                {
+                    return true;
+                }
+                else
+                {
+                    throw new Exception(errMsg);
+                }
+            }
+            catch (Exception ex)
+            {
+                MsgBoxHelper2.Error(ex.Message);
+                return false;
+            }
+        }
+
+        private void WriteCount(double pass, double fail)
         {
             IniFileHelper.WriteIniData("Count", "Pass", pass.ToString(), CountIniPath);
             IniFileHelper.WriteIniData("Count", "Fail", fail.ToString(), CountIniPath);
@@ -306,9 +1007,9 @@
         /// </summary>
         /// <param name="pass">鍚堟牸鏁�</param>
         /// <param name="fail">涓嶅悎鏍兼暟</param>
-        private void DisplayCount(int pass, int fail)
+        private void DisplayCount(double pass, double fail)
         {
-            int total = pass + fail;
+            double total = pass + fail;
             double passRate;
             if (total == 0)
             {
@@ -322,6 +1023,11 @@
             this.TbFail.Text = fail.ToString();
             this.TbTotal.Text = total.ToString();
             this.TbPassRate.Text = string.Format("{0:0.00}", passRate) + "%";
+
+            pie.Slices[0].Value = pass;
+            pie.Slices[1].Value = fail;
+            pieChart.Refresh();
+
             WriteCount(pass, fail);
         }
 
@@ -355,78 +1061,110 @@
         /// </summary>
         private void StartSequence()
         {
-            //MaskWindow mask = new MaskWindow();
+            log.Info($"Start ATE Seq isLoadOK:{isLoadOK}");
+            if (!isLoadOK) return;
             try
             {
-                this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq");
-                this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 0, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType);
-                this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null);
-
-                Dispatcher.Invoke(() =>
-                {
-                    this.CbProduct.IsEnabled = false;
-                    this.BtnStartSeq.IsEnabled = false;
-                    this.BtnStopSeq.IsEnabled = true;
-                });
+                engine?.Globals.SetValBoolean("StationState.StopTest", 1, false);
             }
             catch (Exception ex)
             {
-                Dispatcher.Invoke(() =>
-                {
-                    log.Error("Start Sequence Failed.", ex);
-                    MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.StartSequenceFail")}: {ex.Message}");
-                });
+                log.Error("Reset StopTest Failed.", ex);
             }
-            finally
+            if (ParamSetting.EnableAutoModel)
             {
+                try
+                {
+                    var path = ParameterManager.GetCommonParameterByName<string>("CommonMainSeq", "");
+                    if (string.IsNullOrEmpty(path))
+                    {
+                        Dispatcher.Invoke(() =>
+                        {
+                            MsgBoxHelper.Error(this, $"璇峰厛璁剧疆CommonMainSeq鍙傛暟");
+                        });
+                        return;
+                    }
+                    this.testSeqFile = path;
+                    this.modeSeq = this.engine.GetSequenceFileEx(tsModelPath);
+                    this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 2, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType);
+                    this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null);
+                    IsTesting = true;
+                }
+                catch (Exception ex)
+                {
+                    Dispatcher.Invoke(() =>
+                    {
+                        log.Error("Start Sequence Failed.", ex);
+                        MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.StartSequenceFail")}: {ex.Message}");
+                    });
+                }
+            }
+            else
+            {
+                //MaskWindow mask = new MaskWindow();
+                try
+                {
+                    engine?.Globals.SetValString("StationState.ProductModel", 1, CurrentProductModel);
+                    engine?.CommitGlobalsToDisk(promptOnSaveConflicts: false);
+                    this.modeSeq = this.engine.GetSequenceFileEx(tsModelPath);
+                    this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 2, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType);
+                    this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null);
+                    IsTesting = true;
+                }
+                catch (Exception ex)
+                {
+                    Dispatcher.Invoke(() =>
+                    {
+                        log.Error("Start Sequence Failed.", ex);
+                        MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.StartSequenceFail")}: {ex.Message}");
+                    });
+                }
+                finally
+                {
 
+                }
             }
         }
 
         public void StopSequenceClick()
         {
-            new MaskWindow((WindowX)Window.GetWindow(this),
-                    (win) =>
-                    {
-                        Dispatcher.Invoke(() =>
-                        {
-                            try
-                            {
-                                StopSequence();
-                            }
-                            finally
-                            {
-                                win.Close();
-                            }
-                        });
-                    }
-                    ).Info(LangUtil.Get("App.SequenceIsStopping"));
+            canSwitchModel = false;
+            switchAction = null;
+            ShowMask(() =>
+            {
+                bool stoped = StopSequence();
+            }, null, null, LangUtil.Get("App.SequenceIsStopping"));
         }
 
         /// <summary>
         /// 鍋滄娴嬭瘯搴忓垪
         /// </summary>
-        private void StopSequence()
+        private bool StopSequence()
         {
             try
             {
-                if (this.tsSockets.Count > 0 && this.tsSockets[0]?.SequenceFileContext != null)
-                {
-                    bool val = this.tsSockets[0].SequenceFileContext.StationGlobals.Exists("StationState.StopTest", 0);
-                    if (val)
-                    {
-                        tsSockets[0].SequenceFileContext.StationGlobals.SetValBoolean("StationState.StopTest", 0, true);
-                        bool isStop = this.execution.WaitForEndEx(2000, true, null, null);
-                    }
-                }
-                this.CbProduct.IsEnabled = true;
-                this.BtnStartSeq.IsEnabled = true;
-                this.BtnStopSeq.IsEnabled = false;
+                //if (this.tsSockets.Count > 0)
+                //{
+                //    for (int i = 0; i < tsSockets.Count; i++)
+                //    {
+                //        var context = this.tsSockets[i].SequenceFileContext;
+                //        context?.StationGlobals.SetValBoolean("StationState.StopTest", 1, true);
+                //    }
+                //}
+                engine.Globals.SetValBoolean("StationState.StopTest", 1, true);
+                if (this.execution == null) return true;
+
+                //bool res = this.execution.WaitForEndEx(-1, true, null, null);
+                bool res = this.execution?.WaitForEndEx(-1, true, Type.Missing, null) == true;
+                Marshal.ReleaseComObject(this.execution);
+                this.execution = null;
+                return res;
             }
             catch (Exception ex)
             {
                 log.Error("Stop Sequence Failed.", ex);
                 MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.StopSequenceFail")}: {ex.Message}");
+                return false;
             }
         }
 
@@ -454,21 +1192,29 @@
 
         private void StartClick()
         {
-            new MaskWindow(Window.GetWindow(this),
-                (win) =>
-                {
-                    Dispatcher.Invoke(() =>
-                    {
-                        try
-                        {
-                            StartSequence();
-                        }
-                        finally
-                        {
-                            win.Close();
-                        }
-                    });
-                }).Info(LangUtil.Get("Ts.SequenceIsStarting"));
+            canSwitchModel = true;
+            ShowMask(() =>
+            {
+                StartSequence();
+            }, null, null, LangUtil.Get("Ts.SequenceIsStarting"));
+            //new MaskWindow(Window.GetWindow(this),
+            //    (win) =>
+            //    {
+            //        try
+            //        {
+            //            StartSequence();
+            //        }
+            //        catch (Exception ex) { 
+
+            //        }
+            //        finally
+            //        {
+            //            win.Dispatcher.Invoke(() =>
+            //            {
+            //                win.Close();
+            //            });
+            //        }
+            //    }).Info(LangUtil.Get("Ts.SequenceIsStarting"));
         }
 
         /// <summary>
@@ -482,28 +1228,277 @@
             //this.Close();
         }
 
-        /// <summary>
-        /// 杩涚▼缁撴潫浜嬩欢
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e"></param>
-        private void AxApplicationMgr_ExecutionClosed(object sender, NationalInstruments.TestStand.Interop.UI.Ax._ApplicationMgrEvents_ExecutionClosedEvent e)
+        public void UpdatePositionStatus(int index, string status)
         {
-            try
+            this.tsSockets[index].UpdateStatus(status);
+            this.UpdateTestCounter();
+        }
+
+        public void UpdatePositionProcessValue(int index, int value)
+        {
+            this.tsSockets[index].SetTestProcess(value);
+        }
+
+        public void PausePosition(int index)
+        {
+            this.tsSockets[index].ShowPausePanel();
+        }
+
+        public void AddTestData(int index, string data)
+        {
+            string[] TestItems = data.Split(',');
+            tsSockets[index].AddTestData(TestItems[0], TestItems[1], TestItems[2], TestItems[3],
+                TestItems[4], TestItems[5], TestItems[6]);
+        }
+
+        public void SetPositionBarcode(int index, string strData)
+        {
+            if (strData.Contains(";"))
             {
-                if (this.testSeq == null)
+                var strs = strData.Split(';');
+                this.tsSockets[index].Barcode = strs[0];
+                this.tsSockets[index].Model = strs[1];
+            }
+            else
+            {
+                this.tsSockets[index].Barcode = strData;
+            }
+        }
+
+        public void SavePositionCSV(int index, string csvPath)
+        {
+            //var time = DateTime.Now;
+            //string status = this.tsSockets[index].Status == "Passed" ? "PASS" : "FAIL";
+            //string csvPath = Path.Combine(csvDir, SelectedProduct?.Name ?? "鏈煡浜у搧", time.ToString("yyyyMMdd"), status,
+            //    $"{this.tsSockets[index].Barcode}-{time.ToString("HHmmss")}.csv");
+            this.tsSockets[index].WriteToCSV(csvPath);
+        }
+
+        public void SaveTemplateCSV(int index)
+        {
+            var time = DateTime.Now;
+            string status = this.tsSockets[index].Status == "Passed" ? "PASS" : "FAIL";
+            string csvPath = Path.Combine(csvDir, CurrentProductModel ?? "鏈煡浜у搧", time.ToString("yyyyMMdd"), status, $"{this.tsSockets[index].Barcode}-{time.ToString("HHmmss")}.csv");
+            this.tsSockets[index].WriteToCSV(csvPath);
+        }
+
+        public void SavePositionDB(int index, string status)
+        {
+            CheckSqlHelper();
+            var socket = this.tsSockets[index];
+            var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+            string snr = socket.Barcode;
+            string model = CurrentProductModel;
+
+            List<string> sqls = new List<string>();
+            foreach (var data in socket.Datasource)
+            {
+                sqls.Add($@"INSERT INTO serialData (sn,model,station,step,position,limitDown,limitUp,unit,value,status,finalStatus,consumeTime,totalConsumeTime,time) VALUES
+('{snr}','{model}','','{data.Name}','{index}','{data.LimitDown}','{data.LimitUp}','{data.Unit}','{data.Value}','{data.Result}','{socket.Status}','{data.ConsumeTime}','{socket.ElapseTime}','{time}')");
+            }
+            sqls.Add($@"INSERT INTO testResult (sn,model,station,result,time,position,status) VALUES 
+('{snr}','{model}','','{socket.Status}','{time}','{index}','{status}')");
+            sqliteHelper.ExecuteBatchSql(sqls);
+        }
+
+        private void HandleUIMessage(int eventCode, int index, string strData)
+        {
+            switch (eventCode)
+            {
+                case 10002://鏇存柊娴嬭瘯鐘舵��
+                    string status = strData;
+                    UpdatePositionStatus(index, status);
+                    break;
+
+                case 10003://鍙戦�佹祴璇曟暟鎹�
+                    AddTestData(index, strData);
+                    break;
+
+                case 10004://鍙戦�佹祴璇曡繃绋嬩俊鎭�
+                    this.tsSockets[index].CurrentStep = strData;
+                    break;
+
+                case 10005://鍒濆鍖栨祴璇曟暟鎹紝娓呯┖娴嬭瘯鏁版嵁
+                    this.tsSockets[index].IniTestData();
+                    break;
+
+                case 10006://鍙戦�佷骇鍝佹潯鐮�
+                    SetPositionBarcode(index, strData);
+                    break;
+
+                case 10007://寮�濮嬫祴璇曡鏃�
+                    tsSockets[index].ElapseTime = "Start Timing";
+                    BtnStopSeq.IsEnabled = false;
+                    break;
+
+                case 10008://鍋滄娴嬭瘯璁℃椂
+                    tsSockets[index].ElapseTime = "Stop Timing";
+                    BtnStopSeq.IsEnabled = true;
+                    break;
+
+                case 10009:
+                    // 
+                    break;
+
+                case 10010:
+
+                    //PropertyObj.SetValBoolean("Locals.MD5_Used", 0, true);
+                    //PropertyObj.SetValVariant("FileGlobals.MD5_Value", 0, MD5_DATA);
+                    //PropertyObj.SetValVariant("StationGlobals.MD5", 0, MD5_DATA);
+                    break;
+
+                case 10011:
+                    // write model
+
+                    break;
+
+                case 10012:
+                    // read model
+
+                    break;
+
+                case 10013:
+                    // read continue
+
+
+                    break;
+
+                case 10014:
+
+                    break;
+
+                case 10015:
+
+                    break;
+                case 10016://鏄剧ず3D鎷兼帴鍥剧墖
+
+                    break;
+                case 10017://鏇存柊娴嬭瘯璁℃椂锛岄拡瀵归儴鍒嗚鏃舵湁PLC瀹屾垚鐨勯」鐩�
+                    this.tsSockets[index].ElapseTime = strData;
+                    break;
+                case (int)UIMessageCodes.UIMsg_EndExecution://鎵ц缁撴潫
+                    //IsTesting = false;
+                    //this.ReleaseSequenceFile();
+                    break;
+                case 10030://鏄剧ず娴嬭瘯杩涘害
+                    int ProcessVal = Convert.ToInt32(strData);
+                    this.tsSockets[index].SetTestProcess(ProcessVal);
+                    break;
+                case 10031://瀵煎嚭CSV
+                    if (string.IsNullOrEmpty(strData))
+                    {
+                        SaveTemplateCSV(index);
+                        return;
+                    }
+                    try
+                    {
+                        string[] datas = strData.Split(';');
+                        SavePositionCSV(index, datas[0]);
+                        if (datas.Length >= 2)
+                        {
+                            SavePositionDB(index, datas[1]);
+                        }
+                        else
+                        {
+                            var sss = this.tsSockets[index].Status;
+                            SavePositionDB(index, sss);
+                        }
+                    }
+                    catch (Exception ex)
+                    {
+                        log.Warn("10031 Error.", ex);
+                        SaveTemplateCSV(index);
+                    }
+                    break;
+                case 10032://鎸変笅鏍囨殏鍋滄祴璇�
+                    this.tsSockets[index].ShowPausePanel();
+                    break;
+                case 10033:
+                    var alarm = new AlarmText
+                    {
+                        VirtualId = DateTime.Now.ToString("yyyyMMddHHmmssfff"),
+                        AlarmInfo = strData
+                    };
+                    ShowAlarm(alarm);
+                    break;
+                case 10034:
+                    CurrentProductModel = strData;
+                    break;
+                case 10035:
+                    string[] arr_10035 = strData.Split(';');
+
+                    int[][] points = new int[arr_10035.Length - 1][];
+
+                    for (int i = 1; i < arr_10035.Length; i++)
+                    {
+                        string[] strs = arr_10035[i].Split(',');
+                        points[i - 1] = new int[2] { int.Parse(strs[0]), int.Parse(strs[1]) };
+                    }
+                    this.tsSockets[index].DrawScreenPoints(int.Parse(arr_10035[0]), points);
+                    break;
+                case 10036:
+                    this.tsSockets[index].ClearScreenPoint(int.Parse(strData));
+                    break;
+                case 10099:
+                    string[] arr = strData.Split(',');
+                    if (canSwitchModel) SwitchSequenceByModel(index, arr[0], arr[1]);
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        private void SwitchSequenceByModel(int index, string model, string snr)
+        {
+            Dispatcher.Invoke(() =>
+            {
+                var target = Products.FirstOrDefault(e => e.Name == model);
+
+                ShowMask(() =>
+                {
+                    bool stoped = StopSequence();
+                    //if (stoped)
+                    //{
+                    //    IsTesting = false;
+                    //}
+                }, null, null, "鎹㈠瀷涓紝璇风◢鍚�...");
+
+                if (target == null)
+                {
+                    MsgBoxHelper2.Warn($"璇峰厛鍦ㄤ骇鍝佺鐞嗛〉闈㈤厤缃瀷鍙� [{model}] 鐨勪骇鍝佷俊鎭紒");
                     return;
-                this.engine.ReleaseSequenceFileEx(this.testSeq, 0);
-                this.engine.ReleaseSequenceFileEx(this.modeSeq, 0);
-                this.engine.UnloadAllModules();
-                this.testSeq = null;
-                this.modeSeq = null;
-            }
-            catch (Exception ex)
-            {
-                log.Error("ReleaseSequenceFileEx Failed.", ex);
-                MsgBoxHelper.Error(Window.GetWindow(this), $"{LangUtil.Get("Ts.ReleaseSequenceFileFail")}: {ex.Message}");
-            }
+                }
+
+                switchAction = () =>
+                {
+                    switchAction = null;
+                    log?.Info($"灏濊瘯鑷姩鎹㈠瀷: {switchAction}");
+                    if (canSwitchModel)
+                    {
+                        Dispatcher.Invoke(() =>
+                        {
+                            try
+                            {
+                                log?.Info("寮�濮嬭嚜鍔ㄦ崲鍨�");
+                                SelectedProduct = target;
+                                engine?.Globals.SetValString($"CacheSNR[{index}]", 1, snr);
+                                engine?.CommitGlobalsToDisk(false);
+                                StartClick();
+                            }
+                            catch (Exception ex)
+                            {
+                                log?.Error("鑷姩鎹㈠瀷澶辫触", ex);
+                            }
+                        });
+                    }
+                };
+            });
+        }
+
+        private void ShowAlarm(AlarmText alarm)
+        {
+            AlarmShowHelper.ShowAlarm(alarm);
+            mSMQHelper.Send("Alarm", $"ATE娴嬭瘯 {alarm.AlarmInfo}");
         }
 
         /// <summary>
@@ -515,100 +1510,26 @@
         {
             try
             {
-                int EventCase = Convert.ToInt32(e.uiMsg.Event);
-                int Index = Convert.ToInt16(e.uiMsg.NumericData);//SocketIndex
-                switch (EventCase)
+                int eventCode = Convert.ToInt32(e.uiMsg.Event);
+                int index = Convert.ToInt16(e.uiMsg.NumericData);//SocketIndex
+                string strData = e.uiMsg.StringData;
+
+                try
                 {
-                    case 10001://浼犻�扴ocketContext
-                        tsSockets[Index].SequenceFileContext = (SequenceContext)e.uiMsg.ActiveXData;
-                        break;
-
-                    case 10002://鏇存柊娴嬭瘯鐘舵��
-                        string status = e.uiMsg.StringData;
-                        this.tsSockets[Index].UpdateStatus(status);
-                        this.UpdateTestCounter();
-                        break;
-
-                    case 10003://鍙戦�佹祴璇曟暟鎹�
-                        string[] TestItems = e.uiMsg.StringData.Split('\t');
-                        tsSockets[Index].AddTestData(TestItems[0], TestItems[4], TestItems[1], TestItems[2], TestItems[3], TestItems[5]);
-
-                        break;
-
-                    case 10004://鍙戦�佹祴璇曡繃绋嬩俊鎭�
-                        this.tsSockets[Index].CurrentStep = e.uiMsg.StringData;
-                        break;
-
-                    case 10005://鍒濆鍖栨祴璇曟暟鎹紝娓呯┖娴嬭瘯鏁版嵁
-                        this.tsSockets[Index].IniTestData();
-                        break;
-
-                    case 10006://鍙戦�佷骇鍝佹潯鐮�
-                        this.tsSockets[Index].Barcode = e.uiMsg.StringData;
-                        break;
-
-                    case 10007://寮�濮嬫祴璇曡鏃�
-                        tsSockets[Index].ElapseTime = "Start Timing";
-                        BtnStopSeq.IsEnabled = false;
-                        break;
-
-                    case 10008://鍋滄娴嬭瘯璁℃椂
-                        tsSockets[Index].ElapseTime = "Stop Timing";
-                        BtnStopSeq.IsEnabled = true;
-                        break;
-
-                    case 10009:
-                        // 
-                        break;
-
-                    case 10010:
-
-                        //PropertyObj.SetValBoolean("Locals.MD5_Used", 0, true);
-                        //PropertyObj.SetValVariant("FileGlobals.MD5_Value", 0, MD5_DATA);
-                        //PropertyObj.SetValVariant("StationGlobals.MD5", 0, MD5_DATA);
-                        break;
-
-                    case 10011:
-                        // write model
-
-                        break;
-
-                    case 10012:
-                        // read model
-
-                        break;
-
-                    case 10013:
-                        // read continue
-
-
-                        break;
-
-                    case 10014:
-
-                        break;
-
-                    case 10015:
-
-                        break;
-                    case 10016://鏄剧ず3D鎷兼帴鍥剧墖
-
-                        break;
-                    case 10017://鏇存柊娴嬭瘯璁℃椂锛岄拡瀵归儴鍒嗚鏃舵湁PLC瀹屾垚鐨勯」鐩�
-                        this.tsSockets[Index].ElapseTime = e.uiMsg.StringData;
-                        break;
-                    case (int)UIMessageCodes.UIMsg_EndExecution://鎵ц缁撴潫
-                        this.BtnStartSeq.IsEnabled = true;
-                        this.BtnStopSeq.IsEnabled = true;
-                        // this.ReleaseSequenceFile();
-                        break;
-                    case 10030://鏄剧ず娴嬭瘯杩涘害
-                        int ProcessVal = Convert.ToInt32(e.uiMsg.StringData);
-                        this.tsSockets[Index].SetTestProcess(ProcessVal);
-                        break;
-                    default:
-                        break;
+                    log.Debug($"Event: {eventCode}, NumericData: {index}, StringData: {strData}");
                 }
+                catch
+                {
+
+                }
+                if (eventCode == 10001)
+                {
+                    sequenceContext = (SequenceContext)e.uiMsg.ActiveXData;
+
+                    tsSockets[index].SequenceFileContext = (SequenceContext)e.uiMsg.ActiveXData;
+                    return;
+                }
+                HandleUIMessage(eventCode, index, strData);
             }
             catch (Exception ex)
             {
@@ -618,29 +1539,30 @@
 
         private void UpdateTestCounter()
         {
-            int PassNum = 0;
-            int FailNum = 0;
+            double PassNum = 0;
+            double FailNum = 0;
             foreach (SingleControl socket in this.tsSockets)
             {
                 PassNum += socket.PassNum;
                 FailNum += socket.FailNum;
             }
             this.DisplayCount(PassNum, FailNum);
-            UpdateChart(PassNum, FailNum);
-        }
-
-        private void UpdateChart(int pass, int fail)
-        {
-            pie.Slices[0].Value = pass;
-            pie.Slices[1].Value = fail;
-            pieChart.Refresh();
         }
 
         private void SetTestSeqFile(ProductData product)
         {
+            if (product == null)
+            {
+                testSeqFile = null;
+                return;
+            }
             string name = product.Name;
             List<ParameterData> parameters = ProductManager.GetParametersByProductName(name);
             testSeqFile = parameters.FirstOrDefault(p => p.Name == "TestSequence")?.Value?.ToString();
+            if (AutoExecuteSeq)
+            {
+                StartSequence();
+            }
         }
 
         private void ClearNum()
@@ -649,30 +1571,124 @@
             {
                 PassAmount = 0;
                 FailAmount = 0;
-                DisplayCount(PassAmount, FailAmount);
-                UpdateChart(PassAmount, FailAmount);
                 //this.OpcHandle.DoFctWriteSingle("Count_Clear", "1", out string ErrMsg);
                 foreach (SingleControl socket in tsSockets)
                 {
                     socket.ResetCounter();
                 }
+                DisplayCount(PassAmount, FailAmount);
             }
         }
 
         public override void OnClose(object sender, CancelEventArgs e)
         {
-            StopSequence();
-            this.engine?.ReleaseSequenceFileEx(this.testSeq, 0);
-            this.engine?.ReleaseSequenceFileEx(this.modeSeq, 0);
-            this.engine?.UnloadAllModules();
-            this.testSeq = null;
-            this.modeSeq = null;
-            base.OnClose(sender, e);
+            try
+            {
+                StopSequence();
+                base.OnClose(sender, e);
+            }
+            catch (Exception ex)
+            {
+                log.Error("OnClose Error.", ex);
+            }
+        }
+
+        public override void DoClose(object sender, EventArgs e)
+        {
+            base.DoClose(sender, e);
+        }
+
+        /// <summary>
+        /// 閲婃斁鎵�鏈夌殑搴忓垪鏂囦欢
+        /// </summary>
+        private bool ReleaseSequenceFile()
+        {
+            try
+            {
+                lock (this)
+                {
+                    if (this.testSeq == null)
+                    {
+                        return true;
+                    }
+                    //execution.Abort();
+                    int count = 10;
+                    while (count > 0)
+                    {
+                        try
+                        {
+                            if (this.testSeq == null)
+                                return true;
+
+                            if (this.engine?.ReleaseSequenceFileEx(this.testSeq, 4) == true)
+                            {
+                                Marshal.ReleaseComObject(this.testSeq);
+                                this.testSeq = null;
+                                // GC.Collect();
+                            }
+                            if (this.engine?.ReleaseSequenceFileEx(this.modeSeq, 4) == true)
+                            {
+                                Marshal.ReleaseComObject(this.modeSeq);
+                                this.modeSeq = null;
+                            }
+                            this.engine?.UnloadAllModules();
+                            return this.testSeq == null && this.modeSeq == null;
+                        }
+                        catch (Exception ex)
+                        {
+                            log.Warn($"ReleaseSequenceFile In {count} Times Fail.", ex);
+                            count--;
+                            System.Threading.Thread.Sleep(1000);
+                        }
+                    }
+                    log.Warn($"ReleaseSequenceFile Failed.");
+                    return false;
+                }
+            }
+            catch (Exception ex)
+            {
+                log.Warn("ReleaseSequenceFile Error.", ex);
+                return false;
+            }
         }
 
         private void PluginControl_SizeChanged(object sender, SizeChangedEventArgs e)
         {
 
         }
+
+        private void CbFontSize_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            try
+            {
+                if (e.AddedItems != null && e.AddedItems.Count > 0)
+                {
+                    var fontSize = (double)e.AddedItems[0];
+                    this.Resources["tableFontSize"] = fontSize;
+                    IniFileHelper.WriteIniData("Config", "TableFontSize", fontSize.ToString(), CountIniPath);
+                }
+            }
+            catch
+            {
+            }
+        }
+
+        private void Label_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
+        {
+            //workOrderEditor.Focus();
+            //workOrderEditor.IsEditing = true;
+            if (RequirePassword() == true)
+            {
+                var win = new WorkOrderWin
+                {
+                    WorkOrder = CurrentWorkorder,
+                    Owner = Window.GetWindow(this)
+                };
+                if (win.ShowDialog() == true)
+                {
+                    CurrentWorkorder = win.WorkOrder;
+                }
+            }
+        }
     }
 }
\ No newline at end of file

--
Gitblit v1.9.1