alielie
2026-06-15 f08871fe7d148d667f2f11f80f64de71a0d9504c
Plugin.TsExecution/TsExecution.xaml.cs
@@ -3,16 +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.UI.Controls;
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 Plugin.TsSupport;
using ScottPlot;
using ScottPlot.Plottables;
using System;
@@ -21,39 +22,38 @@
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;
using System.Windows.Media;
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; }
@@ -82,7 +82,6 @@
        private bool isLoadOK = false;
        private Timer GCTimer;
        private int PassAmount = 0;
        private int FailAmount = 0;
@@ -102,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);
            }
        }
@@ -122,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;
@@ -159,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);
                    }
                }
            }
        }
@@ -204,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);
                    }
                }
            }
        }
@@ -218,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;
                    }
                }
            }
        }
@@ -245,47 +276,69 @@
                if (WriteIni("UI_CurrentWorkorder", value))
                {
                    Set(ref currentWorkorder, value);
                    testExecutionWrapper?.SetStationGlobalValue("StationState.WorkOrder", 1, value);
                    testExecutionWrapper?.CommitToDisk(false);
                }
            }
        }
        private bool _DisableScanner;
        public bool DisableScanner
        {
            get => _DisableScanner;
            set
            {
                if (RequirePassword() == true)
                {
                    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();
            //初始化TestStand引擎
            this.InitTestStandEngine();
        }
        public override void SetBaseFolder(string folder)
        {
            CountIniPath = Path.Combine(folder, "Count.ini");
            base.SetBaseFolder(folder);
        }
        public override void InitFinish()
        private void CheckSqlHelper()
        {
            this.ReadCount(out int pass, out int fail);
            this.DisplayCount(pass, fail);
            InitProducts();
            ReadConfig();
            if (!File.Exists(dataLogPath))
            string today = DateTime.Now.ToString("yyyyMMdd");
            string dbPath = Path.Combine(dataLogPath, $"Data_{today}.db");
            if (!File.Exists(dbPath))
            {
                SqliteHelper.CreateDatabase(dataLogPath);
                SqliteHelper.CreateDatabase(dbPath);
            }
            sqliteHelper = new SqliteHelper(dataLogPath);
            sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS serialData (
            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,
@@ -296,7 +349,46 @@
                    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);
            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);
            }
        }
        private void InitMQ()
@@ -315,30 +407,6 @@
            {
                HandleUIMessage(eventCode, index, strData);
            }));
        }
        void createChildInNewThread(int index, string configFile, int probeWarn)
        {
            HostVisual hostVisual = new HostVisual();
            UIElement content = new VisualHost(hostVisual);
            System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(() =>
            {
                VisualTarget visualTarget = new VisualTarget(hostVisual);
                var control = new SingleControl(index, configFile, probeWarn);
                control.Arrange(new Rect(new Point(), content.RenderSize));
                visualTarget.RootVisual = control;
                tsSockets.Add(control);
                System.Windows.Threading.Dispatcher.Run();
            }));
            //panel.Children.Add(content);
            thread.SetApartmentState(System.Threading.ApartmentState.STA);
            thread.IsBackground = true;
            thread.Start();
        }
        /// <summary>
@@ -384,27 +452,25 @@
            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))
                {
                    this.socketNum = Convert.ToInt32(tmpNum);
                }
                string lastModel = engine?.Globals.GetValString("StationState.ProductModel", 1);
                string lastModel = testExecutionWrapper?.GetStationGlobalValue<string>("StationState.ProductModel", 1);
                var tempProduct = Products[0];
                if (!string.IsNullOrEmpty(lastModel))
                {
                    var product = Products.FirstOrDefault(p => p.Name == lastModel);
                    if (product != null)
                    {
                        SelectedProduct = product;
                        RefershUI();
                        return;
                        tempProduct = product;
                    }
                }
                SelectedProduct = Products[0];
                RefershUI();
                SelectedProduct = tempProduct;
            }
            RefershUI();
            if (tsSockets != null)
            {
                foreach (SingleControl socket in tsSockets)
                {
                    socket.RefreshProduct(SelectedProduct);
                }
            }
            SampleStatus = false;
        }
