From b544d5cccd76735e034c8055918a50927b437474 Mon Sep 17 00:00:00 2001
From: wenxiangchao <wenxiangchao@ihengxin.com.cn>
Date: 星期二, 10 十一月 2026 08:29:04 +0800
Subject: [PATCH] fix: 维护模式重复进入失败与按钮灰死 + Broker 并发验证用例

---
 Plugin.TsExecution/TsExecution.xaml.cs | 1056 +++++++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 784 insertions(+), 272 deletions(-)

diff --git a/Plugin.TsExecution/TsExecution.xaml.cs b/Plugin.TsExecution/TsExecution.xaml.cs
index da56cd3..06b9d39 100644
--- a/Plugin.TsExecution/TsExecution.xaml.cs
+++ b/Plugin.TsExecution/TsExecution.xaml.cs
@@ -3,15 +3,17 @@
 using HMI.Core.Api;
 using HMI.Core.Entity;
 using HMI.Core.Manager;
+using HMI.Core.Setting;
 using HMI.Core.Util;
 using HMI.MQUtil;
-using HMI.UI;
+using HMI.Simple.Util;
 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 NPOI.HSSF.UserModel;
+using NPOI.SS.UserModel;
+using OpenTap;
 using Plugin.TsSupport;
 using ScottPlot;
 using ScottPlot.Plottables;
@@ -21,42 +23,41 @@
 using System.ComponentModel;
 using System.IO;
 using System.Linq;
-using System.Timers;
 using System.Windows;
 using System.Windows.Controls;
-using System.Windows.Forms.DataVisualization.Charting;
 
 namespace Plugin.TsExecution
 {
     /// <summary>
     /// UserControl1.xaml 鐨勪氦浜掗�昏緫
     /// </summary>
-    public partial class TsExecution : PluginControl
+    public partial class TsExecution : PluginMaskControl
     {
         #region TestStand浜嬩欢
         /// <summary>
         /// TS 寮曟搸
         /// </summary>
-        private Engine engine = null;
+        //private Engine engine = null;
+
+        ///// <summary>
+        ///// 娴嬭瘯搴忓垪
+        ///// </summary>
+        //private SequenceFile testSeq = null;
+
+        ///// <summary>
+        ///// 娴嬭瘯妯″瀷搴忓垪
+        ///// </summary>
+        //private SequenceFile modeSeq = null;
+
+        //private Execution execution = null;
 
         private string testSeqFile = string.Empty;
-        /// <summary>
-        /// 娴嬭瘯搴忓垪
-        /// </summary>
-        private SequenceFile testSeq = null;
 
-        /// <summary>
-        /// 娴嬭瘯妯″瀷搴忓垪
-        /// </summary>
-        private SequenceFile modeSeq = null;
-        public AxApplicationMgr AxApplicationMgr;
-        private Execution execution = null;
-
-        private Chart chart;
+        private ITestExecutionWrapper testExecutionWrapper;
         #endregion
 
         public static ILog logger { get; private set; }
-        private List<SingleControl> tsSockets = new List<SingleControl>();
+        public List<SingleControl> tsSockets { get; private set; } = new List<SingleControl>();
         /// <summary>
         /// 鏍蜂欢妯″紡鐘舵��
         /// </summary>
@@ -81,7 +82,6 @@
 
 
         private bool isLoadOK = false;
-        private Timer GCTimer;
 
         private int PassAmount = 0;
         private int FailAmount = 0;
@@ -101,7 +101,26 @@
             set
             {
                 Set(ref selectedProduct, value);
+                CurrentProductModel = value?.Name;
+                if (tsSockets != null)
+                {
+                    foreach (SingleControl socket in tsSockets)
+                    {
+                        socket.RefreshProduct(value);
+                        // socket.RefreshProbeCount(value);
+                    }
+                }
                 SetTestSeqFile(value);
+            }
+        }
+
+        private string currentProductModel;
+        public string CurrentProductModel
+        {
+            get => currentProductModel;
+            set
+            {
+                Set(ref currentProductModel, value);
             }
         }
 
@@ -121,6 +140,10 @@
                 Set(ref products, value);
             }
         }
+
+        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;
@@ -158,9 +181,12 @@
             get => _enableCanLog;
             set
             {
-                if (WriteConfig("EnableCanLog", value))
+                if (RequirePassword() == true)
                 {
-                    Set(ref _enableCanLog, value);
+                    if (WriteConfig("EnableCanLog", value))
+                    {
+                        Set(ref _enableCanLog, value);
+                    }
                 }
             }
         }
@@ -203,10 +229,13 @@
             get => _enableSimpleMode;
             set
             {
-                if (WriteConfig("EnableSimpleMode", value))
+                if (RequirePassword() == true)
                 {
-                    Set(ref _enableSimpleMode, value);
-                    foreach (var cell in tsSockets) cell.SetSimpleUI(value);
+                    if (WriteConfig("EnableSimpleMode", value))
+                    {
+                        Set(ref _enableSimpleMode, value);
+                        foreach (var cell in tsSockets) cell.SetSimpleUI(value);
+                    }
                 }
             }
         }
