From a061384ba628a09bf4df91f50321ab22c03129aa Mon Sep 17 00:00:00 2001
From: alielie <alielie@git.com>
Date: 星期二, 18 三月 2025 20:58:36 +0800
Subject: [PATCH] Winform支持遮罩层;

---
 WPFProject/Controls/MainTabControl.xaml             |    1 
 Plugin.TestResult/app.config                        |    2 
 HMI.UI/Util/MsgBoxHelper2.cs                        |   98 ++
 WPFProject/Lang/zh-CN/ServoManage.json              |    6 
 HMI.Base/packages.config                            |    2 
 Plugin.TestResult/TestResultView.xaml.cs            |   11 
 Plugin.TsExecution/Plugin.TsExecution.csproj        |    6 
 HMI.Base/HMI.Base.csproj                            |    4 
 HMI.IOMonitor/packages.config                       |    4 
 HMI.ParameterManage/HMI.ParameterManage.csproj      |   13 
 WPFProject/Controls/WinFormHolder.xaml.cs           |   63 +
 Plugin.ServoManage/Properties/Settings.settings     |    7 
 HMI.DataViewer/HMI.DataViewer.csproj                |    6 
 WPFProject/PanuonWindow.xaml.cs                     |   11 
 HMI.LogViewer/HMI.LogViewer.csproj                  |    6 
 HMI.UI/Converter/VisibilityBoolConverter.cs         |   24 
 Plugin.ServoManage/Plugin.ServoManage.csproj        |  128 +++
 Plugin.ServoManage/packages.config                  |    6 
 HMI.Base/PluginInfo.cs                              |    4 
 HMI.ParameterManage/packages.config                 |    6 
 Plugin.ServoManage/Properties/Resources.Designer.cs |   62 +
 WPFProject/App.config                               |    4 
 HMI.UnitTest/packages.config                        |    4 
 Plugin.ServoManage/ServoManage.xaml.cs              |   39 +
 Plugin.TsExecution/TsExecution.xaml.cs              |  169 ++--
 HMI.UI/Util/ToastHelper.cs                          |   71 +
 WPFProject/App.xaml                                 |    1 
 WPFProject/packages.config                          |    4 
 WPFProject/Controls/WinFormHolder.xaml              |   13 
 HMI.UI/Style/MsgBoxStyle.xaml                       |    6 
 WPFProject/Controls/HolderForm.cs                   |   54 +
 HMI.LogViewer/packages.config                       |    4 
 HMI.Core/Api/IFolderOwner.cs                        |    4 
 HMI.Core/packages.config                            |    2 
 HMI.AlermInfoManage/packages.config                 |    4 
 Plugin.TsExecution/packages.config                  |    4 
 HMI.UI/packages.config                              |    2 
 HMI.Base/PluginControl.cs                           |   16 
 WPFProject/Controls/HolderForm.resx                 |  120 +++
 HMI.ParameterManage/SettingModal.xaml.cs            |    3 
 HMI.Core/Api/IPlugin.cs                             |   29 
 HMI.Core/HMI.Core.csproj                            |    5 
 HMI.Base/PluginLoader.cs                            |   42 
 WPFProject/WPFProject.csproj                        |   42 +
 HMI.SettingControl/packages.config                  |    4 
 HMI.Core/Api/PluginPackage.cs                       |   97 ++
 HMI.IOMonitor/HMI.IOMonitor.csproj                  |    6 
 WPFProject/TextFile1.txt                            |    1 
 HMI.UI/Style/PanuonResource.xaml                    |   10 
 WPFProject/PanuonWindow.xaml                        |    5 
 Plugin.ServoManage/ServoManage.xaml                 |  371 ++++++++++
 HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj      |    6 
 Plugin.ServoManage/Properties/Resources.resx        |  117 +++
 WPFProject/WPFProject.sln                           |   10 
 WPFProject/Controls/HolderForm.Designer.cs          |   59 +
 HMI.MenuManage/packages.config                      |    4 
 Libs/Microsoft.DwayneNeed.dll                       |    0 
 HMI.MenuManage/HMI.MenuManage.csproj                |    6 
 Libs/Microsoft.DwayneNeed.Win32.dll                 |    0 
 HMI.SettingControl/HMI.SettingControl.csproj        |    6 
 Plugin.TestResult/Plugin.TestResult.csproj          |    6 
 WPFProject/Controls/MaskControl.Designer.cs         |   36 
 WPFProject/Controls/MenuTabControl.xaml.cs          |    6 
 HMI.MenuManage/Modal/MenuModal.xaml                 |    1 
 Plugin.ServoManage/Properties/AssemblyInfo.cs       |   52 +
 WPFProject/Controls/MainTabControl.xaml.cs          |   53 +
 Plugin.TestResult/packages.config                   |    4 
 HMI.DataViewer/packages.config                      |    4 
 HMI.IOMonitor/IOMonitor.xaml.cs                     |    3 
 HMI.ParameterManage/TestItem.xaml.cs                |    3 
 WPFProject/App.xaml.cs                              |   26 
 HMI.UnitTest/HMI.UnitTest.csproj                    |    6 
 HMI.UI/Style/Colors.xaml                            |   26 
 Plugin.ServoManage/Properties/Settings.Designer.cs  |   30 
 Plugin.TestResult/DataTable.xaml.cs                 |   63 +
 HMI.UI/HMI.UI.csproj                                |    5 
 WPFProject/Controls/MaskControl.cs                  |   72 +
 77 files changed, 1,996 insertions(+), 214 deletions(-)

diff --git a/HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj b/HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj
index 4c95ddc..48cdbd1 100644
--- a/HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj
+++ b/HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj
@@ -53,8 +53,8 @@
     <Reference Include="ICSharpCode.SharpZipLib, Version=1.0.0.999, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\SharpZipLib.1.0.0\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
     </Reference>
-    <Reference Include="log4net, Version=3.0.3.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\log4net.3.0.3\lib\net462\log4net.dll</HintPath>
+    <Reference Include="log4net, Version=3.0.4.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\log4net.3.0.4\lib\net462\log4net.dll</HintPath>
     </Reference>
     <Reference Include="NPOI, Version=2.4.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\NPOI.2.4.1\lib\net45\NPOI.dll</HintPath>
@@ -69,7 +69,7 @@
       <HintPath>..\WPFProject\packages\NPOI.2.4.1\lib\net45\NPOI.OpenXmlFormats.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.2.2\lib\net472\Panuon.WPF.dll</HintPath>
+      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
diff --git a/HMI.AlermInfoManage/packages.config b/HMI.AlermInfoManage/packages.config
index bc20bca..6adf3c1 100644
--- a/HMI.AlermInfoManage/packages.config
+++ b/HMI.AlermInfoManage/packages.config
@@ -1,8 +1,8 @@
 锘�<?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="log4net" version="3.0.3" targetFramework="net472" />
+  <package id="log4net" version="3.0.4" targetFramework="net472" />
   <package id="NPOI" version="2.4.1" targetFramework="net472" />
-  <package id="Panuon.WPF" version="1.1.2.2" targetFramework="net472" />
+  <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
   <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
   <package id="SharpZipLib" version="1.0.0" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/HMI.Base/HMI.Base.csproj b/HMI.Base/HMI.Base.csproj
index efb3a2c..5203494 100644
--- a/HMI.Base/HMI.Base.csproj
+++ b/HMI.Base/HMI.Base.csproj
@@ -50,8 +50,8 @@
     <ErrorReport>prompt</ErrorReport>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="log4net, Version=3.0.3.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\log4net.3.0.3\lib\net462\log4net.dll</HintPath>
+    <Reference Include="log4net, Version=3.0.4.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\log4net.3.0.4\lib\net462\log4net.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Configuration" />
diff --git a/HMI.Base/PluginControl.cs b/HMI.Base/PluginControl.cs
index d3fee33..9239015 100644
--- a/HMI.Base/PluginControl.cs
+++ b/HMI.Base/PluginControl.cs
@@ -31,19 +31,19 @@
         protected ILog log;
         protected string BaseFolder;
 
-        public virtual object Active()
+        public virtual void Active()
         {
-            return null;
+
         }
 
-        public virtual object DeActive()
+        public virtual void DeActive()
         {
-            return null;
+
         }
 
-        public virtual object Init()
+        public virtual void Init()
         {
-            return null;
+
         }
 
         public virtual void OnTabChange(object sender, object args)
@@ -63,12 +63,12 @@
 
         public virtual void InitFinish()
         {
-            
+
         }
 
         public virtual void OnClose(object sender, CancelEventArgs e)
         {
-           
+
         }
 
         public virtual void DoClose(object sender, EventArgs e)
diff --git a/HMI.Base/PluginInfo.cs b/HMI.Base/PluginInfo.cs
index 69406e7..a756621 100644
--- a/HMI.Base/PluginInfo.cs
+++ b/HMI.Base/PluginInfo.cs
@@ -1,4 +1,5 @@
-锘縰sing System.Collections.ObjectModel;
+锘縰sing HMI.Core.Api;
+using System.Collections.ObjectModel;
 using System.Windows.Media.Imaging;
 
 namespace HMI.Base
@@ -12,6 +13,7 @@
         public bool IsFont { get; set; }
         public string Code { get; set; }
         public string Name { get; set; }
+        public string Type { get; set; }
         public string ParentCode { get; set; }
         public string DllPath { get; set; }
         public string ClassName { get; set; }
diff --git a/HMI.Base/PluginLoader.cs b/HMI.Base/PluginLoader.cs
index cf98bd3..ae11ccb 100644
--- a/HMI.Base/PluginLoader.cs
+++ b/HMI.Base/PluginLoader.cs
@@ -97,31 +97,36 @@
                         {
                             string dllPath = Path.Combine(PluginFolder, menu.DllPath);
                             Assembly ass = Assembly.LoadFrom(dllPath);
+                            var tss = ass.GetTypes();
                             Type ClassType = ass.GetType(menu.ClassName);
                             object Instance = Activator.CreateInstance(ClassType);
                             menu.Content = Instance;
                             if (Instance is IPlugin plugin)
                             {
-                                plugin.SetLogger(LogManager.GetLogger(menu.Code));
-                                string configFolder = Path.Combine(PathHelper.ConfigFolder, menu.Code);
-                                if (!Directory.Exists(configFolder))
+                            }
+                            else
+                            {
+                                plugin = new PluginPackage(Instance);
+                            }
+                            plugin.SetLogger(LogManager.GetLogger(menu.Code));
+                            string configFolder = Path.Combine(PathHelper.ConfigFolder, menu.Code);
+                            if (!Directory.Exists(configFolder))
+                            {
+                                Directory.CreateDirectory(configFolder);
+                            }
+                            plugin.SetBaseFolder(configFolder);
+                            plugin.InitFinish();
+                            pluginContainer.OnCloseEvent += plugin.OnClose;
+                            pluginContainer.DoCloseEvent += plugin.DoClose;
+                            Type SettingType = ass.GetType($"{menu.ClassName}_Setting");
+                            if (SettingType != null)
+                            {
+                                object SettingInstance = Activator.CreateInstance(SettingType);
+                                if (SettingInstance is IFolderOwner fo)
                                 {
-                                    Directory.CreateDirectory(configFolder);
+                                    fo.SetBaseFolder(configFolder);
                                 }
-                                plugin.SetBaseFolder(configFolder);
-                                plugin.InitFinish();
-                                pluginContainer.OnCloseEvent += plugin.OnClose;
-                                pluginContainer.DoCloseEvent += plugin.DoClose;
-                                Type SettingType = ass.GetType($"{menu.ClassName}_Setting");
-                                if (SettingType != null)
-                                {
-                                    object SettingInstance = Activator.CreateInstance(SettingType);
-                                    if (SettingInstance is IFolderOwner fo)
-                                    {
-                                        fo.SetBaseFolder(configFolder);
-                                    }
-                                    menu.SettingControl = SettingInstance;
-                                }
+                                menu.SettingControl = SettingInstance;
                             }
                         }
                         LoadMessageAppend?.Invoke(this,
@@ -184,6 +189,7 @@
                             {
                                 Code = dr["code"].ToString(),
                                 Name = dr["name"].ToString(),
+                                Type = dr["type"].ToString(),
                                 ParentCode = dr["parentCode"].ToString(),
                                 DllPath = dr["dllPath"].ToString(),
                                 ClassName = dr["className"].ToString(),
diff --git a/HMI.Base/packages.config b/HMI.Base/packages.config
index 4bea106..7c7a293 100644
--- a/HMI.Base/packages.config
+++ b/HMI.Base/packages.config
@@ -1,4 +1,4 @@
 锘�<?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="log4net" version="3.0.3" targetFramework="net472" />
+  <package id="log4net" version="3.0.4" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/HMI.Core/Api/IFolderOwner.cs b/HMI.Core/Api/IFolderOwner.cs
index 3079c4d..b6abc70 100644
--- a/HMI.Core/Api/IFolderOwner.cs
+++ b/HMI.Core/Api/IFolderOwner.cs
@@ -8,6 +8,10 @@
 {
     public interface IFolderOwner
     {
+        /// <summary>
+        /// 鍩虹璺緞
+        /// </summary>
+        /// <param name="folder"></param>
         void SetBaseFolder(string folder);
     }
 }
diff --git a/HMI.Core/Api/IPlugin.cs b/HMI.Core/Api/IPlugin.cs
index 3739a4e..7edfb0c 100644
--- a/HMI.Core/Api/IPlugin.cs
+++ b/HMI.Core/Api/IPlugin.cs
@@ -10,32 +10,29 @@
         /// 鍒濆鍖�
         /// </summary>
         /// <returns></returns>
-        object Init();
+        void Init();
 
         /// <summary>
-        /// 鍒濆鍖栧畬鎴愶紙鎵ц瀹屾瀯閫犲櫒锛�
+        /// 鍒濆鍖栧畬鎴愶紙鎵ц瀹屾瀯閫犲櫒锛屽苟涓旇缃ソlogger folder绛夎祫婧愪箣鍚庢墽琛岋級
         /// </summary>
         void InitFinish();
 
         /// <summary>
-        /// 鎻掍欢闈㈡澘琚縺娲绘椂鐨勬搷浣�
+        /// 鎻掍欢琚縺娲绘椂鐨勬搷浣�
         /// </summary>
         /// <returns></returns>
-        object Active();
+        void Active();
 
         /// <summary>
         /// 澶辨椿鏃剁殑鎿嶄綔
         /// </summary>
         /// <returns></returns>
-        object DeActive();
+        void DeActive();
 
         /// <summary>
-        /// 闈㈡澘鍒囨崲浜嬩欢
+        /// 鍒嗛厤鏃ュ織logger锛坙og4net锛�
         /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="args"></param>
-        void OnTabChange(object sender, object args);
-
+        /// <param name="logger"></param>
         void SetLogger(ILog logger);
 
         /// <summary>
@@ -49,5 +46,17 @@
         /// <param name="sender"></param>
         /// <param name="e"></param>
         void DoClose(object sender, EventArgs e);
+
+        /// <summary>
+        /// 闈㈡澘鍒囨崲浜嬩欢锛堥鐣欙級
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="args"></param>
+        void OnTabChange(object sender, object args);
+        /// <summary>
+        /// 鎻掍欢鍔犺浇瀹屼箣鍚庝細鍒嗛厤涓�涓矾寰勶紝鍙互瀛樻斁涓�浜涚嫭绔嬬殑鏂囦欢
+        /// </summary>
+        /// <param name="folder"></param>
+        void SetBaseFolder(string folder);
     }
 }