@@ -430,91 +496,167 @@
        /// </summary>
        private void InitTsEngine()
        {
            AxApplicationMgr = new AxApplicationMgr();
            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);
            ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).BeginInit();
            host.Child = AxApplicationMgr;
            ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).EndInit();
            if (ParamSetting.EngineType == "Tap")
            {
                testExecutionWrapper = new TapWrapper();
            }
            else
            {
                testExecutionWrapper = new TeststandWrapper();
            }
            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)
        {
            ReleaseSequenceFile();
            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
            {
                log.Warn("Release SeqFile Fail!");
            }
        }
        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()
        {
            ParameterData p = ParameterManager.GetCommonParameterByName("ProbeWarn");
            int ProbeWarn = 0;
            if (p != null)
            {
                try
                {
                    ProbeWarn = Convert.ToInt32(p.Value);
                }
                catch
                {
                    ProbeWarn = 0;
                }
            }
            panel.Children.Clear();
            string[] names = ParamSetting.SocketNames.Split(',');
            //重新生成子面板
            for (int i = 0; i < this.socketNum; i++)
            {
                SingleControl control = new SingleControl(i, CountIniPath, ProbeWarn);
                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);
@@ -524,29 +666,13 @@
            {
                panel.Columns = 1;
            }
            else if (tsSockets.Count > 0 && (tsSockets.Count % 3) == 0)
            {
                panel.Columns = 3;
            }
            else
            {
                panel.Columns = 2;
            }
        }
        /// <summary>
        /// 初始化TestStand引擎
        /// </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);
            }
        }