@@ -217,10 +246,13 @@
             get => _ui_showInfoDock;
             set
             {
-                if (WriteConfig("UI_ShowInfoDock", value))
+                if (RequirePassword() == true)
                 {
-                    Set(ref _ui_showInfoDock, value);
-                    detailPanel.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
+                    if (WriteConfig("UI_ShowInfoDock", value))
+                    {
+                        Set(ref _ui_showInfoDock, value);
+                        detailPanel.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
+                    }
                 }
             }
         }
@@ -244,6 +276,8 @@
                 if (WriteIni("UI_CurrentWorkorder", value))
                 {
                     Set(ref currentWorkorder, value);
+                    testExecutionWrapper?.SetStationGlobalValue("StationState.WorkOrder", 1, value);
+                    testExecutionWrapper?.CommitToDisk(false);
                 }
             }
         }
@@ -254,14 +288,32 @@
             get => _DisableScanner;
             set
             {
-                if (WriteConfig("DisableScanner", value))
+                if (RequirePassword() == true)
                 {
-                    Set(ref _DisableScanner, value);
+                    if (WriteConfig("DisableScanner", value))
+                    {
+                        Set(ref _DisableScanner, value);
+                    }
                 }
             }
         }
 
-        private string tsModelPath;
+        private bool enableManualDebug;
+        public bool EnableManualDebug
+        {
+            get => enableManualDebug;
+            set
+            {
+                if (IsTesting)
+                {
+                    MsgBoxHelper2.Warn("璇峰厛缁撴潫鑷姩娴嬭瘯");
+                    return;
+                }
+                Set(ref enableManualDebug, value);
+            }
+        }
+
+        public string tsModelPath { get; private set; }
         private string dataLogPath;
         private SqliteHelper sqliteHelper;
 
@@ -271,12 +323,8 @@
         public TsExecution()
         {
             DataContext = this;
-            GCTimer = new Timer();
             InitializeComponent();
             InitChart();
-            InitTsEngine();
-            //鍒濆鍖朤estStand寮曟搸
-            this.InitTestStandEngine();
         }
 
         public override void SetBaseFolder(string folder)
@@ -328,12 +376,60 @@
 
         public override void InitFinish()
         {
+            InitTsEngine();
             this.ReadCount(out int pass, out int fail);
             this.DisplayCount(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;
+
+                testExecutionWrapper?.SetStationGlobalValue("StationState.OPID", 1, CurrentUserCode);
+                testExecutionWrapper?.CommitToDisk(false);
+            }
+            catch (Exception ex)
+            {
+                log.Warn("Get Login User Failed.", ex);
+            }
+            RefreshUIConfig();
+        }
+
+        /// <summary>
+        /// 鍒锋柊UI閰嶇疆
+        /// </summary>
+        private void RefreshUIConfig()
+        {
+            try
+            {
+                bool enableManualDebug = ParameterManager.GetCommonParameterByName("EnableManualDebug", false);
+                if (enableManualDebug)
+                {
+                    Cb_ManualDebug.Visibility = Visibility.Visible;
+                    EnableManualDebug = false;
+                }
+                else
+                {
+                    Cb_ManualDebug.Visibility = Visibility.Collapsed;
+                    EnableManualDebug = false;
+                }
+
+            }
+            catch (Exception ex)
+            {
+                log.Error("RefreshUIConfig Error.", ex);
+            }
         }
 
         private void InitMQ()
@@ -397,7 +493,7 @@
             Products = ProductManager.GetProducts<ObservableCollection<ProductData>>();
             if (Products != null && Products.Count > 0)
             {
-                string lastModel = engine?.Globals.GetValString("StationState.ProductModel", 1);
+                string lastModel = testExecutionWrapper?.GetStationGlobalValue<string>("StationState.ProductModel", 1);
                 var tempProduct = Products[0];
                 if (!string.IsNullOrEmpty(lastModel))
                 {
@@ -410,6 +506,13 @@
                 SelectedProduct = tempProduct;
             }
             RefershUI();
+            if (tsSockets != null)
+            {
+                foreach (SingleControl socket in tsSockets)
+                {
+                    socket.RefreshProduct(SelectedProduct);
+                }
+            }
             SampleStatus = false;
         }
 