diff --git a/HMI.Core/Api/PluginPackage.cs b/HMI.Core/Api/PluginPackage.cs
new file mode 100644
index 0000000..f1e48ef
--- /dev/null
+++ b/HMI.Core/Api/PluginPackage.cs
@@ -0,0 +1,97 @@
+锘縰sing log4net;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Reflection;
+using System.Web.UI.WebControls;
+
+namespace HMI.Core.Api
+{
+    public class PluginPackage : IPlugin
+    {
+        public static Dictionary<object, IPlugin> Cache = new Dictionary<object, IPlugin>();
+        public static IPlugin Get(object obj)
+        {
+            if(obj is null) return null;
+            if (obj is IPlugin plugin)
+            {
+                return plugin;
+            }
+            if (Cache.ContainsKey(obj)) return Cache[obj];
+            PluginPackage pluginPackage = new PluginPackage(obj);
+            Cache.Add(obj, pluginPackage);
+            return pluginPackage;
+        }
+
+        private object Content;
+
+        private MethodInfo ActiveMethod;
+        private MethodInfo DeActiveMethod;
+        private MethodInfo DoCloseMethod;
+        private MethodInfo InitMethod;
+        private MethodInfo InitFinishMethod;
+        private MethodInfo OnCloseMethod;
+        private MethodInfo OnTabChangeMethod;
+        private MethodInfo SetBaseFolderMethod;
+        private MethodInfo SetLoggerMethod;
+
+        public PluginPackage(object content)
+        {
+            this.Content = content;
+            ActiveMethod = content.GetType().GetMethod("Active");
+            DeActiveMethod = content.GetType().GetMethod("DeActive");
+            DoCloseMethod = content.GetType().GetMethod("DoClose", new Type[] { typeof(object), typeof(EventArgs) });
+            InitMethod = content.GetType().GetMethod("Init");
+            InitFinishMethod = content.GetType().GetMethod("InitFinish");
+            OnCloseMethod = content.GetType().GetMethod("OnClose", new Type[] { typeof(object), typeof(CancelEventArgs) });
+            OnTabChangeMethod = content.GetType().GetMethod("OnTabChange", new Type[] { typeof(object), typeof(object) });
+            SetBaseFolderMethod = content.GetType().GetMethod("SetBaseFolder", new Type[] { typeof(string) });
+            SetLoggerMethod = content.GetType().GetMethod("SetLogger", new Type[] { typeof(ILog) });
+        }
+
+        public void Active()
+        {
+            ActiveMethod?.Invoke(Content, null);
+        }
+
+        public void DeActive()
+        {
+            DeActiveMethod?.Invoke(Content, null);
+        }
+
+        public void DoClose(object sender, EventArgs e)
+        {
+            DoCloseMethod?.Invoke(Content, new object[] { sender, e });
+        }
+
+        public void Init()
+        {
+            InitMethod?.Invoke(Content, null);
+        }
+
+        public void InitFinish()
+        {
+            InitFinishMethod?.Invoke(Content, null);
+        }
+
+        public void OnClose(object sender, CancelEventArgs e)
+        {
+            OnCloseMethod?.Invoke(Content, new object[] { sender, e });
+        }
+
+        public void OnTabChange(object sender, object args)
+        {
+            OnTabChangeMethod?.Invoke(Content, new object[] { sender, args });
+        }
+
+        public void SetBaseFolder(string folder)
+        {
+            SetBaseFolderMethod?.Invoke(Content, new object[] { folder });
+        }
+
+        public void SetLogger(ILog logger)
+        {
+            SetLoggerMethod?.Invoke(Content, new object[] { logger });
+        }
+    }
+}
diff --git a/HMI.Core/HMI.Core.csproj b/HMI.Core/HMI.Core.csproj
index d309f71..b090fb1 100644
--- a/HMI.Core/HMI.Core.csproj
+++ b/HMI.Core/HMI.Core.csproj
@@ -52,8 +52,8 @@
     <ErrorReport>prompt</ErrorReport>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="log4net, Version=3.0.3.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\log4net.3.0.3\lib\net462\log4net.dll</HintPath>
+    <Reference Include="log4net, Version=3.0.4.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\log4net.3.0.4\lib\net462\log4net.dll</HintPath>
     </Reference>
     <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
@@ -96,6 +96,7 @@
     <Compile Include="Api\IStep.cs" />
     <Compile Include="Api\IStepRunner.cs" />
     <Compile Include="Annotation\InitAttribute.cs" />
+    <Compile Include="Api\PluginPackage.cs" />
     <Compile Include="Entity\LangInfo.cs" />
     <Compile Include="Entity\NotifyBase.cs" />
     <Compile Include="Entity\Param.cs" />
diff --git a/HMI.Core/packages.config b/HMI.Core/packages.config
index 221f569..f573bf0 100644
--- a/HMI.Core/packages.config
+++ b/HMI.Core/packages.config
@@ -1,5 +1,5 @@
 锘�<?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="log4net" version="3.0.3" targetFramework="net472" />
+  <package id="log4net" version="3.0.4" targetFramework="net472" />
   <package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/HMI.DataViewer/HMI.DataViewer.csproj b/HMI.DataViewer/HMI.DataViewer.csproj
index a0ecded..7cd4470 100644
--- a/HMI.DataViewer/HMI.DataViewer.csproj
+++ b/HMI.DataViewer/HMI.DataViewer.csproj
@@ -53,8 +53,8 @@
     <Reference Include="ICSharpCode.SharpZipLib, Version=1.0.0.999, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\SharpZipLib.1.0.0\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
     </Reference>
-    <Reference Include="log4net, Version=3.0.3.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\log4net.3.0.3\lib\net462\log4net.dll</HintPath>
+    <Reference Include="log4net, Version=3.0.4.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\log4net.3.0.4\lib\net462\log4net.dll</HintPath>
     </Reference>
     <Reference Include="NPOI, Version=2.4.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\NPOI.2.4.1\lib\net45\NPOI.dll</HintPath>
@@ -69,7 +69,7 @@
       <HintPath>..\WPFProject\packages\NPOI.2.4.1\lib\net45\NPOI.OpenXmlFormats.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.2.2\lib\net472\Panuon.WPF.dll</HintPath>
+      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
diff --git a/HMI.DataViewer/packages.config b/HMI.DataViewer/packages.config
index bc20bca..6adf3c1 100644
--- a/HMI.DataViewer/packages.config
+++ b/HMI.DataViewer/packages.config
@@ -1,8 +1,8 @@
 锘�<?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="log4net" version="3.0.3" targetFramework="net472" />
+  <package id="log4net" version="3.0.4" targetFramework="net472" />
   <package id="NPOI" version="2.4.1" targetFramework="net472" />
-  <package id="Panuon.WPF" version="1.1.2.2" targetFramework="net472" />
+  <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
   <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
   <package id="SharpZipLib" version="1.0.0" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/HMI.IOMonitor/HMI.IOMonitor.csproj b/HMI.IOMonitor/HMI.IOMonitor.csproj
index 70a2ac8..d14ddca 100644
--- a/HMI.IOMonitor/HMI.IOMonitor.csproj
+++ b/HMI.IOMonitor/HMI.IOMonitor.csproj
@@ -53,8 +53,8 @@
     <Reference Include="ICSharpCode.SharpZipLib, Version=1.0.0.999, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\SharpZipLib.1.0.0\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
     </Reference>
-    <Reference Include="log4net, Version=3.0.3.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\log4net.3.0.3\lib\net462\log4net.dll</HintPath>
+    <Reference Include="log4net, Version=3.0.4.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\log4net.3.0.4\lib\net462\log4net.dll</HintPath>
     </Reference>
     <Reference Include="NPOI, Version=2.4.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\NPOI.2.4.1\lib\net45\NPOI.dll</HintPath>
@@ -72,7 +72,7 @@
       <HintPath>..\Libs\OpcInterface.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.2.2\lib\net472\Panuon.WPF.dll</HintPath>
+      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
diff --git a/HMI.IOMonitor/IOMonitor.xaml.cs b/HMI.IOMonitor/IOMonitor.xaml.cs
index a128ad0..fd059d9 100644
--- a/HMI.IOMonitor/IOMonitor.xaml.cs
+++ b/HMI.IOMonitor/IOMonitor.xaml.cs
@@ -416,7 +416,7 @@
             this.DataFilePath = Path.Combine(BaseFolder, "Data.xml");
         }
 
-        public override object Active()
+        public override void Active()
         {
             try
             {
@@ -454,7 +454,6 @@
                 log.Error("Active Execute Failed.", ex);
                 MsgBoxHelper.ErrorMessage(this, $"{this.lang("DIO.ActivateFailed")}: {ex.Message}");
             }
-            return null;
         }
 
         private void CollectionViewSource_Filter(object sender, System.Windows.Data.FilterEventArgs e)
diff --git a/HMI.IOMonitor/packages.config b/HMI.IOMonitor/packages.config
index bc20bca..6adf3c1 100644
--- a/HMI.IOMonitor/packages.config
+++ b/HMI.IOMonitor/packages.config
@@ -1,8 +1,8 @@
 锘�<?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="log4net" version="3.0.3" targetFramework="net472" />
+  <package id="log4net" version="3.0.4" targetFramework="net472" />
   <package id="NPOI" version="2.4.1" targetFramework="net472" />
-  <package id="Panuon.WPF" version="1.1.2.2" targetFramework="net472" />
+  <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
   <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
   <package id="SharpZipLib" version="1.0.0" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/HMI.LogViewer/HMI.LogViewer.csproj b/HMI.LogViewer/HMI.LogViewer.csproj
index cee7707..4d44e26 100644
--- a/HMI.LogViewer/HMI.LogViewer.csproj
+++ b/HMI.LogViewer/HMI.LogViewer.csproj
@@ -50,11 +50,11 @@
     <ErrorReport>prompt</ErrorReport>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="log4net, Version=3.0.3.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\log4net.3.0.3\lib\net462\log4net.dll</HintPath>
+    <Reference Include="log4net, Version=3.0.4.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\log4net.3.0.4\lib\net462\log4net.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.2.2\lib\net472\Panuon.WPF.dll</HintPath>
+      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
diff --git a/HMI.LogViewer/packages.config b/HMI.LogViewer/packages.config
index 63cdc53..21b491c 100644
--- a/HMI.LogViewer/packages.config
+++ b/HMI.LogViewer/packages.config
@@ -1,6 +1,6 @@
 锘�<?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="log4net" version="3.0.3" targetFramework="net472" />
-  <package id="Panuon.WPF" version="1.1.2.2" targetFramework="net472" />
+  <package id="log4net" version="3.0.4" targetFramework="net472" />
+  <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
   <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/HMI.MenuManage/HMI.MenuManage.csproj b/HMI.MenuManage/HMI.MenuManage.csproj
index c702947..bfdb3d1 100644
--- a/HMI.MenuManage/HMI.MenuManage.csproj
+++ b/HMI.MenuManage/HMI.MenuManage.csproj
@@ -53,14 +53,14 @@
     <Reference Include="DatabaseHelper">
       <HintPath>..\Libs\DatabaseHelper.dll</HintPath>
     </Reference>
-    <Reference Include="log4net, Version=3.0.3.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\log4net.3.0.3\lib\net462\log4net.dll</HintPath>
+    <Reference Include="log4net, Version=3.0.4.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\log4net.3.0.4\lib\net462\log4net.dll</HintPath>
     </Reference>
     <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.2.2\lib\net472\Panuon.WPF.dll</HintPath>
+      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
diff --git a/HMI.MenuManage/Modal/MenuModal.xaml b/HMI.MenuManage/Modal/MenuModal.xaml
index 00b120b..8eac944 100644
--- a/HMI.MenuManage/Modal/MenuModal.xaml
+++ b/HMI.MenuManage/Modal/MenuModal.xaml
@@ -58,6 +58,7 @@
                           Style="{StaticResource InputFormGroupStyle}" Header="{DynamicResource HMI.Menu.Type}" GroupName="MyFormGroup">
                 <ComboBox x:Name="TbType" Style="{StaticResource FormComboxStyle}">
                     <ComboBoxItem>WPF</ComboBoxItem>
+                    <ComboBoxItem>WinForm</ComboBoxItem>
                     <ComboBoxItem>LV</ComboBoxItem>
                 </ComboBox>
             </pu:FormGroup>
diff --git a/HMI.MenuManage/packages.config b/HMI.MenuManage/packages.config
index afc77a6..6f57c8f 100644
--- a/HMI.MenuManage/packages.config
+++ b/HMI.MenuManage/packages.config
@@ -1,7 +1,7 @@
 锘�<?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="log4net" version="3.0.3" targetFramework="net472" />
+  <package id="log4net" version="3.0.4" targetFramework="net472" />
   <package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" />
-  <package id="Panuon.WPF" version="1.1.2.2" targetFramework="net472" />
+  <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
   <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/HMI.ParameterManage/HMI.ParameterManage.csproj b/HMI.ParameterManage/HMI.ParameterManage.csproj
index f8c2d82..65ac66f 100644
--- a/HMI.ParameterManage/HMI.ParameterManage.csproj
+++ b/HMI.ParameterManage/HMI.ParameterManage.csproj
@@ -50,18 +50,20 @@
     <ErrorReport>prompt</ErrorReport>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="log4net">
-      <HintPath>..\WPFProject\packages\log4net.3.0.3\lib\net462\log4net.dll</HintPath>
+    <Reference Include="log4net, Version=3.0.4.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\log4net.3.0.4\lib\net462\log4net.dll</HintPath>
     </Reference>
     <Reference Include="NPOI, Version=2.4.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1" />
-    <Reference Include="Panuon.WPF">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.2.2\lib\net472\Panuon.WPF.dll</HintPath>
+    <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
-    <Reference Include="Panuon.WPF.UI">
+    <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
     </Reference>
     <Reference Include="System" />
+    <Reference Include="System.Configuration" />
     <Reference Include="System.Data" />
+    <Reference Include="System.Web" />
     <Reference Include="System.Xml" />
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="System.Core" />
@@ -152,6 +154,7 @@
       <Generator>ResXFileCodeGenerator</Generator>
       <LastGenOutput>Resources.Designer.cs</LastGenOutput>
     </EmbeddedResource>
+    <None Include="packages.config" />
     <None Include="Properties\Settings.settings">
       <Generator>SettingsSingleFileGenerator</Generator>
       <LastGenOutput>Settings.Designer.cs</LastGenOutput>