@@ -559,6 +685,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;
@@ -570,29 +699,118 @@
        /// <param name="fail"></param>
        private void ReadConfig()
        {
            ParameterData value;
            HMI.Core.Entity.ParameterData value;
            bool flag = false;
            try
            {
                value = ParameterManager.GetCommonParameterByName("EnableMes");
                _enableMes = bool.Parse(value.Value);
                Set("EnableMes");
                value = ParameterManager.GetCommonParameterByName("DefaultEnableMes");
                if (value != null)
                {
                    flag = bool.Parse(value.Value);
                }
            }
            catch
            {
                _enableMes = false;
                Set("EnableMes");
                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");
                _enableNGPause = bool.Parse(value.Value);
                Set("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
@@ -607,22 +825,18 @@
                Set("EnableCanLog");
            }
            try
            {
                value = ParameterManager.GetCommonParameterByName("EnableDebugMode");
                _enableDebugMode = bool.Parse(value.Value);
                Set("EnableDebugMode");
            }
            catch
            {
                _enableDebugMode = false;
                Set("EnableDebugMode");
            }
            try
            {
                value = ParameterManager.GetCommonParameterByName("EnableSimpleMode");
                EnableSimpleMode = bool.Parse(value.Value);
                if (value == null)
                {
                    CbEnableSimpleMode.Visibility = Visibility.Collapsed;
                }
                else
                {
                    EnableSimpleMode = bool.Parse(value.Value);
                }
            }
            catch
            {
@@ -632,7 +846,14 @@
            try
            {
                value = ParameterManager.GetCommonParameterByName("UI_ShowInfoDock");
                UI_ShowInfoDock = bool.Parse(value.Value);
                if (value == null)
                {
                    CbUI_ShowInfoDock.Visibility = Visibility.Collapsed;
                }
                else
                {
                    UI_ShowInfoDock = bool.Parse(value.Value);
                }
            }
            catch
            {
@@ -679,13 +900,11 @@
            {
                value = ParameterManager.GetCommonParameterByName("UI_CurrentWorkorder");
                currentWorkorder = value.Value;
                Set("CurrentWorkorder");
                CurrentWorkorder = value.Value;
            }
            catch
            {
                currentWorkorder = string.Empty;
                Set("CurrentWorkorder");
                CurrentWorkorder = string.Empty;
            }
            try
@@ -702,36 +921,37 @@
            {
            }
            dataLogPath = ParamSetting.DataLogFolder;
            try
            {
                value = ParameterManager.GetCommonParameterByName("TS_DataLogPath");
                dataLogPath = value.Value;
                value = ParameterManager.GetCommonParameterByName("TsModelPath");
                tsModelPath = value?.Value ?? @"C:\Users\Public\Documents\National Instruments\TestStand 2020 (64-bit)\Components\Models\ParallelModel.seq";
            }
            catch
            {
                dataLogPath = Path.Combine(PathHelper.ConfigFolder, "DataBoard", "DataLog.db");
                //@"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 void WriteToTsWhenInit()
        //{
        //    foreach (var ts in tsSockets)
        //    {
        //        ts?.SequenceFileContext?.StationGlobals.SetValBoolean($"SystemSetting.EnableMes", 1, EnableMes);
        //        ts?.SequenceFileContext?.StationGlobals.SetValBoolean($"SystemSetting.EnableNGPause", 1, EnableNGPause);
        //        ts?.SequenceFileContext?.StationGlobals.SetValBoolean($"SystemSetting.EnableCanLog", 1, EnableCanLog);
        //        ts?.SequenceFileContext?.StationGlobals.SetValBoolean($"SystemSetting.EnableDebugMode", 1, EnableDebugMode);
        //    }
        //}
        private bool WriteConfig(string name, bool value)
        {
            //IniFileHelper.WriteIniData("Config", name, value.ToString(), CountIniPath);
            try
            {
                if (ParameterManager.UpdateCommonParameter(name, value, out string errMsg))
@@ -739,6 +959,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;
                }
@@ -840,54 +1065,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(@"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);
                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>
@@ -897,23 +1149,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)
@@ -948,49 +1191,254 @@
        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();
        }
        /// <summary>
        /// 进程结束事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AxApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e)
        {
            ReleaseSequenceFile();
            //        }
            //        finally
            //        {
            //            win.Dispatcher.Invoke(() =>
            //            {
            //                win.Close();
            //            });
            //        }
            //    }).Info(LangUtil.Get("Ts.SequenceIsStarting"));
        }
        public void UpdatePositionStatus(int index, string status)
        {
            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)
        {
@@ -1009,33 +1457,56 @@
                TestItems[4], TestItems[5], TestItems[6]);
        }
        public void SetPositionBarcode(int index, string barcode)
        public void SetPositionBarcode(int index, string strData)
        {
            this.tsSockets[index].Barcode = barcode;
            if (strData.Contains(";"))
            {
                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)
        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");
            //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 SavePositionDB(int index)
        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,station,step,limitDown,limitUp,unit,value,status,finalStatus,consumeTime,totalConsumeTime,time) VALUES
('{snr}','','{data.Name}','{data.LimitDown}','{data.LimitUp}','{data.Unit}','{data.Value}','{data.Result}','{socket.Status}','{data.ConsumeTime}','{socket.ElapseTime}','{time}')");
                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}')");
            }
            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)
@@ -1114,7 +1585,7 @@
                    this.tsSockets[index].ElapseTime = strData;
                    break;
                case (int)UIMessageCodes.UIMsg_EndExecution://执行结束
                    IsTesting = false;
                    //IsTesting = false;
                    //this.ReleaseSequenceFile();
                    break;
                case 10030://显示测试进度
@@ -1122,58 +1593,159 @@
                    this.tsSockets[index].SetTestProcess(ProcessVal);
                    break;
                case 10031://导出CSV
                    SavePositionCSV(index);
                    SavePositionDB(index);
                    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);
                        return;
                    }
                    try
                    {
                        string[] datas = strData.Split(';');
                        SavePositionCSV(index, datas[0]);
                        if (datas.Length >= 2)
                        {
                            SavePositionDB(index, datas[1]);
                        }
                        else
                        {
                            Dispatcher.Invoke(() =>
                            {
                                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:
                    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()
@@ -1196,9 +1768,12 @@
                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();
            StartSequence();
            if (AutoExecuteSeq)
            {
                StartSequence();
            }
        }
        private void ClearNum()
@@ -1229,6 +1804,11 @@
            }
        }
        public override void DoClose(object sender, EventArgs e)
        {
            base.DoClose(sender, e);
        }
        /// <summary>
        /// 释放所有的序列文件
        /// </summary>
@@ -1238,18 +1818,23 @@
            {
                lock (this)
                {
                    if (this.testSeq == null)
                        return true;
                    if (this.engine.ReleaseSequenceFileEx(this.testSeq, 4))
                    //execution.Abort();
                    int count = 10;
                    while (count > 0)
                    {
                        this.testSeq = null;
                        try
                        {
                            return testExecutionWrapper.ReleaseSeqFile();
                        }
                        catch (Exception ex)
                        {
                            log.Warn($"ReleaseSequenceFile In {count} Times Fail.", ex);
                            count--;
                            System.Threading.Thread.Sleep(1000);
                        }
                    }
                    if (this.engine.ReleaseSequenceFileEx(this.modeSeq, 4))
                    {
                        this.modeSeq = null;
                    }
                    this.engine.UnloadAllModules();
                    return true;
                    log.Warn($"ReleaseSequenceFile Failed.");
                    return false;
                }
            }
            catch (Exception ex)
@@ -1263,5 +1848,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;
                }
            }
        }
    }
}