@@ -434,25 +537,68 @@
         /// </summary>
         private void InitTsEngine()
         {
-            AxApplicationMgr = TestAppManager.GetAxApplicationMgr();
-            AxApplicationMgr.EndExecution += AxApplicationMgr_EndExecution;
-            AxApplicationMgr.ExitApplication += new EventHandler(this.AxApplicationMgr_ExitApplication);
-            AxApplicationMgr.UIMessageEvent +=
-                new _ApplicationMgrEvents_UIMessageEventEventHandler(this.AxApplicationMgr_UIMessageEvent);
-            AxApplicationMgr.ExecutionClosed +=
-                new _ApplicationMgrEvents_ExecutionClosedEventHandler(this.AxApplicationMgr_ExecutionClosed);
+            if (ParamSetting.EngineType == "Tap")
+            {
+                var wrapper = new TapWrapper();
+                wrapper.RegisteUserInput(this);
+                log.Debug($"Wrapper UI is {wrapper.ui}");
+                testExecutionWrapper = wrapper;
+            }
+            else
+            {
+                testExecutionWrapper = new TeststandWrapper();
+            }
 
-            ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).BeginInit();
-            host.Child = AxApplicationMgr;
-            ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).EndInit();
+            testExecutionWrapper.EndExecutionEvent += TestExecutionWrapper_EndExecutionEvent;
+            testExecutionWrapper.UIMessageEvent += TestExecutionWrapper_UIMessageEvent;
+            if (testExecutionWrapper is TeststandWrapper tsw)
+            {
+                var AxApplicationMgr = tsw.AxApplicationMgr;
+                ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).BeginInit();
+                host.Child = AxApplicationMgr;
+                ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).EndInit();
+            }
+            testExecutionWrapper.Init();
         }
 
-        private void AxApplicationMgr_EndExecution(object sender, _ApplicationMgrEvents_EndExecutionEvent e)
+        private void TestExecutionWrapper_UIMessageEvent(object sender, UIMessageEvent e)
+        {
+            try
+            {
+                int eventCode = Convert.ToInt32(e.EventCode);
+                int index = Convert.ToInt16(e.NumberData);//SocketIndex
+                string strData = e.StrData;
+
+                try
+                {
+                    log.Debug($"Event: {eventCode}, NumericData: {index}, StringData: {strData}");
+                }
+                catch
+                {
+
+                }
+                if (eventCode == 10001)
+                {
+                    testExecutionWrapper?.SetContext((SequenceContext)e.Data);
+                    tsSockets[index].SequenceFileContext = (SequenceContext)e.Data;
+                    return;
+                }
+                HandleUIMessage(eventCode, index, strData);
+            }
+            catch (Exception ex)
+            {
+                log.Warn("Ts Event Error.", ex);
+            }
+        }
+
+        private void TestExecutionWrapper_EndExecutionEvent(object sender, ExecutionEndEvent e)
         {
             log.Info("AxApplicationMgr_EndExecution");
             if (ReleaseSequenceFile())
             {
+                IsTesting = false;
                 log.Info("Release SeqFile Success!");
+                if (canSwitchModel) switchAction?.Invoke();
             }
             else
             {
@@ -460,70 +606,102 @@
             }
         }
 
-        /// <summary>
-        /// 杩涚▼缁撴潫浜嬩欢
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e"></param>
-        private void AxApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e)
-        {
-            //ReleaseSequenceFile();
-        }
+        private volatile bool canSwitchModel = false;
+        private volatile Action switchAction = null;
 
         private void PluginControl_Loaded(object sender, RoutedEventArgs e)
         {
-            new MaskWindow((WindowX)Window.GetWindow(this),
-                (win) =>
+            ShowMask(() =>
+            {
+                try
                 {
-                    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}");
-                    }
+                    //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}");
-                    }
-
-                    Dispatcher.Invoke(() =>
-                    {
-                        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}");
+                }
+
+                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, this.probeWarn);
+                string name = string.Empty;
+                if (i < names.Length)
+                {
+                    name = names[i];
+                }
+
+                SingleControl control = new SingleControl(i, CountIniPath, this.probeWarn)
+                {
+                    SocketName = name
+                };
+                control.parent = this;
                 panel.Children.Add(control);
                 tsSockets.Add(control);
 
@@ -533,29 +711,13 @@
             {
                 panel.Columns = 1;
             }
+            else if (tsSockets.Count > 0 && (tsSockets.Count % 3) == 0)
+            {
+                panel.Columns = 3;
+            }
             else
             {
                 panel.Columns = 2;
-            }
-        }
-
-        /// <summary>
-        /// 鍒濆鍖朤estStand寮曟搸
-        /// </summary>
-        private void InitTestStandEngine()
-        {
-            try
-            {
-                this.engine = this.AxApplicationMgr.GetEngine();
-                this.engine.PersistBreakpoints = false;
-                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");
-            }
-            catch (Exception ex)
-            {
-                throw new Exception(LangUtil.Get("Ts.InitTestStandEngineFail"), ex);
             }
         }
 