diff --git a/HMI.ParameterManage/SettingModal.xaml.cs b/HMI.ParameterManage/SettingModal.xaml.cs
index 4c19f6b..a28c106 100644
--- a/HMI.ParameterManage/SettingModal.xaml.cs
+++ b/HMI.ParameterManage/SettingModal.xaml.cs
@@ -67,7 +67,8 @@
         public bool ValidateName(object value, out string err)
         {
             err = null;
-            if (Datasource?.FirstOrDefault(e => e.Name == value.ToString()) != null)
+            var data = Datasource?.FirstOrDefault(e => e.Name == value.ToString());
+            if (data != null && data != Data)
             {
                 err = this.lang("App.MustBeUnique", this.lang("Pm.Parameter.Name"));
                 return false;
diff --git a/HMI.ParameterManage/TestItem.xaml.cs b/HMI.ParameterManage/TestItem.xaml.cs
index 96e0570..d693447 100644
--- a/HMI.ParameterManage/TestItem.xaml.cs
+++ b/HMI.ParameterManage/TestItem.xaml.cs
@@ -52,7 +52,7 @@
 
         bool isActivated;
         public static string FileFolder { get; private set; }
-        public override object Active()
+        public override void Active()
         {
             if (!isActivated)
             {
@@ -62,7 +62,6 @@
                 FileFolder = folder;
                 isActivated = true;
             }
-            return null;
         }
 
         private void Button_Click(object sender, RoutedEventArgs e)
diff --git a/HMI.ParameterManage/packages.config b/HMI.ParameterManage/packages.config
new file mode 100644
index 0000000..21b491c
--- /dev/null
+++ b/HMI.ParameterManage/packages.config
@@ -0,0 +1,6 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="log4net" version="3.0.4" targetFramework="net472" />
+  <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
+  <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
+</packages>
\ No newline at end of file
diff --git a/HMI.SettingControl/HMI.SettingControl.csproj b/HMI.SettingControl/HMI.SettingControl.csproj
index 1595ac0..ad41524 100644
--- a/HMI.SettingControl/HMI.SettingControl.csproj
+++ b/HMI.SettingControl/HMI.SettingControl.csproj
@@ -50,11 +50,11 @@
     <ErrorReport>prompt</ErrorReport>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="log4net, Version=3.0.3.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\log4net.3.0.3\lib\net462\log4net.dll</HintPath>
+    <Reference Include="log4net, Version=3.0.4.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\log4net.3.0.4\lib\net462\log4net.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.2.2\lib\net472\Panuon.WPF.dll</HintPath>
+      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
diff --git a/HMI.SettingControl/packages.config b/HMI.SettingControl/packages.config
index 63cdc53..21b491c 100644
--- a/HMI.SettingControl/packages.config
+++ b/HMI.SettingControl/packages.config
@@ -1,6 +1,6 @@
 锘�<?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="log4net" version="3.0.3" targetFramework="net472" />
-  <package id="Panuon.WPF" version="1.1.2.2" targetFramework="net472" />
+  <package id="log4net" version="3.0.4" targetFramework="net472" />
+  <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
   <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/HMI.UI/Converter/VisibilityBoolConverter.cs b/HMI.UI/Converter/VisibilityBoolConverter.cs
new file mode 100644
index 0000000..54c6626
--- /dev/null
+++ b/HMI.UI/Converter/VisibilityBoolConverter.cs
@@ -0,0 +1,24 @@
+锘縰sing System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Data;
+
+namespace HMI.UI.Converter
+{
+    public class VisibilityBoolConverter : IValueConverter
+    {
+        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (value is bool flag && flag == true)
+            {
+                return Visibility.Visible;
+            }
+            return Visibility.Collapsed;
+        }
+
+        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            return value;
+        }
+    }
+}
diff --git a/HMI.UI/HMI.UI.csproj b/HMI.UI/HMI.UI.csproj
index 4f9d89f..3255fc9 100644
--- a/HMI.UI/HMI.UI.csproj
+++ b/HMI.UI/HMI.UI.csproj
@@ -59,7 +59,7 @@
   </PropertyGroup>
   <ItemGroup>
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.2.2\lib\net472\Panuon.WPF.dll</HintPath>
+      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
@@ -80,6 +80,7 @@
     <Reference Include="PresentationFramework" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Converter\VisibilityBoolConverter.cs" />
     <Compile Include="Converter\DataGridRowFlagConverter.cs" />
     <Compile Include="Converter\DataGridRowNumberConverter.cs" />
     <Compile Include="Converter\PathImageConverter.cs" />
@@ -100,6 +101,7 @@
     <Compile Include="Util\IValueValidator.cs" />
     <Compile Include="Util\MaskHolder.cs" />
     <Compile Include="Util\MsgBoxHelper.cs" />
+    <Compile Include="Util\MsgBoxHelper2.cs" />
     <Compile Include="Util\ToastHelper.cs" />
     <Resource Include="Resources\Font\Font.xaml">
       <Generator>MSBuild:Compile</Generator>
@@ -173,6 +175,5 @@
       <Name>HMI.Core</Name>
     </ProjectReference>
   </ItemGroup>
-  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 </Project>
\ No newline at end of file
diff --git a/HMI.UI/Style/Colors.xaml b/HMI.UI/Style/Colors.xaml
index 69587ce..3bd20ff 100644
--- a/HMI.UI/Style/Colors.xaml
+++ b/HMI.UI/Style/Colors.xaml
@@ -66,8 +66,32 @@
         <GradientStop Color="#aa0e00" Offset="1"/>
     </LinearGradientBrush>
 
+    <RadialGradientBrush x:Key="Normal" GradientOrigin="0.5,0.5" 
+                             RadiusX="0.75" 
+                             RadiusY="0.75">
+        <RadialGradientBrush.GradientStops>
+            <GradientStop Color="White" Offset="0" />
+            <GradientStop Color="Gray" Offset="0.7" />
+            <GradientStop Color="Gray" Offset="1" />
+        </RadialGradientBrush.GradientStops>
+    </RadialGradientBrush>
 
+    <RadialGradientBrush x:Key="Ok" GradientOrigin="0.5,0.5" 
+                                 RadiusX="0.75" 
+                                 RadiusY="0.75">
+        <RadialGradientBrush.GradientStops>
+            <GradientStop Color="White" Offset="0" />
+            <GradientStop Color="Green" Offset="1" />
+        </RadialGradientBrush.GradientStops>
+    </RadialGradientBrush>
 
-
+    <RadialGradientBrush x:Key="Ng" GradientOrigin="0.5,0.5" 
+                             RadiusX="0.75" 
+                             RadiusY="0.75">
+        <RadialGradientBrush.GradientStops>
+            <GradientStop Color="White" Offset="0" />
+            <GradientStop Color="Red" Offset="1" />
+        </RadialGradientBrush.GradientStops>
+    </RadialGradientBrush>
 
 </ResourceDictionary>
\ No newline at end of file
diff --git a/HMI.UI/Style/MsgBoxStyle.xaml b/HMI.UI/Style/MsgBoxStyle.xaml
index 5e0dafb..a29c393 100644
--- a/HMI.UI/Style/MsgBoxStyle.xaml
+++ b/HMI.UI/Style/MsgBoxStyle.xaml
@@ -11,6 +11,8 @@
             <Style TargetType="pu:WindowX" BasedOn="{StaticResource {x:Static pu:MessageBoxX.WindowXStyleKey}}">
                 <Setter Property="pu:WindowXCaption.Background" Value="{StaticResource WarningColor}" />
                 <Setter Property="pu:WindowXCaption.Foreground" Value="{StaticResource WarningColorContract}" />
+                <Setter Property="Width" Value="350" />
+                <Setter Property="Height" Value="200" />
             </Style>
         </pu:MessageBoxXSettings.WindowXStyle>
 
@@ -47,6 +49,8 @@
             <Style TargetType="pu:WindowX" BasedOn="{StaticResource {x:Static pu:MessageBoxX.WindowXStyleKey}}">
                 <Setter Property="pu:WindowXCaption.Background" Value="{StaticResource DangerColor}" />
                 <Setter Property="pu:WindowXCaption.Foreground" Value="{StaticResource DangerColorContrast}" />
+                <Setter Property="Width" Value="350" />
+                <Setter Property="Height" Value="200" />
             </Style>
         </pu:MessageBoxXSettings.WindowXStyle>
 
@@ -83,6 +87,8 @@
             <Style TargetType="pu:WindowX" BasedOn="{StaticResource {x:Static pu:MessageBoxX.WindowXStyleKey}}">
                 <Setter Property="pu:WindowXCaption.Background" Value="{StaticResource PrimaryColor}" />
                 <Setter Property="pu:WindowXCaption.Foreground" Value="{StaticResource PrimaryColorContract}" />
+                <Setter Property="Width" Value="350" />
+                <Setter Property="Height" Value="200" />
             </Style>
         </pu:MessageBoxXSettings.WindowXStyle>
 
diff --git a/HMI.UI/Style/PanuonResource.xaml b/HMI.UI/Style/PanuonResource.xaml
index b587af8..3d29dc3 100644
--- a/HMI.UI/Style/PanuonResource.xaml
+++ b/HMI.UI/Style/PanuonResource.xaml
@@ -8,7 +8,6 @@
                     xmlns:sys="clr-namespace:System;assembly=mscorlib"
                     xmlns:pw="https://opensource.panuon.com/wpf"
                     xmlns:pu="https://opensource.panuon.com/wpf-ui"
-             xmlns:hc="clr-namespace:HMI.Core;assembly=HMI.Core"
              xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
              xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI">
     <ResourceDictionary.MergedDictionaries>
@@ -16,8 +15,6 @@
         <pu:StyleDictionary Includes="PasswordBox,TextBox,ComboBox,Button,DataGrid,TreeView,Menu" />
         <ResourceDictionary Source="/HMI.UI;component/Resources/Font/Font.xaml"/>
     </ResourceDictionary.MergedDictionaries>
-
-    <hc:LangConverter x:Key="lc"/>
     <sys:Double x:Key="TitleFontSize">20</sys:Double>
     <sys:Double x:Key="ContentFontSize">16</sys:Double>
     <sys:Double x:Key="ContentFontSize2">14</sys:Double>
@@ -286,4 +283,11 @@
                 Value="{DynamicResource App.Save}"/>
         <Setter Property="pu:WindowXModalDialog.ButtonPanelMargin" Value="0,30,10,10"/>
     </Style>
+
+    <Popup x:Key="testPop" Placement="Relative" StaysOpen="True" Width="1920" Height="1080">
+        <Rectangle x:Name="RectMask"
+           Fill="Red"
+           Opacity="0"
+           Visibility="Visible" />
+    </Popup>
 </ResourceDictionary>
\ No newline at end of file
diff --git a/HMI.UI/Util/MsgBoxHelper2.cs b/HMI.UI/Util/MsgBoxHelper2.cs
new file mode 100644
index 0000000..782354b
--- /dev/null
+++ b/HMI.UI/Util/MsgBoxHelper2.cs
@@ -0,0 +1,98 @@
+锘縰sing HMI.Core.Util;
+using Panuon.WPF.UI;
+using Panuon.WPF.UI.Configurations;
+using System.Windows;
+
+namespace HMI.UI.Util
+{
+    public class MsgBoxHelper2
+    {
+        public static MessageBoxResult Warn(string message,
+            string caption = null,
+            MessageBoxButton button = MessageBoxButton.OK,
+            MessageBoxIcon icon = MessageBoxIcon.Warning,
+            DefaultButton defaultButton = DefaultButton.Unset, int? countdown = null)
+        {
+            caption = caption ?? LangUtil.Get("App.Warn");
+            var setting = Application.Current.FindResource("MsgBoxWarn") as MessageBoxXSetting;
+            return ShowMessage(message, caption, button, icon, defaultButton, setting, countdown);
+        }
+
+        public static MessageBoxResult Error(string message,
+            string caption = null,
+            MessageBoxButton button = MessageBoxButton.OK,
+            MessageBoxIcon icon = MessageBoxIcon.Error,
+            DefaultButton defaultButton = DefaultButton.Unset, int? countdown = null)
+        {
+            caption = caption ?? LangUtil.Get("App.Error");
+            var setting = Application.Current.FindResource("MsgBoxError") as MessageBoxXSetting;
+            return ShowMessage(message, caption, button, icon, defaultButton, setting, countdown);
+        }
+
+        public static MessageBoxResult Info(string message,
+            string caption = null,
+            MessageBoxButton button = MessageBoxButton.OK,
+            MessageBoxIcon icon = MessageBoxIcon.Info,
+            DefaultButton defaultButton = DefaultButton.Unset, int? countdown = null)
+        {
+            caption = caption ?? LangUtil.Get("App.Info");
+            var setting = Application.Current.FindResource("MsgBoxInfo") as MessageBoxXSetting;
+            return ShowMessage(message, caption, button, icon, defaultButton, setting, countdown);
+        }
+
+        public static MessageBoxResult WarnChoose(string message,
+            string caption = null,
+            MessageBoxButton button = MessageBoxButton.OKCancel,
+            MessageBoxIcon icon = MessageBoxIcon.Warning,
+            DefaultButton defaultButton = DefaultButton.Unset, int? countdown = null)
+        {
+            caption = caption ?? LangUtil.Get("App.Warn");
+            var setting = Application.Current.FindResource("MsgBoxWarn") as MessageBoxXSetting;
+            return ShowMessage(message, caption, button, icon, defaultButton, setting, countdown);
+        }
+
+        public static MessageBoxResult ErrorChoose(string message,
+            string caption = null,
+            MessageBoxButton button = MessageBoxButton.OKCancel,
+            MessageBoxIcon icon = MessageBoxIcon.Error,
+            DefaultButton defaultButton = DefaultButton.Unset, int? countdown = null)
+        {
+            caption = caption ?? LangUtil.Get("App.Error");
+            var setting = Application.Current.FindResource("MsgBoxError") as MessageBoxXSetting;
+            return ShowMessage(message, caption, button, icon, defaultButton, setting, countdown);
+        }
+
+        public static MessageBoxResult InfoChoose(string message,
+            string caption = null,
+            MessageBoxButton button = MessageBoxButton.OKCancel,
+            MessageBoxIcon icon = MessageBoxIcon.Info,
+            DefaultButton defaultButton = DefaultButton.Unset, int? countdown = null)
+        {
+            caption = caption ?? LangUtil.Get("App.Info");
+            var setting = Application.Current.FindResource("MsgBoxInfo") as MessageBoxXSetting;
+            return ShowMessage(message, caption, button, icon, defaultButton, setting, countdown);
+        }
+
+        public static MessageBoxResult ShowMessage(string message,
+            string caption,
+            MessageBoxButton button,
+            MessageBoxIcon icon,
+            DefaultButton defaultButton, MessageBoxXSetting setting, int? countdown)
+        {
+            MessageBoxResult res = MessageBoxResult.None;
+            var window = Application.Current.MainWindow;
+            if (window is WindowX)
+            {
+                window.Dispatcher.Invoke(() =>
+                {
+                    res = MessageBoxX.Show(window, message, caption, button, icon, defaultButton, setting, countdown);
+                });
+                return res;
+            }
+            else
+            {
+                return MessageBox.Show(message, caption);
+            }
+        }
+    }
+}
diff --git a/HMI.UI/Util/ToastHelper.cs b/HMI.UI/Util/ToastHelper.cs
index 2156bdc..90a409b 100644
--- a/HMI.UI/Util/ToastHelper.cs
+++ b/HMI.UI/Util/ToastHelper.cs
@@ -1,4 +1,6 @@
-锘縰sing Panuon.WPF.UI;
+锘縰sing HMI.Core.Util;
+using Panuon.WPF.UI;
+using System.Runtime.CompilerServices;
 using System.Windows;
 using System.Windows.Controls;
 
@@ -40,6 +42,73 @@
             if (Instance == null) { Instance = helper; }
         }
 
+        public static void Success(string message,
+            MessageBoxIcon icon = MessageBoxIcon.Success,
+            ToastPosition position = ToastPosition.Top, double offset = 0, int durationMs = 3000,
+            ToastWindow targetWindow = ToastWindow.ActiveWindow)
+        {
+            var window = Application.Current.MainWindow;
+            if (window is WindowX)
+            {
+                Instance.Success(window, message, icon, position, offset, durationMs, targetWindow);
+            }
+            else
+            {
+                MessageBox.Show(message, LangUtil.Get("App.Success"));
+            }
+        }
+
+        public static void Warning(string message,
+            MessageBoxIcon icon = MessageBoxIcon.Warning,
+            ToastPosition position = ToastPosition.Top, double offset = 0, int durationMs = 3000,
+            ToastWindow targetWindow = ToastWindow.ActiveWindow)
+        {
+            var window = Application.Current.MainWindow;
+            if (window is WindowX)
+            {
+                Instance.Warning(window, message, icon, position, offset, durationMs, targetWindow);
+            }
+            else
+            {
+                MessageBox.Show(message, LangUtil.Get("App.Warn"));
+            }
+        }
+
+        public static void Error(string message,
+            MessageBoxIcon icon = MessageBoxIcon.Error,
+            ToastPosition position = ToastPosition.Top, double offset = 0, int durationMs = 3000,
+            ToastWindow targetWindow = ToastWindow.ActiveWindow)
+        {
+            var window = Application.Current.MainWindow;
+            if (window is WindowX)
+            {
+
+                Instance.Error(window, message, icon, position, offset, durationMs, targetWindow);
+            }
+            else
+            {
+                MessageBox.Show(message, LangUtil.Get("App.Error"));
+            }
+        }
+
+        public static void Info(string message,
+            MessageBoxIcon icon = MessageBoxIcon.Info,
+            ToastPosition position = ToastPosition.Top, double offset = 0, int durationMs = 3000,
+            ToastWindow targetWindow = ToastWindow.ActiveWindow)
+        {
+            var window = Application.Current.MainWindow;
+            if (window is WindowX)
+            {
+
+                Instance.Info(window, message, icon, position, offset, durationMs, targetWindow);
+            }
+            else
+            {
+                MessageBox.Show(message, LangUtil.Get("App.Info"));
+            }
+        }
+
+
         public static void Success(DependencyObject dp,
             string message,
             MessageBoxIcon icon = MessageBoxIcon.Success,
diff --git a/HMI.UI/packages.config b/HMI.UI/packages.config
index 46ff1b7..18db34a 100644
--- a/HMI.UI/packages.config
+++ b/HMI.UI/packages.config
@@ -1,5 +1,5 @@
 锘�<?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Panuon.WPF" version="1.1.2.2" targetFramework="net472" />
+  <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
   <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/HMI.UnitTest/HMI.UnitTest.csproj b/HMI.UnitTest/HMI.UnitTest.csproj
index f91baeb..cd246aa 100644
--- a/HMI.UnitTest/HMI.UnitTest.csproj
+++ b/HMI.UnitTest/HMI.UnitTest.csproj
@@ -55,11 +55,11 @@
     <Prefer32Bit>true</Prefer32Bit>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="log4net, Version=3.0.3.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\log4net.3.0.3\lib\net462\log4net.dll</HintPath>
+    <Reference Include="log4net, Version=3.0.4.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\log4net.3.0.4\lib\net462\log4net.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.2.2\lib\net472\Panuon.WPF.dll</HintPath>
+      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
diff --git a/HMI.UnitTest/packages.config b/HMI.UnitTest/packages.config
index 63cdc53..21b491c 100644
--- a/HMI.UnitTest/packages.config
+++ b/HMI.UnitTest/packages.config
@@ -1,6 +1,6 @@
 锘�<?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="log4net" version="3.0.3" targetFramework="net472" />
-  <package id="Panuon.WPF" version="1.1.2.2" targetFramework="net472" />
+  <package id="log4net" version="3.0.4" targetFramework="net472" />
+  <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
   <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/Libs/Microsoft.DwayneNeed.Win32.dll b/Libs/Microsoft.DwayneNeed.Win32.dll
new file mode 100644
index 0000000..cf63f99
--- /dev/null
+++ b/Libs/Microsoft.DwayneNeed.Win32.dll
Binary files differ
diff --git a/Libs/Microsoft.DwayneNeed.dll b/Libs/Microsoft.DwayneNeed.dll
new file mode 100644
index 0000000..2450e58
--- /dev/null
+++ b/Libs/Microsoft.DwayneNeed.dll
Binary files differ
diff --git a/Plugin.ServoManage/Plugin.ServoManage.csproj b/Plugin.ServoManage/Plugin.ServoManage.csproj
new file mode 100644
index 0000000..2bbb589
--- /dev/null
+++ b/Plugin.ServoManage/Plugin.ServoManage.csproj
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{1853E00F-6865-4BC6-974B-6A5E1C00BAFE}</ProjectGuid>
+    <OutputType>library</OutputType>
+    <RootNamespace>Plugin.ServoManage</RootNamespace>
+    <AssemblyName>Plugin.ServoManage</AssemblyName>
+    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <WarningLevel>4</WarningLevel>
+    <Deterministic>true</Deterministic>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <LangVersion>7.3</LangVersion>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>bin\x64\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <LangVersion>7.3</LangVersion>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="log4net, Version=3.0.4.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\log4net.3.0.4\lib\net462\log4net.dll</HintPath>
+    </Reference>
+    <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
+    </Reference>
+    <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Web" />
+    <Reference Include="System.Xml" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xaml">
+      <RequiredTargetFramework>4.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="WindowsBase" />
+    <Reference Include="PresentationCore" />
+    <Reference Include="PresentationFramework" />
+  </ItemGroup>
+  <ItemGroup>
+    <Page Include="ServoManage.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Compile Include="ServoManage.xaml.cs">
+      <DependentUpon>ServoManage.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+    <None Include="packages.config" />
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\HMI.Base\HMI.Base.csproj">
+      <Project>{2a6f9720-a890-4036-9d73-41a0dae28341}</Project>
+      <Name>HMI.Base</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HMI.Core\HMI.Core.csproj">
+      <Project>{3e3bf44a-0b69-45c5-9512-528cb48a7106}</Project>
+      <Name>HMI.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HMI.UI\HMI.UI.csproj">
+      <Project>{f17de6b5-af1d-48c6-94a0-6b763a6546a6}</Project>
+      <Name>HMI.UI</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
diff --git a/Plugin.ServoManage/Properties/AssemblyInfo.cs b/Plugin.ServoManage/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..f17020b
--- /dev/null
+++ b/Plugin.ServoManage/Properties/AssemblyInfo.cs
@@ -0,0 +1,52 @@
+锘縰sing System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// 鏈夊叧绋嬪簭闆嗙殑涓�鑸俊鎭敱浠ヤ笅
+// 鎺у埗銆傛洿鏀硅繖浜涚壒鎬у�煎彲淇敼
+// 涓庣▼搴忛泦鍏宠仈鐨勪俊鎭��
+[assembly: AssemblyTitle("Plugin.ServoManage")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Plugin.ServoManage")]
+[assembly: AssemblyCopyright("Copyright 漏  2025")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 灏� ComVisible 璁剧疆涓� false 浼氫娇姝ょ▼搴忛泦涓殑绫诲瀷
+//瀵� COM 缁勪欢涓嶅彲瑙併�傚鏋滈渶瑕佷粠 COM 璁块棶姝ょ▼搴忛泦涓殑绫诲瀷
+//璇峰皢姝ょ被鍨嬬殑 ComVisible 鐗规�ц缃负 true銆�
+[assembly: ComVisible(false)]
+
+//鑻ヨ寮�濮嬬敓鎴愬彲鏈湴鍖栫殑搴旂敤绋嬪簭锛岃璁剧疆
+//.csproj 鏂囦欢涓殑 <UICulture>CultureYouAreCodingWith</UICulture>
+//鍦� <PropertyGroup> 涓�備緥濡傦紝濡傛灉浣犱娇鐢ㄧ殑鏄編鍥借嫳璇��
+//浣跨敤鐨勬槸缇庡浗鑻辫锛岃灏� <UICulture> 璁剧疆涓� en-US銆�  鐒跺悗鍙栨秷
+//瀵逛互涓� NeutralResourceLanguage 鐗规�х殑娉ㄩ噴銆�  鏇存柊
+//浠ヤ笅琛屼腑鐨勨�渆n-US鈥濅互鍖归厤椤圭洰鏂囦欢涓殑 UICulture 璁剧疆銆�
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly:ThemeInfo(
+    ResourceDictionaryLocation.None, //涓婚鐗瑰畾璧勬簮璇嶅吀鎵�澶勪綅缃�
+                             //(鏈湪椤甸潰涓壘鍒拌祫婧愭椂浣跨敤锛�
+                             //鎴栧簲鐢ㄧ▼搴忚祫婧愬瓧鍏镐腑鎵惧埌鏃朵娇鐢�)
+    ResourceDictionaryLocation.SourceAssembly //甯歌璧勬簮璇嶅吀鎵�澶勪綅缃�
+                                      //(鏈湪椤甸潰涓壘鍒拌祫婧愭椂浣跨敤锛�
+                                      //銆佸簲鐢ㄧ▼搴忔垨浠讳綍涓婚涓撶敤璧勬簮瀛楀吀涓壘鍒版椂浣跨敤)
+)]
+
+
+// 绋嬪簭闆嗙殑鐗堟湰淇℃伅鐢变笅鍒楀洓涓�肩粍鎴�: 
+//
+//      涓荤増鏈�
+//      娆$増鏈�
+//      鐢熸垚鍙�
+//      淇鍙�
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Plugin.ServoManage/Properties/Resources.Designer.cs b/Plugin.ServoManage/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..5ddb6f8
--- /dev/null
+++ b/Plugin.ServoManage/Properties/Resources.Designer.cs
@@ -0,0 +1,62 @@
+锘�//------------------------------------------------------------------------------
+// <auto-generated>
+//     姝や唬鐮佺敱宸ュ叿鐢熸垚銆�
+//     杩愯鏃剁増鏈�: 4.0.30319.42000
+//
+//     瀵规鏂囦欢鐨勬洿鏀瑰彲鑳藉鑷翠笉姝g‘鐨勮涓猴紝濡傛灉
+//     閲嶆柊鐢熸垚浠g爜锛屽垯鎵�鍋氭洿鏀瑰皢涓㈠け銆�
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Plugin.ServoManage.Properties {
+    
+    
+    /// <summary>
+    ///   寮虹被鍨嬭祫婧愮被锛岀敤浜庢煡鎵炬湰鍦板寲瀛楃涓茬瓑銆�
+    /// </summary>
+    // 姝ょ被鏄敱 StronglyTypedResourceBuilder
+    // 绫婚�氳繃绫讳技浜� ResGen 鎴� Visual Studio 鐨勫伐鍏疯嚜鍔ㄧ敓鎴愮殑銆�
+    // 鑻ヨ娣诲姞鎴栫Щ闄ゆ垚鍛橈紝璇风紪杈� .ResX 鏂囦欢锛岀劧鍚庨噸鏂拌繍琛� ResGen
+    // (浠� /str 浣滀负鍛戒护閫夐」)锛屾垨閲嶆柊鐢熸垚 VS 椤圭洰銆�
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   杩斿洖姝ょ被浣跨敤鐨勭紦瀛� ResourceManager 瀹炰緥銆�
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if ((resourceMan == null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Plugin.ServoManage.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   閲嶅啓褰撳墠绾跨▼鐨� CurrentUICulture 灞炴�э紝瀵�
+        ///   浣跨敤姝ゅ己绫诲瀷璧勬簮绫荤殑鎵�鏈夎祫婧愭煡鎵炬墽琛岄噸鍐欍��
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+    }
+}
diff --git a/Plugin.ServoManage/Properties/Resources.resx b/Plugin.ServoManage/Properties/Resources.resx
new file mode 100644
index 0000000..af7dbeb
--- /dev/null
+++ b/Plugin.ServoManage/Properties/Resources.resx
@@ -0,0 +1,117 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/Plugin.ServoManage/Properties/Settings.Designer.cs b/Plugin.ServoManage/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..8064725
--- /dev/null
+++ b/Plugin.ServoManage/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+锘�//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Plugin.ServoManage.Properties
+{
+    
+    
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+    {
+        
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+        
+        public static Settings Default
+        {
+            get
+            {
+                return defaultInstance;
+            }
+        }
+    }
+}
diff --git a/Plugin.ServoManage/Properties/Settings.settings b/Plugin.ServoManage/Properties/Settings.settings
new file mode 100644
index 0000000..033d7a5
--- /dev/null
+++ b/Plugin.ServoManage/Properties/Settings.settings
@@ -0,0 +1,7 @@
+锘�<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>
\ No newline at end of file
diff --git a/Plugin.ServoManage/ServoManage.xaml b/Plugin.ServoManage/ServoManage.xaml
new file mode 100644
index 0000000..421d871
--- /dev/null
+++ b/Plugin.ServoManage/ServoManage.xaml
@@ -0,0 +1,371 @@
+锘�<UserControl x:Class="Plugin.ServoManage.ServoManage"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:Plugin.ServoManage"
+             mc:Ignorable="d" 
+             xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+             xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+             xmlns:pw="https://opensource.panuon.com/wpf"
+             xmlns:pu="https://opensource.panuon.com/wpf-ui"
+             xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+             xmlns:cc="clr-namespace:HMI.Core;assembly=HMI.Core"
+             Loaded="UserControl_Loaded"
+             d:DesignHeight="450" d:DesignWidth="800">
+    <UserControl.Resources>
+        <Style x:Key="Desc" TargetType="Label">
+            <Setter Property="Padding" Value="10"/>
+            <Setter Property="FontSize" Value="12"/>
+            <Setter Property="BorderThickness" Value="1"/>
+            <Setter Property="BorderBrush" Value="#3a3a3a"/>
+            <Setter Property="HorizontalContentAlignment" Value="Center"/>
+            <Setter Property="VerticalContentAlignment" Value="Center"/>
+        </Style>
+
+        <Style x:Key="LabelText" TargetType="Label" BasedOn="{StaticResource Desc}">
+            <Setter Property="BorderThickness" Value="1,0,1,1"/>
+        </Style>
+
+        <Style x:Key="BDesc" TargetType="Label" BasedOn="{StaticResource Desc}">
+            <Setter Property="Background" Value="#afeeee"/>
+        </Style>
+
+        <Style x:Key="YDesc" TargetType="Label" BasedOn="{StaticResource Desc}">
+            <Setter Property="Background" Value="#ffff00"/>
+        </Style>
+    </UserControl.Resources>
+    
+    <Border Style="{StaticResource CardBoarder}">
+        <Grid dp:GridHelper.Space="10">
+            <Grid.RowDefinitions>
+                <RowDefinition Height="Auto"/>
+                <RowDefinition Height="Auto"/>
+                <RowDefinition/>
+            </Grid.RowDefinitions>
+
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="7*"/>
+                <ColumnDefinition Width="3*"/>
+            </Grid.ColumnDefinitions>
+
+            <DockPanel Grid.ColumnSpan="2">
+                <StackPanel DockPanel.Dock="Right" Style="{StaticResource ButtonGroup}">
+                    <Button Style="{StaticResource AddBtn}" x:Name="addBtn" Click="Button_Click"/>
+                    <Button Style="{StaticResource EditBtn}" x:Name="editBtn" Click="Button_Click"/>
+                    <Button Style="{StaticResource RfhBtn}" x:Name="rfhBtn" Click="Button_Click"/>
+                    <Button Style="{StaticResource DelBtn}" x:Name="delBtn" Click="Button_Click"/>
+                </StackPanel>
+                <TextBlock Style="{StaticResource TitleBox}" Text="{DynamicResource svo.title}"/>
+            </DockPanel>
+
+            <DockPanel Grid.Row="2" Grid.ColumnSpan="2" Margin="0,10,0,0">
+                <pu:Drawer DockPanel.Dock="Left" x:Name="DrwMenu" MinWidth="35" MaxWidth="400"
+                           Padding="0"
+                           ShadowColor="{x:Null}"
+                           AnimationDuration="0" BorderThickness="2,0,0,2" BorderBrush="{StaticResource CommonBoarder}">
+                    <Grid>
+                        <Grid.RowDefinitions>
+                            <RowDefinition Height="Auto"/>
+                            <RowDefinition/>
+                        </Grid.RowDefinitions>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition/>
+                            <ColumnDefinition Width="Auto"/>
+                        </Grid.ColumnDefinitions>
+
+                        <Border Grid.ColumnSpan="2" BorderThickness="2" BorderBrush="{StaticResource CommonBoarder}" Background="{StaticResource VerBar}">
+                            <DockPanel Height="35">
+                                <ToggleButton x:Name="drawerBtn" BorderThickness="0"
+                  DockPanel.Dock="Right"
+                  Background="Transparent"
+                  Width="35" Height="35" HorizontalAlignment="Right"
+                  RenderTransformOrigin="0.5,0.5"
+                                              Foreground="{StaticResource PrimaryColorContract}"
+                  FontFamily="{StaticResource iconfont}"
+                  Content="&#xe60e;" IsChecked="{Binding IsOpen, ElementName=DrwMenu, Mode=TwoWay}">
+                                    <ToggleButton.Style>
+                                        <Style TargetType="ToggleButton" BasedOn="{StaticResource CommonToggle}">
+                                            <Style.Triggers>
+                                                <DataTrigger Binding="{Binding IsOpen, ElementName=DrwMenu}" Value="False">
+                                                    <Setter Property="RenderTransform">
+                                                        <Setter.Value>
+                                                            <RotateTransform Angle="-90"/>
+                                                        </Setter.Value>
+                                                    </Setter>
+                                                </DataTrigger>
+                                                <DataTrigger Binding="{Binding IsOpen, ElementName=DrwMenu}" Value="True">
+                                                    <Setter Property="Background" Value="Red"/>
+                                                    <Setter Property="RenderTransform">
+                                                        <Setter.Value>
+                                                            <RotateTransform Angle="90"/>
+                                                        </Setter.Value>
+                                                    </Setter>
+                                                </DataTrigger>
+                                                <Trigger Property="IsChecked" Value="True">
+                                                    <Setter Property="Background" Value="Red"/>
+                                                </Trigger>
+                                            </Style.Triggers>
+                                        </Style>
+                                    </ToggleButton.Style>
+                                </ToggleButton>
+
+                                <TextBlock Text="{DynamicResource svo.list}" FontSize="16" 
+                                           Foreground="{StaticResource PrimaryColorContract}"
+                                           VerticalAlignment="Center" HorizontalAlignment="Center"/>
+                            </DockPanel>
+                        </Border>
+
+
+                        <Grid Grid.Row="1">
+                            <Grid.RowDefinitions>
+                                <RowDefinition Height="Auto"/>
+                                <RowDefinition/>
+                            </Grid.RowDefinitions>
+                            <Grid.ColumnDefinitions>
+                                <ColumnDefinition Width="Auto"/>
+                                <ColumnDefinition/>
+                            </Grid.ColumnDefinitions>
+
+                            <DataGrid Grid.Row="1" Grid.ColumnSpan="2" Style="{StaticResource DefaultDataGrid}"
+                                      IsReadOnly="False"
+                                      SelectionMode="Single"
+                                      BorderThickness="0"
+                                      ItemsSource="{Binding Datas}">
+                                <DataGrid.Columns>
+                                    <DataGridTemplateColumn Header="#" IsReadOnly="True" CanUserResize="False">
+                                        <DataGridTemplateColumn.CellTemplate>
+                                            <DataTemplate>
+                                                <TextBlock Text="{Binding Converter={StaticResource rowNumber},
+RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"/>
+                                            </DataTemplate>
+                                        </DataGridTemplateColumn.CellTemplate>
+                                    </DataGridTemplateColumn>
+
+                                    <DataGridTextColumn IsReadOnly="True" Width="*" Binding="{Binding Name}">
+                                        <DataGridTextColumn.Header>
+                                            <TextBlock Text="{DynamicResource svo.name}"/>
+                                        </DataGridTextColumn.Header>
+                                    </DataGridTextColumn>
+
+                                    <DataGridTemplateColumn Width="100" IsReadOnly="True" CanUserResize="False">
+                                        <DataGridTemplateColumn.Header>
+                                            <TextBlock Text="{DynamicResource App.Opt}"/>
+                                        </DataGridTemplateColumn.Header>
+
+                                        <DataGridTemplateColumn.CellTemplate>
+                                            <DataTemplate>
+                                                <StackPanel Orientation="Horizontal" dp:StackPanelHelper.ChildSpace="10">
+                                                    <Button x:Name="editServoBtn" Style="{StaticResource EditLink}"  DataContext="{Binding }"
+Click="Button_Click"/>
+                                                    <Button x:Name="delServoBtn" Style="{StaticResource DeleteLink}"
+DataContext="{Binding }"
+Click="Button_Click"/>
+                                                </StackPanel>
+                                            </DataTemplate>
+                                        </DataGridTemplateColumn.CellTemplate>
+                                    </DataGridTemplateColumn>
+                                </DataGrid.Columns>
+
+                            </DataGrid>
+                        </Grid>
+
+                        <Label Grid.Row="1" Grid.Column="1"  Width="100" Height="34"
+                               VerticalContentAlignment="Center"
+                               HorizontalContentAlignment="Center"
+                                   Content="{DynamicResource svo.list}"
+                                   FontSize="16">
+                            <Label.LayoutTransform>
+                                <RotateTransform CenterX="25" CenterY="25" Angle="270"/>
+                            </Label.LayoutTransform>
+
+                            <Label.Style>
+                                <Style TargetType="Label">
+                                    <Style.Triggers>
+                                        <DataTrigger Binding="{Binding IsOpen, ElementName=DrwMenu,Mode=OneWay}" Value="True">
+                                            <Setter Property="Visibility" Value="Collapsed"/>
+                                        </DataTrigger>
+                                        <DataTrigger Binding="{Binding IsOpen, ElementName=DrwMenu}" Value="False">
+                                            <Setter Property="Visibility" Value="Visible"/>
+                                        </DataTrigger>
+                                    </Style.Triggers>
+                                </Style>
+                            </Label.Style>
+                        </Label>
+                    </Grid>
+                </pu:Drawer>
+
+                <Border BorderThickness="2" BorderBrush="{StaticResource CommonBoarder}">
+                    <Grid dp:GridHelper.Space="10">
+                        <Grid.RowDefinitions>
+                            <RowDefinition Height="Auto"/>
+                            <RowDefinition/>
+                        </Grid.RowDefinitions>
+
+                        <DockPanel>
+                            <StackPanel Style="{StaticResource ButtonGroup}">
+                                <TextBlock Style="{StaticResource TitleBox}" 
+                                           FontSize="{StaticResource ContentFontSize2}" 
+                                           Text="{DynamicResource svo.product}"/>
+                                <ComboBox x:Name="productInput" Style="{StaticResource FormComboxStyle}" MinWidth="180" />
+
+                                <Button Style="{StaticResource AddBtn}" Click="Button_Click"/>
+                                <Button Style="{StaticResource EditBtn}" Click="Button_Click"/>
+                                <Button Style="{StaticResource RfhBtn}" Click="Button_Click"/>
+                                <Button Style="{StaticResource DelBtn}" Click="Button_Click"/>
+                            </StackPanel>
+                        </DockPanel>
+
+                        <WrapPanel Grid.Row="1">
+                            <GroupBox Header="鎶ヨ" Padding="10">
+                                <StackPanel Style="{StaticResource ButtonGroup}">
+                                    <StackPanel>
+                                        <Label Style="{StaticResource YDesc}" Content="鎺у埗鎶ヨ"/>
+                                        <Label Style="{StaticResource LabelText}" Content="鎺у埗鎶ヨ"/>
+                                    </StackPanel>
+                                    <StackPanel>
+                                        <Label Style="{StaticResource YDesc}" Content="椹卞姩鎶ヨ"/>
+                                        <Label Style="{StaticResource LabelText}" Content="鎺у埗鎶ヨ"/>
+                                    </StackPanel>
+                                    <StackPanel>
+                                        <Label Style="{StaticResource YDesc}" Content="鏁呴殰椹卞姩"/>
+                                        <Label Style="{StaticResource LabelText}" Content="0"/>
+                                    </StackPanel>
+                                </StackPanel>
+                            </GroupBox>
+
+                            <GroupBox Header="浣嶇疆" Padding="10">
+                                <StackPanel Style="{StaticResource ButtonGroup}">
+                                    <StackPanel>
+                                        <Label Style="{StaticResource BDesc}" Content="褰撳墠浣嶇疆"/>
+                                        <Label Style="{StaticResource LabelText}" Content="0"/>
+                                    </StackPanel>
+
+                                    <StackPanel>
+                                        <Label Style="{StaticResource BDesc}" Content="褰撳墠閫熷害"/>
+                                        <Label Style="{StaticResource LabelText}" Content="0"/>
+                                    </StackPanel>
+                                    <StackPanel>
+                                        <Label Style="{StaticResource BDesc}" Content="鍔犻�熷害"/>
+                                        <Label Style="{StaticResource LabelText}" Content="0"/>
+                                    </StackPanel>
+                                    <StackPanel>
+                                        <Label Style="{StaticResource BDesc}" Content="鍑忛�熷害"/>
+                                        <Label Style="{StaticResource LabelText}" Content="0"/>
+                                    </StackPanel>
+                                </StackPanel>
+                            </GroupBox>
+
+                            <GroupBox Header="鐘舵��" Padding="10">
+                                <StackPanel Style="{StaticResource ButtonGroup}">
+                                    <StackPanel>
+                                        <Label Style="{StaticResource YDesc}" Content="浣胯兘"/>
+                                        <Label Style="{StaticResource LabelText}">
+                                            <Ellipse Height="30" Width="30" Fill="{StaticResource Normal}" />
+                                        </Label>
+                                    </StackPanel>
+
+                                    <StackPanel>
+                                        <Label Style="{StaticResource YDesc}" Content="鍑嗗濂�"/>
+                                        <Label Style="{StaticResource LabelText}">
+                                            <Ellipse Height="30" Width="30" Fill="{StaticResource Normal}" />
+                                        </Label>
+                                    </StackPanel>
+                                    <StackPanel>
+                                        <Label Style="{StaticResource YDesc}" Content="杩愯涓�"/>
+                                        <Label Style="{StaticResource LabelText}">
+                                            <Ellipse Height="30" Width="30" Fill="{StaticResource Normal}" />
+                                        </Label>
+                                    </StackPanel>
+                                    <StackPanel>
+                                        <Label Style="{StaticResource YDesc}" Content="鏁呴殰"/>
+                                        <Label Style="{StaticResource LabelText}">
+                                            <Ellipse Height="30" Width="30" Fill="{StaticResource Normal}" />
+                                        </Label>
+                                    </StackPanel>
+                                    <StackPanel>
+                                        <Label Style="{StaticResource YDesc}" Content="杞存姤璀�"/>
+                                        <Label Style="{StaticResource LabelText}">
+                                            <Ellipse Height="30" Width="30" Fill="{StaticResource Normal}" />
+                                        </Label>
+                                    </StackPanel>
+                                    <StackPanel>
+                                        <Label Style="{StaticResource YDesc}" Content="浠g爜"/>
+                                        <Label Style="{StaticResource LabelText}">
+                                            <Ellipse Height="30" Width="30" Fill="{StaticResource Normal}" />
+                                        </Label>
+                                    </StackPanel>
+                                </StackPanel>
+                            </GroupBox>
+
+                            <GroupBox Header="闄愪綅浼犳劅鍣�" Padding="10">
+                                <StackPanel Style="{StaticResource ButtonGroup}" Orientation="Vertical">
+                                    <StackPanel Orientation="Horizontal">
+                                        <Label Style="{StaticResource YDesc}" Content="浣胯兘"/>
+                                        <Label Style="{StaticResource LabelText}" BorderThickness="0,1,1,1" >
+                                            <Ellipse Height="30" Width="30" Fill="{StaticResource Normal}" />
+                                        </Label>
+                                    </StackPanel>
+
+                                    <StackPanel Orientation="Horizontal">
+                                        <Label Style="{StaticResource YDesc}" Content="鍑嗗濂�"/>
+                                        <Label Style="{StaticResource LabelText}" BorderThickness="0,1,1,1" >
+                                            <Ellipse Height="30" Width="30" Fill="{StaticResource Normal}" />
+                                        </Label>
+                                    </StackPanel>
+                                    <StackPanel Orientation="Horizontal">
+                                        <Label Style="{StaticResource YDesc}" Content="杩愯涓�"/>
+                                        <Label Style="{StaticResource LabelText}" BorderThickness="0,1,1,1" >
+                                            <Ellipse Height="30" Width="30" Fill="{StaticResource Normal}" />
+                                        </Label>
+                                    </StackPanel>
+                                </StackPanel>
+                            </GroupBox>
+
+                            <GroupBox Header="瀵稿姩" Padding="10">
+                                <StackPanel Style="{StaticResource ButtonGroup}">
+                                    <Button Style="{StaticResource PrimaryButton}">瀵稿姩</Button>
+
+                                    <Label Style="{StaticResource LabelText}" BorderThickness="1" Content="鍑嗗濂�"/>
+
+                                    <Button Style="{StaticResource PrimaryButton}">姝e悜</Button>
+                                </StackPanel>
+                            </GroupBox>
+
+                            <GroupBox Header="鎿嶄綔" Padding="10">
+                                <Grid dp:GridHelper.Space="10">
+                                    <Grid.RowDefinitions>
+                                        <RowDefinition Height="Auto"/>
+                                        <RowDefinition Height="Auto"/>
+                                        <RowDefinition Height="Auto"/>
+                                        <RowDefinition Height="Auto"/>
+                                        <RowDefinition Height="Auto"/>
+                                    </Grid.RowDefinitions>
+                                    <Button Style="{StaticResource PrimaryButton}">璋冭瘯妯″紡</Button>
+                                    <UniformGrid Grid.Row="1" Columns="2">
+                                        <Button Style="{StaticResource PrimaryButton}"
+                                                Margin="0,0,5,0">璋冭瘯妯″紡</Button>
+                                        <Button Style="{StaticResource PrimaryButton}"
+                                                Margin="5,0,0,0">璋冭瘯妯″紡</Button>
+                                    </UniformGrid>
+                                    <Button Grid.Row="2" Style="{StaticResource PrimaryButton}">鍒濆鍖�</Button>
+                                    <Button Grid.Row="3" Style="{StaticResource PrimaryButton}">鍋滄</Button>
+                                    <UniformGrid Grid.Row="4" Columns="3">
+                                        <Button Style="{StaticResource PrimaryButton}">璋冭瘯妯″紡</Button>
+                                        <Label Style="{StaticResource LabelText}" 
+                                               Margin="10,0,10,0"
+                                               BorderThickness="1" Content="鍑嗗濂�"/>
+                                        <Button Style="{StaticResource PrimaryButton}">璋冭瘯妯″紡</Button>
+                                    </UniformGrid>
+                                </Grid>
+                                
+                            </GroupBox>
+
+
+                        </WrapPanel>
+                    </Grid>
+                </Border>
+            </DockPanel>
+        </Grid>
+    </Border>
+</UserControl>
diff --git a/Plugin.ServoManage/ServoManage.xaml.cs b/Plugin.ServoManage/ServoManage.xaml.cs
new file mode 100644
index 0000000..d816844
--- /dev/null
+++ b/Plugin.ServoManage/ServoManage.xaml.cs
@@ -0,0 +1,39 @@
+锘縰sing HMI.Base;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Plugin.ServoManage
+{
+    /// <summary>
+    /// UserControl1.xaml 鐨勪氦浜掗�昏緫
+    /// </summary>
+    public partial class ServoManage: UserControl
+    {
+        public ServoManage()
+        {
+            InitializeComponent();
+        }
+
+        private void UserControl_Loaded(object sender, RoutedEventArgs e)
+        {
+
+        }
+
+        private void Button_Click(object sender, RoutedEventArgs e)
+        {
+
+        }
+    }
+}
diff --git a/Plugin.ServoManage/packages.config b/Plugin.ServoManage/packages.config
new file mode 100644
index 0000000..21b491c
--- /dev/null
+++ b/Plugin.ServoManage/packages.config
@@ -0,0 +1,6 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="log4net" version="3.0.4" targetFramework="net472" />
+  <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
+  <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
+</packages>
\ No newline at end of file
diff --git a/Plugin.TestResult/DataTable.xaml.cs b/Plugin.TestResult/DataTable.xaml.cs
index aa7f621..39e223c 100644
--- a/Plugin.TestResult/DataTable.xaml.cs
+++ b/Plugin.TestResult/DataTable.xaml.cs
@@ -3,7 +3,9 @@
 using Plugin.TestResult_WPF.Model;
 using SuperSocket.SocketBase.Protocol;
 using System;
+using System.Collections.Generic;
 using System.ComponentModel;
+using System.IO;
 using System.Runtime.CompilerServices;
 using System.Windows;
 using System.Windows.Controls;
@@ -76,6 +78,11 @@
         private TcpServer tcpServer;
         private string CountIniPath;
 
+        // 骞冲潎娓╁害
+        public List<double> tempratures = new List<double>();
+        public Dictionary<string, List<double>> detailTempratures
+            = new Dictionary<string, List<double>>();
+
         public DataTable(TestResultView parent, int index, string title,
             string countIniPath,
             BaseConfig config)
@@ -126,11 +133,23 @@
         public void SetTemperature(double t)
         {
             infoTable.temperature = t;
+            tempratures.Add(t);
             chart.AddData(t);
         }
 
         public void SetTemperature(string name, double t)
         {
+            List<double> list;
+            if (detailTempratures.ContainsKey(name))
+            {
+                list = detailTempratures[name];
+            }
+            else
+            {
+                list = new List<double>();
+                detailTempratures.Add(name, list);
+            }
+            list.Add(t);
             multiChart.AddData(name, t);
         }
 
@@ -201,6 +220,9 @@
         {
             chart.Clear();
             multiChart.Clear();
+
+            tempratures.Clear();
+            detailTempratures.Clear();
         }
 
         /// <summary>
@@ -363,5 +385,46 @@
         {
             StartTcpServer();
         }
+
+        public void SaveTempFile(string filePath)
+        {
+            try
+            {
+                FileInfo fi = new FileInfo(filePath);
+                if (!fi.Directory.Exists)
+                {
+                    fi.Directory.Create();  //鏂囦欢涓嶅瓨鍦紝鍒涘缓鏂囦欢
+                }
+
+                using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
+                using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
+                {
+                    string title = string.Join(",", detailTempratures.Keys) + ",骞冲潎鍊�";
+                    sw.WriteLine(title);
+
+                    for (int i = 0; i < tempratures.Count; i++)
+                    {
+                        string line = "";
+                        foreach (string key in detailTempratures.Keys)
+                        {
+                            if (detailTempratures[key] == null || detailTempratures[key].Count <= i)
+                            {
+                                line += ",";
+                            }
+                            else
+                            {
+                                line += $"{detailTempratures[key][i]},";
+                            }
+                        }
+                        line += tempratures[i];
+                        sw.WriteLine(line);
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine(ex.ToString());
+            }
+        }
     }
 }
diff --git a/Plugin.TestResult/Plugin.TestResult.csproj b/Plugin.TestResult/Plugin.TestResult.csproj
index 404f92f..47d09d8 100644
--- a/Plugin.TestResult/Plugin.TestResult.csproj
+++ b/Plugin.TestResult/Plugin.TestResult.csproj
@@ -58,8 +58,8 @@
     <Reference Include="HarfBuzzSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\HarfBuzzSharp.7.3.0.3\lib\net462\HarfBuzzSharp.dll</HintPath>
     </Reference>
-    <Reference Include="log4net, Version=3.0.3.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\log4net.3.0.3\lib\net462\log4net.dll</HintPath>
+    <Reference Include="log4net, Version=3.0.4.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\log4net.3.0.4\lib\net462\log4net.dll</HintPath>
     </Reference>
     <Reference Include="NationalInstruments.TestStand.Interop.AdapterAPI, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -97,7 +97,7 @@
       <HintPath>..\WPFProject\packages\OpenTK.3.3.1\lib\net20\OpenTK.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.2.2\lib\net472\Panuon.WPF.dll</HintPath>
+      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
diff --git a/Plugin.TestResult/TestResultView.xaml.cs b/Plugin.TestResult/TestResultView.xaml.cs
index c1d5f03..8cc204f 100644
--- a/Plugin.TestResult/TestResultView.xaml.cs
+++ b/Plugin.TestResult/TestResultView.xaml.cs
@@ -383,6 +383,17 @@
                     tables[ovenIndex].GetSingleCell(cellIndex).ClearInfo();
                     return;
                 }
+                if (MethodCode == 12)
+                {
+                    /// 淇濆瓨娓╁害鏂囦欢
+                    /// 
+                    strData = e.uiMsg.StringData;
+                    string[] datas = strData.Split(';');
+                    int ovenIndex = int.Parse(datas[0]);
+                    string folder = datas[1];
+                    tables[ovenIndex].SaveTempFile(folder);
+                    return;
+                }
             }
             catch (Exception ex)
             {
diff --git a/Plugin.TestResult/app.config b/Plugin.TestResult/app.config
index 3b5d9d8..907b804 100644
--- a/Plugin.TestResult/app.config
+++ b/Plugin.TestResult/app.config
@@ -4,7 +4,7 @@
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <dependentAssembly>
         <assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-3.0.3.0" newVersion="3.0.3.0" />
+        <bindingRedirect oldVersion="0.0.0.0-3.0.4.0" newVersion="3.0.4.0" />
       </dependentAssembly>
       <dependentAssembly>
         <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
diff --git a/Plugin.TestResult/packages.config b/Plugin.TestResult/packages.config
index dae6676..0b67ea1 100644
--- a/Plugin.TestResult/packages.config
+++ b/Plugin.TestResult/packages.config
@@ -4,10 +4,10 @@
   <package id="HarfBuzzSharp.NativeAssets.Linux" version="7.3.0.3" targetFramework="net472" />
   <package id="HarfBuzzSharp.NativeAssets.macOS" version="7.3.0.3" targetFramework="net472" />
   <package id="HarfBuzzSharp.NativeAssets.Win32" version="7.3.0.3" targetFramework="net472" />
-  <package id="log4net" version="3.0.3" targetFramework="net472" />
+  <package id="log4net" version="3.0.4" targetFramework="net472" />
   <package id="OpenTK" version="3.3.1" targetFramework="net472" />
   <package id="OpenTK.GLWpfControl" version="3.3.0" targetFramework="net472" />
-  <package id="Panuon.WPF" version="1.1.2.2" targetFramework="net472" />
+  <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
   <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
   <package id="ScottPlot" version="5.0.47" targetFramework="net472" />
   <package id="ScottPlot.WPF" version="5.0.47" targetFramework="net472" />
diff --git a/Plugin.TsExecution/Plugin.TsExecution.csproj b/Plugin.TsExecution/Plugin.TsExecution.csproj
index 4e19d52..16de6e0 100644
--- a/Plugin.TsExecution/Plugin.TsExecution.csproj
+++ b/Plugin.TsExecution/Plugin.TsExecution.csproj
@@ -58,8 +58,8 @@
     <Reference Include="HarfBuzzSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\HarfBuzzSharp.7.3.0.3\lib\net462\HarfBuzzSharp.dll</HintPath>
     </Reference>
-    <Reference Include="log4net, Version=3.0.3.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\log4net.3.0.3\lib\net462\log4net.dll</HintPath>
+    <Reference Include="log4net, Version=3.0.4.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\log4net.3.0.4\lib\net462\log4net.dll</HintPath>
     </Reference>
     <Reference Include="NationalInstruments.TestStand.Interop.API, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL">
       <EmbedInteropTypes>True</EmbedInteropTypes>
@@ -72,7 +72,7 @@
       <HintPath>..\WPFProject\packages\OpenTK.3.3.1\lib\net20\OpenTK.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.2.2\lib\net472\Panuon.WPF.dll</HintPath>
+      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
diff --git a/Plugin.TsExecution/TsExecution.xaml.cs b/Plugin.TsExecution/TsExecution.xaml.cs
index 4e71b42..c06a55f 100644
--- a/Plugin.TsExecution/TsExecution.xaml.cs
+++ b/Plugin.TsExecution/TsExecution.xaml.cs
@@ -238,16 +238,21 @@
 
         private void RefershUI()
         {
-            if (this.tsSockets.Count == 0)
+            panel.Children.Clear();
+            //閲嶆柊鐢熸垚瀛愰潰鏉�
+            for (int i = 0; i < this.socketNum; i++)
             {
-                panel.Children.Clear();
-                //閲嶆柊鐢熸垚瀛愰潰鏉�
-                for (int i = 0; i < this.socketNum; i++)
-                {
-                    SingleControl control = new SingleControl(i, CountIniPath);
-                    panel.Children.Add(control);
-                    tsSockets.Add(control);
-                }
+                SingleControl control = new SingleControl(i, CountIniPath);
+                panel.Children.Add(control);
+                tsSockets.Add(control);
+            }
+            if (tsSockets.Count == 1)
+            {
+                panel.Columns = 1;
+            }
+            else
+            {
+                panel.Columns = 2;
             }
         }
 
@@ -500,100 +505,106 @@
         /// <param name="e"></param>
         private void AxApplicationMgr_UIMessageEvent(object sender, _ApplicationMgrEvents_UIMessageEventEvent e)
         {
-            int EventCase = Convert.ToInt32(e.uiMsg.Event);
-            int Index = Convert.ToInt16(e.uiMsg.NumericData);//SocketIndex
-
-            switch (EventCase)
+            try
             {
-                case 10001://浼犻�扴ocketContext
-                    tsSockets[Index].SequenceFileContext = (SequenceContext)e.uiMsg.ActiveXData;
-                    break;
+                int EventCase = Convert.ToInt32(e.uiMsg.Event);
+                int Index = Convert.ToInt16(e.uiMsg.NumericData);//SocketIndex
+                switch (EventCase)
+                {
+                    case 10001://浼犻�扴ocketContext
+                        tsSockets[Index].SequenceFileContext = (SequenceContext)e.uiMsg.ActiveXData;
+                        break;
 
-                case 10002://鏇存柊娴嬭瘯鐘舵��
-                    string status = e.uiMsg.StringData;
-                    this.tsSockets[Index].UpdateStatus(status);
-                    this.UpdateTestCounter();
-                    break;
+                    case 10002://鏇存柊娴嬭瘯鐘舵��
+                        string status = e.uiMsg.StringData;
+                        this.tsSockets[Index].UpdateStatus(status);
+                        this.UpdateTestCounter();
+                        break;
 
-                case 10003://鍙戦�佹祴璇曟暟鎹�
-                    string[] TestItems = e.uiMsg.StringData.Split('\t');
-                    tsSockets[Index].AddTestData(TestItems[0], TestItems[4], TestItems[1], TestItems[2], TestItems[3], TestItems[5]);
+                    case 10003://鍙戦�佹祴璇曟暟鎹�
+                        string[] TestItems = e.uiMsg.StringData.Split('\t');
+                        tsSockets[Index].AddTestData(TestItems[0], TestItems[4], TestItems[1], TestItems[2], TestItems[3], TestItems[5]);
 
-                    break;
+                        break;
 
-                case 10004://鍙戦�佹祴璇曡繃绋嬩俊鎭�
-                    this.tsSockets[Index].CurrentStep = e.uiMsg.StringData;
-                    break;
+                    case 10004://鍙戦�佹祴璇曡繃绋嬩俊鎭�
+                        this.tsSockets[Index].CurrentStep = e.uiMsg.StringData;
+                        break;
 
-                case 10005://鍒濆鍖栨祴璇曟暟鎹紝娓呯┖娴嬭瘯鏁版嵁
-                    this.tsSockets[Index].IniTestData();
-                    break;
+                    case 10005://鍒濆鍖栨祴璇曟暟鎹紝娓呯┖娴嬭瘯鏁版嵁
+                        this.tsSockets[Index].IniTestData();
+                        break;
 
-                case 10006://鍙戦�佷骇鍝佹潯鐮�
-                    this.tsSockets[Index].Barcode = e.uiMsg.StringData;
-                    break;
+                    case 10006://鍙戦�佷骇鍝佹潯鐮�
+                        this.tsSockets[Index].Barcode = e.uiMsg.StringData;
+                        break;
 
-                case 10007://寮�濮嬫祴璇曡鏃�
-                    tsSockets[Index].ElapseTime = "Start Timing";
-                    BtnStopSeq.IsEnabled = false;
-                    break;
+                    case 10007://寮�濮嬫祴璇曡鏃�
+                        tsSockets[Index].ElapseTime = "Start Timing";
+                        BtnStopSeq.IsEnabled = false;
+                        break;
 
-                case 10008://鍋滄娴嬭瘯璁℃椂
-                    tsSockets[Index].ElapseTime = "Stop Timing";
-                    BtnStopSeq.IsEnabled = true;
-                    break;
+                    case 10008://鍋滄娴嬭瘯璁℃椂
+                        tsSockets[Index].ElapseTime = "Stop Timing";
+                        BtnStopSeq.IsEnabled = true;
+                        break;
 
-                case 10009:
-                    // reset the value of controls units failed/pass rate
-                    break;
+                    case 10009:
+                        // 
+                        break;
 
-                case 10010:
+                    case 10010:
 
-                    //PropertyObj.SetValBoolean("Locals.MD5_Used", 0, true);
-                    //PropertyObj.SetValVariant("FileGlobals.MD5_Value", 0, MD5_DATA);
-                    //PropertyObj.SetValVariant("StationGlobals.MD5", 0, MD5_DATA);
-                    break;
+                        //PropertyObj.SetValBoolean("Locals.MD5_Used", 0, true);
+                        //PropertyObj.SetValVariant("FileGlobals.MD5_Value", 0, MD5_DATA);
+                        //PropertyObj.SetValVariant("StationGlobals.MD5", 0, MD5_DATA);
+                        break;
 
-                case 10011:
-                    // write model
+                    case 10011:
+                        // write model
 
-                    break;
+                        break;
 
-                case 10012:
-                    // read model
+                    case 10012:
+                        // read model
 
-                    break;
+                        break;
 
-                case 10013:
-                    // read continue
+                    case 10013:
+                        // read continue
 
 
-                    break;
+                        break;
 
-                case 10014:
+                    case 10014:
 
-                    break;
+                        break;
 
-                case 10015:
+                    case 10015:
 
-                    break;
-                case 10016://鏄剧ず3D鎷兼帴鍥剧墖
+                        break;
+                    case 10016://鏄剧ず3D鎷兼帴鍥剧墖
 
-                    break;
-                case 10017://鏇存柊娴嬭瘯璁℃椂锛岄拡瀵归儴鍒嗚鏃舵湁PLC瀹屾垚鐨勯」鐩�
-                    this.tsSockets[Index].ElapseTime = e.uiMsg.StringData;
-                    break;
-                case (int)UIMessageCodes.UIMsg_EndExecution://鎵ц缁撴潫
-                    this.BtnStartSeq.IsEnabled = true;
-                    this.BtnStopSeq.IsEnabled = true;
-                    // this.ReleaseSequenceFile();
-                    break;
-                case 10030://鏄剧ず娴嬭瘯杩涘害
-                    int ProcessVal = Convert.ToInt32(e.uiMsg.StringData);
-                    this.tsSockets[Index].SetTestProcess(ProcessVal);
-                    break;
-                default:
-                    break;
+                        break;
+                    case 10017://鏇存柊娴嬭瘯璁℃椂锛岄拡瀵归儴鍒嗚鏃舵湁PLC瀹屾垚鐨勯」鐩�
+                        this.tsSockets[Index].ElapseTime = e.uiMsg.StringData;
+                        break;
+                    case (int)UIMessageCodes.UIMsg_EndExecution://鎵ц缁撴潫
+                        this.BtnStartSeq.IsEnabled = true;
+                        this.BtnStopSeq.IsEnabled = true;
+                        // this.ReleaseSequenceFile();
+                        break;
+                    case 10030://鏄剧ず娴嬭瘯杩涘害
+                        int ProcessVal = Convert.ToInt32(e.uiMsg.StringData);
+                        this.tsSockets[Index].SetTestProcess(ProcessVal);
+                        break;
+                    default:
+                        break;
+                }
+            }
+            catch (Exception ex)
+            {
+                log.Warn("Ts Event Error.", ex);
             }
         }
 
diff --git a/Plugin.TsExecution/packages.config b/Plugin.TsExecution/packages.config
index c9d3fbb..5f0c729 100644
--- a/Plugin.TsExecution/packages.config
+++ b/Plugin.TsExecution/packages.config
@@ -4,10 +4,10 @@
   <package id="HarfBuzzSharp.NativeAssets.Linux" version="7.3.0.3" targetFramework="net472" />
   <package id="HarfBuzzSharp.NativeAssets.macOS" version="7.3.0.3" targetFramework="net472" />
   <package id="HarfBuzzSharp.NativeAssets.Win32" version="7.3.0.3" targetFramework="net472" />
-  <package id="log4net" version="3.0.3" targetFramework="net472" />
+  <package id="log4net" version="3.0.4" targetFramework="net472" />
   <package id="OpenTK" version="3.3.1" targetFramework="net472" />
   <package id="OpenTK.GLWpfControl" version="3.3.0" targetFramework="net472" />
-  <package id="Panuon.WPF" version="1.1.2.2" targetFramework="net472" />
+  <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
   <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
   <package id="ScottPlot" version="5.0.54" targetFramework="net472" />
   <package id="ScottPlot.WPF" version="5.0.54" targetFramework="net472" />
diff --git a/WPFProject/App.config b/WPFProject/App.config
index e806f9e..dbe641b 100644
--- a/WPFProject/App.config
+++ b/WPFProject/App.config
@@ -5,7 +5,7 @@
 	</startup>
 	<runtime>
 		<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-			<probing privatePath="Libs;ThirdParty;Plugin;3rds;" />
+			<probing privatePath="Libs;ThirdParty;Plugin;3rds;"/>
 			<dependentAssembly>
 				<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
 				<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
@@ -24,7 +24,7 @@
 			</dependentAssembly>
 			<dependentAssembly>
 				<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
-				<bindingRedirect oldVersion="0.0.0.0-3.0.3.0" newVersion="3.0.3.0" />
+				<bindingRedirect oldVersion="0.0.0.0-3.0.4.0" newVersion="3.0.4.0" />
 			</dependentAssembly>
 		</assemblyBinding>
 	</runtime>
diff --git a/WPFProject/App.xaml b/WPFProject/App.xaml
index 74e1851..d38cde6 100644
--- a/WPFProject/App.xaml
+++ b/WPFProject/App.xaml
@@ -21,6 +21,7 @@
             <Style TargetType="{x:Type pu:FormGroup}" BasedOn="{StaticResource InputFormGroupStyle}"></Style>
             <uic:PathImageConverter x:Key="path2Image"/>
             <uic:DataGridRowNumberConverter x:Key="rowNumber"/>
+            <uic:VisibilityBoolConverter x:Key="vbConverter"/>
             <uic:DataGridRowFlagConverter x:Key="rowFlag"/>
             <hc:LangConverter x:Key="lc"/>
         </ResourceDictionary>
diff --git a/WPFProject/App.xaml.cs b/WPFProject/App.xaml.cs
index cfb8c29..545b7cc 100644
--- a/WPFProject/App.xaml.cs
+++ b/WPFProject/App.xaml.cs
@@ -4,6 +4,8 @@
 using log4net;
 using Panuon.WPF.UI;
 using System;
+using System.IO;
+using System.Reflection;
 using System.Threading;
 using System.Windows;
 using WPFProject.Utils;
@@ -34,9 +36,11 @@
         private static Mutex mutex;
         private void Application_Startup(object sender, StartupEventArgs e)
         {
-            mutex = new System.Threading.Mutex(true, "TestPlatform_OnlyRun_CRNS");
+            mutex = new Mutex(true, "TestPlatform_OnlyRun_CRNS");
             if (mutex.WaitOne(0, false))
             {
+                AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
+
                 LangUtil.Load();
                 SystemSetting.SystemSettingChanged += SystemSetting_SystemSettingChanged;
                 ToastHelper.Register(new MainToastHandler());
@@ -51,6 +55,26 @@
             }
         }
 
+        private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
+        {
+            // 鑾峰彇璇锋眰鍔犺浇鐨勭▼搴忛泦鍚嶇О
+            string assemblyName = new AssemblyName(args.Name).Name;
+
+            string[] dirs = new string[] { "3rds", "Libs" };
+
+            foreach (string dir in dirs)
+            {
+                string dllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, dir, $"{assemblyName}.dll");
+                if (File.Exists(dllPath))
+                {
+                    // 濡傛灉渚濊禆 DLL 瀛樺湪锛屽垯鍔犺浇骞惰繑鍥炲畠
+                    return Assembly.LoadFrom(dllPath);
+                }
+            }
+            // 鍚﹀垯杩斿洖 null
+            return null;
+        }
+
         private void SystemSetting_SystemSettingChanged(object sender, SystemSetting e)
         {
             LangUtil.LoadLang();
diff --git a/WPFProject/Controls/HolderForm.Designer.cs b/WPFProject/Controls/HolderForm.Designer.cs
new file mode 100644
index 0000000..1ac238f
--- /dev/null
+++ b/WPFProject/Controls/HolderForm.Designer.cs
@@ -0,0 +1,59 @@
+锘縩amespace WPFProject.Controls
+{
+    partial class HolderForm
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.panel1 = new System.Windows.Forms.Panel();
+            this.SuspendLayout();
+            // 
+            // panel1
+            // 
+            this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.panel1.Location = new System.Drawing.Point(0, 0);
+            this.panel1.Name = "panel1";
+            this.panel1.Size = new System.Drawing.Size(800, 450);
+            this.panel1.TabIndex = 0;
+            // 
+            // HolderForm
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 18F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(800, 450);
+            this.Controls.Add(this.panel1);
+            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
+            this.Name = "HolderForm";
+            this.Text = "HolderForm";
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Panel panel1;
+    }
+}
\ No newline at end of file
diff --git a/WPFProject/Controls/HolderForm.cs b/WPFProject/Controls/HolderForm.cs
new file mode 100644
index 0000000..f0e9566
--- /dev/null
+++ b/WPFProject/Controls/HolderForm.cs
@@ -0,0 +1,54 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using System.Windows.Threading;
+
+namespace WPFProject.Controls
+{
+    public partial class HolderForm : Form
+    {
+        private MaskControl maskPanel = new MaskControl
+        {
+            Dock = DockStyle.Fill,
+            Visible = false
+        };
+        public HolderForm()
+        {
+            InitializeComponent();
+            this.Controls.Add(maskPanel);
+        }
+
+        public object Content { get; private set; }
+
+        public void UpdateChild(object content)
+        {
+            this.Content = content;
+            if (content is Form form)
+            {
+                form.TopLevel = false;
+                form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
+                form.Dock = System.Windows.Forms.DockStyle.Fill;
+                this.Controls.Clear();
+                this.Controls.Add(maskPanel);
+                this.Controls.Add(form);
+                form.Show();
+            }
+        }
+
+        public void ShowMask()
+        {
+            maskPanel.ShowLoad(this.Location, this.Size);
+        }
+
+        public void HideMask()
+        {
+            maskPanel.HideLoad();
+        }
+    }
+}
diff --git a/WPFProject/Controls/HolderForm.resx b/WPFProject/Controls/HolderForm.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/WPFProject/Controls/HolderForm.resx
@@ -0,0 +1,120 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/WPFProject/Controls/MainTabControl.xaml b/WPFProject/Controls/MainTabControl.xaml
index 9f051b9..2950b42 100644
--- a/WPFProject/Controls/MainTabControl.xaml
+++ b/WPFProject/Controls/MainTabControl.xaml
@@ -5,6 +5,7 @@
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
              xmlns:local="clr-namespace:WPFProject.Controls"
              mc:Ignorable="d" 
+             Loaded="UserControl_Loaded"
              Foreground="#51555f"
              d:DesignHeight="450" d:DesignWidth="800">
     <UserControl.Resources>
diff --git a/WPFProject/Controls/MainTabControl.xaml.cs b/WPFProject/Controls/MainTabControl.xaml.cs
index 37e847e..1e57271 100644
--- a/WPFProject/Controls/MainTabControl.xaml.cs
+++ b/WPFProject/Controls/MainTabControl.xaml.cs
@@ -1,10 +1,15 @@
-锘縰sing System.Collections.ObjectModel;
+锘縰sing HMI.Base;
+using HMI.Core.Api;
+using Microsoft.DwayneNeed.Interop;
+using Panuon.WPF.UI;
+using System.Collections.ObjectModel;
 using System.ComponentModel;
 using System.Runtime.CompilerServices;
 using System.Windows;
 using System.Windows.Controls;
-using HMI.Base;
-using HMI.Core.Api;
+using System.Windows.Data;
+using System.Windows.Forms.Integration;
+using System.Windows.Media;
 using WPFProject.UI;
 
 namespace WPFProject.Controls
@@ -33,12 +38,14 @@
         }
         #endregion
 