@@ -568,6 +730,9 @@
         {
             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 string csvDir;
@@ -579,7 +744,7 @@
         /// <param name="fail"></param>
         private void ReadConfig()
         {
-            ParameterData value;
+            HMI.Core.Entity.ParameterData value;
 
 
             bool flag = false;
@@ -754,7 +919,7 @@
             {
 
                 value = ParameterManager.GetCommonParameterByName("TestReportFolder");
-                csvDir = value.Value;
+                csvDir = value?.Value ?? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestReport");
                 if (!Directory.Exists(csvDir))
                 {
                     Directory.CreateDirectory(csvDir);
@@ -769,7 +934,7 @@
             {
 
                 value = ParameterManager.GetCommonParameterByName("IsOptRequirePassword");
-                IsOptRequirePassword = bool.Parse(value.Value);
+                IsOptRequirePassword = value == null ? false : bool.Parse(value.Value);
             }
             catch
             {
@@ -780,13 +945,11 @@
             {
 
                 value = ParameterManager.GetCommonParameterByName("UI_CurrentWorkorder");
-                currentWorkorder = value.Value;
-                Set("CurrentWorkorder");
+                CurrentWorkorder = value.Value;
             }
             catch
             {
-                currentWorkorder = string.Empty;
-                Set("CurrentWorkorder");
+                CurrentWorkorder = string.Empty;
             }
 
             try
@@ -803,22 +966,13 @@
             {
             }
 
-            try
-            {
-
-                value = ParameterManager.GetCommonParameterByName("TS_DataLogPath");
-                dataLogPath = value.Value;
-            }
-            catch
-            {
-                dataLogPath = Path.Combine(PathHelper.ConfigFolder, "DataBoard");
-            }
+            dataLogPath = ParamSetting.DataLogFolder;
 
             try
             {
 
                 value = ParameterManager.GetCommonParameterByName("TsModelPath");
-                tsModelPath = value.Value;
+                tsModelPath = value?.Value ?? @"C:\Users\Public\Documents\National Instruments\TestStand 2020 (64-bit)\Components\Models\ParallelModel.seq";
             }
             catch
             {
@@ -850,6 +1004,11 @@
                     foreach (var ts in tsSockets)
                     {
                         ts?.SequenceFileContext?.StationGlobals.SetValBoolean($"SystemSetting.{name}", 1, value);
+                        if (name == "EnableDebugMode" && ts?.SequenceFileContext?.Sequence != null)
+                        {
+                            ts.SequenceFileContext.Sequence.FailureAction =
+                                value ? FailureActions.FailureAction_None : FailureActions.FailureAction_GotoCleanup;
+                        }
                     }
                     return true;
                 }
@@ -951,54 +1110,81 @@
         /// </summary>
         private void StartSequence()
         {
+            log.Info($"Start ATE Seq isLoadOK:{isLoadOK}");
             if (!isLoadOK) return;
-            //MaskWindow mask = new MaskWindow();
             try
             {
-                engine?.Globals.SetValString("StationState.ProductModel", 1, SelectedProduct?.Name);
-                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;
+                testExecutionWrapper?.SetStationGlobalValue("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;
+                    testExecutionWrapper?.StartSequence(this.testSeqFile, this.tsModelPath);
+                    //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
+                {
+                    testExecutionWrapper?.SetStationGlobalValue("StationState.ProductModel", 1, CurrentProductModel);
+                    testExecutionWrapper?.CommitToDisk(false);
+                    testExecutionWrapper?.StartSequence(this.testSeqFile, this.tsModelPath);
+                    //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) =>
-                    {
-                        try
-                        {
-                            bool stoped = StopSequence();
-                            if (stoped)
-                            {
-                                IsTesting = false;
-                            }
-                        }
-                        finally
-                        {
-                            Dispatcher.Invoke(() =>
-                            {
-
-                                win.Close();
-                            });
-                        }
-                    }
-                    ).Info(LangUtil.Get("App.SequenceIsStopping"));
+            canSwitchModel = false;
+            switchAction = null;
+            ShowMask(() =>
+            {
+                bool stoped = StopSequence();
+            }, null, null, LangUtil.Get("App.SequenceIsStopping"));
         }
 
         /// <summary>
@@ -1008,23 +1194,14 @@
         {
             try
             {
-                if (this.tsSockets.Count > 0)
-                {
-                    for (int i = 0; i < tsSockets.Count; i++)
-                    {
-                        var context = this.tsSockets[i].SequenceFileContext;
-                        //bool val = context.StationGlobals.Exists("StationState.StopTest", 0);
-                        //if (val)
-                        //{
-                        //    context.StationGlobals.SetValBoolean("StationState.StopTest", 0, true);
-                        //    bool isStop = this.execution.WaitForEndEx(2000, true, null, null);
-                        //}
-                        context?.StationGlobals.SetValBoolean("StationState.StopTest", 1, true);
-                    }
-                }
-                if (this.execution == null) return true;
+                testExecutionWrapper.SetStationGlobalValue("StationState.StopTest", 1, true);
 
-                bool res = this.execution.WaitForEndEx(2000, true, null, null);
+
+                //bool res = this.execution.WaitForEndEx(-1, true, null, null);
+                bool res = this.testExecutionWrapper.WaitForExit();
+                //if (this.execution != null)
+                //    Marshal.ReleaseComObject(this.execution);
+                //this.execution = null;
                 return res;
             }
             catch (Exception ex)
@@ -1059,39 +1236,257 @@
 
         private void StartClick()
         {
-            new MaskWindow(Window.GetWindow(this),
-                (win) =>
-                {
-                    try
-                    {
-                        StartSequence();
-                    }
-                    finally
-                    {
-                        win.Dispatcher.Invoke(() =>
-                        {
-                            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) { 
 
-        /// <summary>
-        /// 閫�鍑哄簲鐢�
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e"></param>
-        private void AxApplicationMgr_ExitApplication(object sender, EventArgs e)
-        {
-            //Environment.ExitCode = this.AxApplicationMgr.ExitCode;
-            //this.Close();
+            //        }
+            //        finally
+            //        {
+            //            win.Dispatcher.Invoke(() =>
+            //            {
+            //                win.Close();
+            //            });
+            //        }
+            //    }).Info(LangUtil.Get("Ts.SequenceIsStarting"));
         }
 
         public void UpdatePositionStatus(int index, string status)
         {
-            this.tsSockets[index].UpdateStatus(status);
-            this.UpdateTestCounter();
+            Dispatcher.Invoke(() =>
+            {
+                this.tsSockets[index].UpdateStatus(status);
+                OnStatusPublished(index, status);
+                this.UpdateTestCounter();
+            });
         }
+
+        private void OnStatusPublished(int index, string status)
+        {
+            if (ParamSetting.CustomerCode != "SOUND")
+            {
+                return;
+            }
+            if (status == "Passed" || status == "Failed")
+            {
+                SaveSOUNDExcel(index, status);
+            }
+        }
+
+        private string ConvertStatus(string status)
+        {
+            if (string.Equals(status, "passed", StringComparison.OrdinalIgnoreCase))
+            {
+                return "Pass";
+            }
+            else
+            {
+                return "Fail";
+            }
+        }
+
+        #region 妗戝痉瀹氬埗
+        private ICell CreateCell(ISheet sheet, int r, int c, ICellStyle style)
+        {
+            var row = sheet.GetRow(r);
+            if (row == null)
+            {
+                row = sheet.CreateRow(r);
+            }
+            var cell = row.GetCell(c);
+            if (cell == null)
+            {
+                cell = row.CreateCell(c);
+            }
+            if (style != null)
+            {
+                cell.CellStyle = style;
+            }
+            return cell;
+        }
+
+        private string GetOutputFolder()
+        {
+            var value = ParameterManager.GetCommonParameterByName("SOUND_Output");
+            if (value != null)
+            {
+                return value.Value;
+            }
+            return ParamSetting.DataLogFolder;
+        }
+
+        private void SaveSOUNDExcel(int index, string status)
+        {
+            lock (this)
+            {
+                try
+                {
+                    string outputFolder = GetOutputFolder();
+
+                    var socket = this.tsSockets[index];
+                    DateTime testTime = DateTime.Now;
+                    string filePath = Path.Combine(outputFolder, $"{testTime.ToString("yy-MM-dd")}_{CurrentProductModel}.xls");
+                    if (!File.Exists(filePath))
+                    {
+                        Dictionary<string, int> columnMap = new Dictionary<string, int>();
+                        HSSFWorkbook workbook = new HSSFWorkbook();
+                        ISheet sheet = workbook.CreateSheet("Sheet1");
+
+                        ICellStyle border = workbook.CreateCellStyle();
+                        border.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
+                        border.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
+                        border.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
+                        border.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
+                        border.BottomBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+                        border.TopBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+                        border.LeftBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+                        border.RightBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+
+
+                        ICellStyle red = workbook.CreateCellStyle();
+                        red.CloneStyleFrom(border);
+                        red.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Red.Index;
+                        red.FillPattern = FillPattern.SolidForeground;
+
+                        ICellStyle green = workbook.CreateCellStyle();
+                        green.CloneStyleFrom(border);
+                        green.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.BrightGreen.Index;
+                        green.FillPattern = FillPattern.SolidForeground;
+
+                        CreateCell(sheet, 1, 0, border);
+                        CreateCell(sheet, 1, 1, border);
+                        CreateCell(sheet, 1, 2, border);
+                        CreateCell(sheet, 1, 3, border);
+                        CreateCell(sheet, 1, 4, border);
+
+                        CreateCell(sheet, 2, 0, border);
+                        CreateCell(sheet, 2, 1, border);
+                        CreateCell(sheet, 2, 2, border);
+                        CreateCell(sheet, 2, 3, border);
+                        CreateCell(sheet, 2, 4, border).SetCellValue("涓婇檺");
+
+                        CreateCell(sheet, 3, 0, border).SetCellValue("娴嬭瘯鏃堕棿");
+                        CreateCell(sheet, 3, 1, border).SetCellValue("娴嬭瘯浜�");
+                        CreateCell(sheet, 3, 2, border).SetCellValue("娴嬭瘯璁惧");
+                        CreateCell(sheet, 3, 3, border).SetCellValue("鏉″舰鐮�");
+                        CreateCell(sheet, 3, 4, border).SetCellValue("涓嬮檺");
+
+                        int column = 5;
+                        int row = 4;
+
+                        CreateCell(sheet, row, 0, border).SetCellValue(testTime.ToString("*HH:mm:ss*"));
+                        CreateCell(sheet, row, 1, border).SetCellValue(UserInfo.User.Name);
+                        CreateCell(sheet, row, 2, border).SetCellValue(ParamSetting.StationName);
+                        CreateCell(sheet, row, 3, border).SetCellValue(socket.Barcode);
+                        CreateCell(sheet, row, 4, status == "Passed" ? green : red).SetCellValue(ConvertStatus(status));
+
+                        foreach (var data in socket.Datasource)
+                        {
+                            int col = column;
+                            if (columnMap.ContainsKey(data.Name))
+                            {
+                                col = columnMap[data.Name];
+                            }
+                            else
+                            {
+                                columnMap[data.Name] = column++;
+                            }
+
+                            CreateCell(sheet, 1, col, border).SetCellValue(data.Name);
+                            CreateCell(sheet, 2, col, border).SetCellValue(data.LimitUp);
+                            CreateCell(sheet, 3, col, border).SetCellValue(data.LimitDown);
+                            CreateCell(sheet, row, col, data.Result == "Failed" ? red : border).SetCellValue(data.Value);
+                        }
+                        using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate))
+                        {
+                            workbook.Write(fs);
+                        }
+                    }
+                    else
+                    {
+                        using (FileStream fs = File.OpenRead(filePath))
+                        {
+                            IWorkbook workbook = new HSSFWorkbook(fs);
+                            ICellStyle border = workbook.CreateCellStyle();
+                            border.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
+                            border.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
+                            border.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
+                            border.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
+                            border.BottomBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+                            border.TopBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+                            border.LeftBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+                            border.RightBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+
+
+                            ICellStyle red = workbook.CreateCellStyle();
+                            red.CloneStyleFrom(border);
+                            red.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Red.Index;
+                            red.FillPattern = FillPattern.SolidForeground;
+
+                            ICellStyle green = workbook.CreateCellStyle();
+                            green.CloneStyleFrom(border);
+                            green.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.BrightGreen.Index;
+                            green.FillPattern = FillPattern.SolidForeground;
+
+                            ISheet sheet = workbook.GetSheet("Sheet1");
+                            Dictionary<string, int> columnMap = new Dictionary<string, int>();
+                            var titleRow = sheet.GetRow(1);
+                            for (int i = 0; i < titleRow.LastCellNum; i++)
+                            {
+                                if (!string.IsNullOrEmpty(titleRow.GetCell(i).StringCellValue))
+                                {
+                                    columnMap[titleRow.GetCell(i).StringCellValue] = i;
+                                }
+                            }
+                            int row = sheet.LastRowNum + 1;
+                            CreateCell(sheet, row, 0, border).SetCellValue(testTime.ToString("*HH:mm:ss*"));
+                            CreateCell(sheet, row, 1, border).SetCellValue(UserInfo.User.Name);
+                            CreateCell(sheet, row, 2, border).SetCellValue(ParamSetting.StationName);
+                            CreateCell(sheet, row, 3, border).SetCellValue(socket.Barcode);
+                            CreateCell(sheet, row, 4, status == "Passed" ? green : red).SetCellValue(ConvertStatus(status));
+
+                            foreach (var data in socket.Datasource)
+                            {
+                                int col = titleRow.LastCellNum;
+                                if (columnMap.ContainsKey(data.Name))
+                                {
+                                    col = columnMap[data.Name];
+                                }
+                                else
+                                {
+                                    columnMap[data.Name] = col;
+                                }
+
+                                CreateCell(sheet, 1, col, border).SetCellValue(data.Name);
+                                CreateCell(sheet, 2, col, border).SetCellValue(data.LimitUp);
+                                CreateCell(sheet, 3, col, border).SetCellValue(data.LimitDown);
+                                CreateCell(sheet, row, col, data.Result == "Failed" ? red : border).SetCellValue(data.Value);
+                            }
+                            using (FileStream nfs = new FileStream(filePath, FileMode.OpenOrCreate))
+                            {
+                                workbook.Write(nfs);
+                            }
+                        }
+                    }
+
+                }
+                catch (Exception ex)
+                {
+                    log.Error("SOUND Export Excel Data Error.", ex);
+                }
+            }
+        }
+        #endregion
 
         public void UpdatePositionProcessValue(int index, int value)
         {
@@ -1137,7 +1532,7 @@
         {
             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");
+            string csvPath = Path.Combine(csvDir, CurrentProductModel ?? "鏈煡浜у搧", time.ToString("yyyyMMdd"), status, $"{this.tsSockets[index].Barcode}-{time.ToString("HHmmss")}.csv");
             this.tsSockets[index].WriteToCSV(csvPath);
         }
 
@@ -1147,7 +1542,7 @@
             var socket = this.tsSockets[index];
             var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
             string snr = socket.Barcode;
-            string model = SelectedProduct?.Name;
+            string model = CurrentProductModel;
 
             List<string> sqls = new List<string>();
             foreach (var data in socket.Datasource)
@@ -1155,9 +1550,11 @@
                 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);
+
+            var ssql = $@"INSERT INTO testResult (sn,model,station,result,time,position,status) VALUES 
+('{snr}','{model}','','{socket.Status}','{time}','{index}','{status}')";
+            sqliteHelper.ExecuteSql(ssql);
         }
 
         private void HandleUIMessage(int eventCode, int index, string strData)
@@ -1182,17 +1579,26 @@
                     break;
 
                 case 10006://鍙戦�佷骇鍝佹潯鐮�
-                    SetPositionBarcode(index, strData);
+                    Dispatcher.Invoke(() =>
+                    {
+                        SetPositionBarcode(index, strData);
+                    });
                     break;
 
                 case 10007://寮�濮嬫祴璇曡鏃�
-                    tsSockets[index].ElapseTime = "Start Timing";
-                    BtnStopSeq.IsEnabled = false;
+                    Dispatcher.Invoke(() =>
+                    {
+                        tsSockets[index].ElapseTime = "Start Timing";
+                        BtnStopSeq.IsEnabled = false;
+                    });
                     break;
 
                 case 10008://鍋滄娴嬭瘯璁℃椂
-                    tsSockets[index].ElapseTime = "Stop Timing";
-                    BtnStopSeq.IsEnabled = true;
+                    Dispatcher.Invoke(() =>
+                    {
+                        tsSockets[index].ElapseTime = "Stop Timing";
+                        BtnStopSeq.IsEnabled = true;
+                    });
                     break;
 
                 case 10009:
@@ -1233,17 +1639,43 @@
 
                     break;
                 case 10017://鏇存柊娴嬭瘯璁℃椂锛岄拡瀵归儴鍒嗚鏃舵湁PLC瀹屾垚鐨勯」鐩�
-                    this.tsSockets[index].ElapseTime = strData;
+                    Dispatcher.Invoke(() =>
+                    {
+                        this.tsSockets[index].ElapseTime = strData;
+                    });
                     break;
                 case (int)UIMessageCodes.UIMsg_EndExecution://鎵ц缁撴潫
-                    IsTesting = false;
+                    //IsTesting = false;
                     //this.ReleaseSequenceFile();
                     break;
                 case 10030://鏄剧ず娴嬭瘯杩涘害
                     int ProcessVal = Convert.ToInt32(strData);
-                    this.tsSockets[index].SetTestProcess(ProcessVal);
+                    Dispatcher.Invoke(() =>
+                    {
+                        this.tsSockets[index].SetTestProcess(ProcessVal);
+                    });
                     break;
                 case 10031://瀵煎嚭CSV
+
+                    if (ParamSetting.CustomerCode == "SOUND")
+                    {
+                        string[] datas = strData.Split(';');
+                        this.tsSockets[index].WriteToExcel(datas[0]);
+                        if (datas.Length >= 2)
+                        {
+                            SavePositionDB(index, datas[1]);
+                        }
+                        else
+                        {
+                            Dispatcher.Invoke(() =>
+                            {
+                                var sss = this.tsSockets[index].Status;
+                                SavePositionDB(index, sss);
+                            });
+                        }
+                        return;
+                    }
+
                     if (string.IsNullOrEmpty(strData))
                     {
                         SaveTemplateCSV(index);
@@ -1259,8 +1691,11 @@
                         }
                         else
                         {
-                            var sss = this.tsSockets[index].Status;
-                            SavePositionDB(index, sss);
+                            Dispatcher.Invoke(() =>
+                            {
+                                var sss = this.tsSockets[index].Status;
+                                SavePositionDB(index, sss);
+                            });
                         }
                     }
                     catch (Exception ex)
@@ -1273,53 +1708,107 @@
                     this.tsSockets[index].ShowPausePanel();
                     break;
                 case 10033:
-                    ShowAlarm(strData);
+                    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 100350:
+                    string[] arr_100350 = strData.Split(';');
+
+                    int[][] points_0 = new int[arr_100350.Length - 1][];
+
+                    for (int i = 1; i < arr_100350.Length; i++)
+                    {
+                        if (string.IsNullOrEmpty(arr_100350[i]))
+                        {
+                            continue;
+                        }
+                        string[] strs = arr_100350[i].Split(',');
+                        points_0[i - 1] = new int[2] { int.Parse(strs[0]), int.Parse(strs[1]) };
+                    }
+                    this.tsSockets[index].DrawNewScreenPoints(int.Parse(arr_100350[0]), points_0);
+                    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 ShowAlarm(string info)
+        private void SwitchSequenceByModel(int index, string model, string snr)
         {
-            AlarmShowHelper.ShowAlarm(info);
-            mSMQHelper.Send("Alarm", $"ATE娴嬭瘯 {info}");
-        }
-
-        /// <summary>
-        /// TestStand鐢ㄦ埛浜や簰浜嬩欢
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e"></param>
-        private void AxApplicationMgr_UIMessageEvent(object sender, _ApplicationMgrEvents_UIMessageEventEvent e)
-        {
-            try
+            Dispatcher.Invoke(() =>
             {
-                int eventCode = Convert.ToInt32(e.uiMsg.Event);
-                int index = Convert.ToInt16(e.uiMsg.NumericData);//SocketIndex
-                string strData = e.uiMsg.StringData;
+                var target = Products.FirstOrDefault(e => e.Name == model);
 
-                try
+                ShowMask(() =>
                 {
-                    log.Info($"Event: {eventCode}, NumericData: {index}, StringData: {strData}");
-                }
-                catch
-                {
+                    bool stoped = StopSequence();
+                    //if (stoped)
+                    //{
+                    //    IsTesting = false;
+                    //}
+                }, null, null, "鎹㈠瀷涓紝璇风◢鍚�...");
 
-                }
-                if (eventCode == 10001)
+                if (target == null)
                 {
-                    tsSockets[index].SequenceFileContext = (SequenceContext)e.uiMsg.ActiveXData;
+                    MsgBoxHelper2.Warn($"璇峰厛鍦ㄤ骇鍝佺鐞嗛〉闈㈤厤缃瀷鍙� [{model}] 鐨勪骇鍝佷俊鎭紒");
                     return;
                 }
-                HandleUIMessage(eventCode, index, strData);
-            }
-            catch (Exception ex)
-            {
-                log.Warn("Ts Event Error.", ex);
-            }
+
+                switchAction = () =>
+                {
+                    switchAction = null;
+                    log?.Info($"灏濊瘯鑷姩鎹㈠瀷: {switchAction}");
+                    if (canSwitchModel)
+                    {
+                        Dispatcher.Invoke(() =>
+                        {
+                            try
+                            {
+                                log?.Info("寮�濮嬭嚜鍔ㄦ崲鍨�");
+                                SelectedProduct = target;
+                                testExecutionWrapper?.SetStationGlobalValue($"CacheSNR[{index}]", 1, snr);
+                                testExecutionWrapper?.CommitToDisk(false);
+                                StartClick();
+                            }
+                            catch (Exception ex)
+                            {
+                                log?.Error("鑷姩鎹㈠瀷澶辫触", ex);
+                            }
+                        });
+                    }
+                };
+            });
+        }
+
+        private void ShowAlarm(AlarmText alarm)
+        {
+            AlarmShowHelper.ShowAlarm(alarm);
+            mSMQHelper.Send("Alarm", "PC", $"ATE娴嬭瘯 {alarm.AlarmInfo}", 2);
         }
 
         private void UpdateTestCounter()
@@ -1342,7 +1831,7 @@
                 return;
             }
             string name = product.Name;
-            List<ParameterData> parameters = ProductManager.GetParametersByProductName(name);
+            List<HMI.Core.Entity.ParameterData> parameters = ProductManager.GetParametersByProductName(name);
             testSeqFile = parameters.FirstOrDefault(p => p.Name == "TestSequence")?.Value?.ToString();
             if (AutoExecuteSeq)
             {
@@ -1380,6 +1869,7 @@
 
         public override void DoClose(object sender, EventArgs e)
         {
+            testExecutionWrapper?.Dispose();
             base.DoClose(sender, e);
         }
 
@@ -1398,19 +1888,7 @@
                     {
                         try
                         {
-                            if (this.testSeq == null)
-                                return true;
-
-                            if (this.engine.ReleaseSequenceFileEx(this.testSeq, 4))
-                            {
-                                this.testSeq = null;
-                            }
-                            if (this.engine.ReleaseSequenceFileEx(this.modeSeq, 4))
-                            {
-                                this.modeSeq = null;
-                            }
-                            this.engine.UnloadAllModules();
-                            return this.testSeq == null && this.modeSeq == null;
+                            return testExecutionWrapper.ReleaseSeqFile();
                         }
                         catch (Exception ex)
                         {
@@ -1434,5 +1912,39 @@
         {
 
         }
+
+        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