+        private WinFormHolder winFormHolder;
         public MainTabControl()
         {
             IPlugin plugin = new WorkControl();
-            MenuItems = new ObservableCollection<PluginInfo>( PluginLoader.GetLoader().Menus);
+            MenuItems = new ObservableCollection<PluginInfo>(PluginLoader.GetLoader().Menus);
             SubMenuItems = MenuItems[0].Children;
             this.DataContext = this;
+            winFormHolder = new WinFormHolder();
             InitializeComponent();
         }
 
@@ -145,12 +152,40 @@
             if (e.AddedItems?.Count > 0)
             {
                 var data = (PluginInfo)e.AddedItems[0];
-                var content = (UIElement)data.Content;
-                var last = (IPlugin)page.Child;
-                last?.DeActive();
-                page.Child = content;
-                ((IPlugin)content)?.Active();
+                var content = data.Content;
+                var last = page.Child;
+                PluginPackage.Get(last)?.DeActive();
+                if (data.Type == "WinForm")
+                {
+                    if (content is System.Windows.Forms.Form form)
+                    {
+                        winFormHolder.Content = form;
+                    }
+                    else
+                    {
+                        winFormHolder.Content = content;
+                    }
+                    page.Child = winFormHolder;
+                }
+                else
+                {
+                    page.Child = (UIElement)content;
+                }
+
+                PluginPackage.Get(content)?.Active();
             }
         }
+
+        private void UserControl_Loaded(object sender, RoutedEventArgs e)
+        {
+            var ss = ((WindowX)Window.GetWindow(this));
+            Binding binding = new Binding("IsMaskVisible")
+            {
+                Source = ((WindowX)Window.GetWindow(this)),
+                Mode = BindingMode.TwoWay,
+                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
+            };
+            winFormHolder.SetBinding(WinFormHolder.MaskVisiableProperty, binding);
+        }
     }
 }
diff --git a/WPFProject/Controls/MaskControl.Designer.cs b/WPFProject/Controls/MaskControl.Designer.cs
new file mode 100644
index 0000000..c1babc9
--- /dev/null
+++ b/WPFProject/Controls/MaskControl.Designer.cs
@@ -0,0 +1,36 @@
+锘縩amespace WPFProject.Controls
+{
+    partial class MaskControl
+    {
+        /// <summary>
+        /// 蹇呴渶鐨勮璁″櫒鍙橀噺銆�
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// 娓呯悊鎵�鏈夋鍦ㄤ娇鐢ㄧ殑璧勬簮銆�
+        /// </summary>
+        /// <param name="disposing">濡傛灉搴旈噴鏀炬墭绠¤祫婧愶紝涓� true锛涘惁鍒欎负 false銆�</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region 缁勪欢璁捐鍣ㄧ敓鎴愮殑浠g爜
+
+        /// <summary>
+        /// 璁捐鍣ㄦ敮鎸佹墍闇�鐨勬柟娉� - 涓嶈淇敼
+        /// 浣跨敤浠g爜缂栬緫鍣ㄤ慨鏀规鏂规硶鐨勫唴瀹广��
+        /// </summary>
+        private void InitializeComponent()
+        {
+            components = new System.ComponentModel.Container();
+        }
+
+        #endregion
+    }
+}
diff --git a/WPFProject/Controls/MaskControl.cs b/WPFProject/Controls/MaskControl.cs
new file mode 100644
index 0000000..cdc1b42
--- /dev/null
+++ b/WPFProject/Controls/MaskControl.cs
@@ -0,0 +1,72 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace WPFProject.Controls
+{
+    public partial class MaskControl : Panel
+    {
+        public MaskControl()
+        {
+            SetStyle(ControlStyles.Opaque, true);//璁剧疆鑳屾櫙閫忔槑
+            SetStyle(ControlStyles.SupportsTransparentBackColor, true);//璁剧疆鑳屾櫙閫忔槑
+            base.CreateControl();
+            this.BackColor = Color.White;
+            this.Visible = false;
+        }
+
+        //protected override CreateParams CreateParams
+        //{
+        //    get
+        //    {
+        //        CreateParams cp = base.CreateParams;
+        //        cp.ExStyle |= 0x00000020; // 寮�鍚� WS_EX_TRANSPARENT,浣挎帶浠舵敮鎸侀�忔槑
+        //        return cp;
+        //    }
+        //}
+
+        protected override void OnPaint(PaintEventArgs pe)
+        {
+            Pen labelBorderPen;
+            SolidBrush labelBackColorBrush;
+            Color cl = Color.FromArgb(128, this.BackColor);
+            labelBorderPen = new Pen(cl, 0);
+            labelBackColorBrush = new SolidBrush(cl);
+            base.OnPaint(pe);
+            pe.Graphics.DrawRectangle(labelBorderPen, 0, 0, this.Width, this.Height);
+            pe.Graphics.FillRectangle(labelBackColorBrush, 0, 0, this.Width, this.Height);
+        }
+
+        /// <summary>
+        /// 鏄剧ず鍔犺浇
+        /// </summary>
+        public void ShowLoad(Point location, Size size)
+        {
+            this.Location = location;
+            this.Size = size;
+            this.BringToFront();
+            this.Dock = DockStyle.Fill;
+            this.Visible = true;
+        }
+
+
+
+        /// <summary>
+
+        /// 闅愯棌鍔犺浇
+
+        /// </summary>
+
+        public void HideLoad()
+        {
+            this.Visible = false;
+        }
+
+    }
+}
diff --git a/WPFProject/Controls/MenuTabControl.xaml.cs b/WPFProject/Controls/MenuTabControl.xaml.cs
index 9a765d1..71a1e5e 100644
--- a/WPFProject/Controls/MenuTabControl.xaml.cs
+++ b/WPFProject/Controls/MenuTabControl.xaml.cs
@@ -156,8 +156,10 @@
             foreach (IconTabItem item in Items)
             {
                 item.Visibility = ItemVisibility;
-                if (item.Children != null) {
-                    foreach (var child in item.Children) {
+                if (item.Children != null)
+                {
+                    foreach (var child in item.Children)
+                    {
                         child.Visibility = ItemVisibility;
                     }
                 }
diff --git a/WPFProject/Controls/WinFormHolder.xaml b/WPFProject/Controls/WinFormHolder.xaml
new file mode 100644
index 0000000..5d72f93
--- /dev/null
+++ b/WPFProject/Controls/WinFormHolder.xaml
@@ -0,0 +1,13 @@
+锘�<UserControl x:Class="WPFProject.Controls.WinFormHolder"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:WPFProject.Controls"
+             mc:Ignorable="d" 
+             x:Name="control"
+             d:DesignHeight="450" d:DesignWidth="800">
+    <Grid>
+        <WindowsFormsHost x:Name="host"/>
+    </Grid>
+</UserControl>
diff --git a/WPFProject/Controls/WinFormHolder.xaml.cs b/WPFProject/Controls/WinFormHolder.xaml.cs
new file mode 100644
index 0000000..5dff207
--- /dev/null
+++ b/WPFProject/Controls/WinFormHolder.xaml.cs
@@ -0,0 +1,63 @@
+锘縰sing System.Windows;
+using System.Windows.Controls;
+
+namespace WPFProject.Controls
+{
+    /// <summary>
+    /// WinFormHolder.xaml 鐨勪氦浜掗�昏緫
+    /// </summary>
+    public partial class WinFormHolder : UserControl
+    {
+
+        private HolderForm holderForm;
+        public WinFormHolder()
+        {
+            holderForm = new HolderForm();
+            InitializeComponent();
+            holderForm.TopLevel = false;
+            holderForm.Dock = System.Windows.Forms.DockStyle.Fill;
+            host.Child = holderForm;
+        }
+
+        public object Content
+        {
+            get => holderForm?.Content;
+            set => holderForm?.UpdateChild(value);
+        }
+
+        public bool MaskVisiable
+        {
+            get => GetMaskVisiable(this);
+            set => SetMaskVisiable(this, value);
+        }
+
+        public static bool GetMaskVisiable(WinFormHolder obj)
+        {
+            return (bool)obj.GetValue(MaskVisiableProperty);
+        }
+
+        public static void SetMaskVisiable(WinFormHolder obj, bool? value)
+        {
+            obj.SetValue(MaskVisiableProperty, value);
+        }
+
+        public static readonly DependencyProperty MaskVisiableProperty =
+            DependencyProperty.RegisterAttached("MaskVisiable", typeof(bool?), typeof(WinFormHolder)
+                , new PropertyMetadata(null, OnSpaceChanged));
+
+        private static void OnSpaceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            if (d is WinFormHolder obj)
+            {
+                if (e.NewValue is bool flag && flag == true)
+                {
+                    obj.holderForm.ShowMask();
+                }
+                else
+                {
+                    obj.holderForm.HideMask();
+                }
+            }
+        }
+    }
+}
diff --git a/WPFProject/Lang/zh-CN/ServoManage.json b/WPFProject/Lang/zh-CN/ServoManage.json
new file mode 100644
index 0000000..929f988
--- /dev/null
+++ b/WPFProject/Lang/zh-CN/ServoManage.json
@@ -0,0 +1,6 @@
+{
+  "svo.title": "浼烘湇绠$悊",
+  "svo.list": "浼烘湇鍒楄〃",
+  "svo.name": "鍚嶇О",
+  "svo.product": "浜у搧鍨嬪彿",
+}
\ No newline at end of file
diff --git a/WPFProject/PanuonWindow.xaml b/WPFProject/PanuonWindow.xaml
index 4e6bdc8..e2f650f 100644
--- a/WPFProject/PanuonWindow.xaml
+++ b/WPFProject/PanuonWindow.xaml
@@ -12,15 +12,16 @@
             WindowState="Maximized"
             x:Name="window"
             BorderBrush="Transparent"
-            Loaded="window_Loaded"
             pu:WindowXCaption.Buttons="All"
             xmlns:sys="clr-namespace:System;assembly=mscorlib"
             xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
             xmlns:hc="clr-namespace:HMI.Core;assembly=HMI.Core"
             Closed="window_Closed"
+            Topmost="False"
             pu:WindowXCaption.Background="Transparent"
             pu:WindowXCaption.Height="80"
-            pu:WindowXCaption.Foreground="#FFF" >
+            IsOverlayerVisible="True"
+            pu:WindowXCaption.Foreground="#FFF">
     <Window.Resources>
         <hc:LangConverter x:Key="lc"/>
         <Style x:Key="UserMenu" TargetType="Menu" BasedOn="{StaticResource {x:Static pu:StyleKeys.MenuStyle}}">
diff --git a/WPFProject/PanuonWindow.xaml.cs b/WPFProject/PanuonWindow.xaml.cs
index 375df69..8f84a71 100644
--- a/WPFProject/PanuonWindow.xaml.cs
+++ b/WPFProject/PanuonWindow.xaml.cs
@@ -22,7 +22,7 @@
     {
         public PanuonWindow()
         {
-            Loaded += PanuonWindow_Loaded;
+            this.Loaded += PanuonWindow_Loaded;
         }
 
         private UserInfo currentUser;
@@ -41,7 +41,9 @@
             RefrshConfig();
             InitializeComponent();
             userMenu.Header = this.lang("App.Welcome", UserInfo.User.Name);
-            ShowMenu = true;
+            ShowMenu = true; 
+            Application.Current.MainWindow = this;
+            SystemSetting.SystemSettingChanged += SystemSetting_SystemSettingChanged;
         }
 
         private void RefrshConfig()
@@ -100,11 +102,6 @@
             //ScaleTransform verticalFlipTransform = new ScaleTransform(1, temp * -1);
             //btn.RenderTransform = verticalFlipTransform;
             //menuTab.ChangeItemVisibility();
-        }
-
-        private void window_Loaded(object sender, RoutedEventArgs e)
-        {
-            SystemSetting.SystemSettingChanged += SystemSetting_SystemSettingChanged;
         }
 
         private void SystemSetting_SystemSettingChanged(object sender, SystemSetting e)
diff --git a/WPFProject/TextFile1.txt b/WPFProject/TextFile1.txt
index 680b8c0..228ea1f 100644
--- a/WPFProject/TextFile1.txt
+++ b/WPFProject/TextFile1.txt
@@ -11,6 +11,7 @@
 move /y "$(TargeDir)HMI.SettingControl.dll" $(TargeDir)Plugin\HMI.SettingControl.dll"
 move /y "$(TargeDir)Plugin.TestResult.dll" $(TargeDir)Plugin\Plugin.TestResult.dll"
 move /y "$(TargeDir)Plugin.TsExecution.dll" $(TargeDir)Plugin\Plugin.TsExecution.dll"
+move /y "$(TargeDir)Plugin.ServoManage.dll" $(TargeDir)Plugin\Plugin.ServoManage.dll"
 
 setlocal enabledelayedexpansion
 
diff --git a/WPFProject/WPFProject.csproj b/WPFProject/WPFProject.csproj
index 0276b9d..3fa1e7a 100644
--- a/WPFProject/WPFProject.csproj
+++ b/WPFProject/WPFProject.csproj
@@ -107,8 +107,14 @@
     <Reference Include="HandyControl, Version=3.4.0.0, Culture=neutral, PublicKeyToken=45be8712787a1e5b, processorArchitecture=MSIL">
       <HintPath>packages\HandyControl.3.4.0\lib\net472\HandyControl.dll</HintPath>
     </Reference>
-    <Reference Include="log4net, Version=3.0.3.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
-      <HintPath>packages\log4net.3.0.3\lib\net462\log4net.dll</HintPath>
+    <Reference Include="log4net, Version=3.0.4.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
+      <HintPath>packages\log4net.3.0.4\lib\net462\log4net.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.DwayneNeed">
+      <HintPath>..\Libs\Microsoft.DwayneNeed.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.DwayneNeed.Win32">
+      <HintPath>..\Libs\Microsoft.DwayneNeed.Win32.dll</HintPath>
     </Reference>
     <Reference Include="Microsoft.Xaml.Behaviors, Version=1.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
       <HintPath>packages\Microsoft.Xaml.Behaviors.Wpf.1.1.39\lib\net45\Microsoft.Xaml.Behaviors.dll</HintPath>
@@ -117,7 +123,7 @@
       <HintPath>packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>packages\Panuon.WPF.1.1.2.2\lib\net472\Panuon.WPF.dll</HintPath>
+      <HintPath>packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
     <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
@@ -190,14 +196,29 @@
       <SubType>Designer</SubType>
     </ApplicationDefinition>
     <Compile Include="Controls\DpPlugin.cs" />
+    <Compile Include="Controls\HolderForm.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Controls\HolderForm.Designer.cs">
+      <DependentUpon>HolderForm.cs</DependentUpon>
+    </Compile>
     <Compile Include="Controls\InnerWindow.xaml.cs">
       <DependentUpon>InnerWindow.xaml</DependentUpon>
     </Compile>
     <Compile Include="Controls\MainTabControl.xaml.cs">
       <DependentUpon>MainTabControl.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Controls\MaskControl.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="Controls\MaskControl.Designer.cs">
+      <DependentUpon>MaskControl.cs</DependentUpon>
+    </Compile>
     <Compile Include="Controls\MinInnerWindow.xaml.cs">
       <DependentUpon>MinInnerWindow.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Controls\WinFormHolder.xaml.cs">
+      <DependentUpon>WinFormHolder.xaml</DependentUpon>
     </Compile>
     <Compile Include="Entity\PluginLoadMessage.cs" />
     <Compile Include="Entity\PluginSettingInfo.cs" />
@@ -276,6 +297,10 @@
       <Generator>MSBuild:Compile</Generator>
     </Page>
     <Page Include="Controls\MinInnerWindow.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="Controls\WinFormHolder.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
@@ -404,6 +429,9 @@
     </Content>
     <Resource Include="Resources\Background.png" />
     <Resource Include="Resources\JingCeLogo.png" />
+    <EmbeddedResource Include="Controls\HolderForm.resx">
+      <DependentUpon>HolderForm.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="Forms\Form1.resx">
       <DependentUpon>Form1.cs</DependentUpon>
     </EmbeddedResource>
@@ -463,6 +491,9 @@
     <Content Include="Lang\en-US\TestResult.json">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </Content>
+    <Content Include="Lang\zh-CN\ServoManage.json">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
     <None Include="packages.config" />
     <None Include="Properties\app.manifest" />
     <None Include="Properties\Settings.settings">
@@ -514,6 +545,10 @@
       <Project>{de4205c6-5923-46fd-a4b9-65169bf61c75}</Project>
       <Name>HMI.MenuManage</Name>
     </ProjectReference>
+    <ProjectReference Include="..\Plugin.ServoManage\Plugin.ServoManage.csproj">
+      <Project>{1853e00f-6865-4bc6-974b-6a5e1c00bafe}</Project>
+      <Name>Plugin.ServoManage</Name>
+    </ProjectReference>
     <ProjectReference Include="..\Plugin.TestResult\Plugin.TestResult.csproj">
       <Project>{7375b74c-b6bf-4814-9838-e1caacad1897}</Project>
       <Name>Plugin.TestResult</Name>
@@ -555,6 +590,7 @@
 move /y "$(TargeDir)HMI.SettingControl.dll" $(TargeDir)Plugin\HMI.SettingControl.dll"
 move /y "$(TargeDir)Plugin.TestResult.dll" $(TargeDir)Plugin\Plugin.TestResult.dll"
 move /y "$(TargeDir)Plugin.TsExecution.dll" $(TargeDir)Plugin\Plugin.TsExecution.dll"
+move /y "$(TargeDir)Plugin.ServoManage.dll" $(TargeDir)Plugin\Plugin.ServoManage.dll"
 
 setlocal enabledelayedexpansion
 
diff --git a/WPFProject/WPFProject.sln b/WPFProject/WPFProject.sln
index c443e15..d7f5c5a 100644
--- a/WPFProject/WPFProject.sln
+++ b/WPFProject/WPFProject.sln
@@ -39,6 +39,8 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HMI.Util", "..\HMI.Util\HMI.Util.csproj", "{AFEA100A-9223-448D-AB10-3015D93DD98C}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.ServoManage", "..\Plugin.ServoManage\Plugin.ServoManage.csproj", "{1853E00F-6865-4BC6-974B-6A5E1C00BAFE}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -191,6 +193,14 @@
 		{AFEA100A-9223-448D-AB10-3015D93DD98C}.Release|Any CPU.Build.0 = Release|Any CPU
 		{AFEA100A-9223-448D-AB10-3015D93DD98C}.Release|x64.ActiveCfg = Release|Any CPU
 		{AFEA100A-9223-448D-AB10-3015D93DD98C}.Release|x64.Build.0 = Release|Any CPU
+		{1853E00F-6865-4BC6-974B-6A5E1C00BAFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{1853E00F-6865-4BC6-974B-6A5E1C00BAFE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{1853E00F-6865-4BC6-974B-6A5E1C00BAFE}.Debug|x64.ActiveCfg = Debug|x64
+		{1853E00F-6865-4BC6-974B-6A5E1C00BAFE}.Debug|x64.Build.0 = Debug|x64
+		{1853E00F-6865-4BC6-974B-6A5E1C00BAFE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{1853E00F-6865-4BC6-974B-6A5E1C00BAFE}.Release|Any CPU.Build.0 = Release|Any CPU
+		{1853E00F-6865-4BC6-974B-6A5E1C00BAFE}.Release|x64.ActiveCfg = Release|Any CPU
+		{1853E00F-6865-4BC6-974B-6A5E1C00BAFE}.Release|x64.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/WPFProject/packages.config b/WPFProject/packages.config
index 05fc73f..2260565 100644
--- a/WPFProject/packages.config
+++ b/WPFProject/packages.config
@@ -3,10 +3,10 @@
   <package id="AIStudio.Wpf.Controls" version="1.2.2" targetFramework="net472" />
   <package id="gong-wpf-dragdrop" version="3.2.1" targetFramework="net472" />
   <package id="HandyControl" version="3.4.0" targetFramework="net472" />
-  <package id="log4net" version="3.0.3" targetFramework="net472" />
+  <package id="log4net" version="3.0.4" targetFramework="net472" />
   <package id="Microsoft.Xaml.Behaviors.Wpf" version="1.1.39" targetFramework="net472" />
   <package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" />
-  <package id="Panuon.WPF" version="1.1.2.2" targetFramework="net472" />
+  <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
   <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
   <package id="System.IO" version="4.3.0" targetFramework="net472" />
   <package id="System.Net.Http" version="4.3.4" targetFramework="net472" />

--
Gitblit v1.9.1