From 15bbd62b0b24b72c717ae91ab45348a2083ad04e Mon Sep 17 00:00:00 2001
From: alielie <alielie@git.com>
Date: 星期五, 10 十月 2025 08:58:18 +0800
Subject: [PATCH] 优化bug;

---
 HMI.ParameterManage/ProductModal.xaml.cs              |   11 
 HMI.ParameterManage/ParameterManage.xaml.cs           |    5 
 Plugin.DataBoard/Plugin.DataBoard.csproj              |    1 
 Plugin.SeqEditor/AssemblyInfo.cs                      |    1 
 HMI.LogViewer/LogViewer.xaml                          |  270 +++
 SimpleUtil/DIOController/IDIOController.cs            |   20 
 Plugin.SeqEditor/Util/Step2EPO.cs                     |    7 
 Plugin.TsExecution/Plugin.TsExecution.csproj          |   22 
 SimpleUtil/HMI.Simple.Util/ProductUtil.cs             |    2 
 SimpleUtil/HMI.Simple.Util/Properties/AssemblyInfo.cs |    2 
 SimpleUtil/DIOController/DaskHelper.cs                |  132 +
 Plugin.SeqEditor/SettingPanel/CallSeqPanel.xaml.cs    |   39 
 HMI.ParameterManage/ParameterModal.xaml               |   31 
 SimpleUtil/DIOController/DIOControllerCreator.cs      |   31 
 SimpleUtil/DIOController/PCIController.cs             |   66 
 HMI.ParameterManage/ParameterManage.xaml              |   51 
 Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs      |  105 +
 Plugin.TestResult/ViewControl.xaml.cs                 |    2 
 HMI.DataViewer/DataViewer.xaml.cs                     |   12 
 SimpleUtil/DIOController/IniFileHelper.cs             |   94 +
 SimpleUtil/DIOController/Properties/AssemblyInfo.cs   |   33 
 Plugin.SeqEditor/Entity/StepUI.cs                     |   16 
 SimpleUtil/HMI.Simple.Util/SerialDataHelper.cs        |  117 +
 HMI.LogViewer/Properties/AssemblyInfo.cs              |    2 
 SimpleUtil/DIOController/DIOController.csproj         |   70 +
 Plugin.TsExecution/TsExecution.xaml.cs                |  301 +++
 SimpleUtil/DIOController/Dask.cs                      |  803 +++++++++++
 Plugin.TsExecution/TsExecution.xaml                   |   15 
 Plugin.DataBoard/Libs/Static/test.html                |   68 
 SimpleUtil/DIOController/ModBusTcpController.cs       |   79 +
 HMI.ParameterManage/Model/XmlModel.cs                 |   16 
 ConsoleTest/ConsoleTest.csproj                        |   59 
 HMI.Core/Entity/ParameterData.cs                      |   13 
 HMI.ParameterManage/ProductModal.xaml                 |    4 
 Plugin.SeqEditor/SeqEditor.xaml.cs                    |   57 
 Plugin.DataBoard/SerialData.cs                        |    6 
 HMI.ParameterManage/SettingModal.xaml                 |   24 
 Plugin.DataBoard/DataBoard.xaml.cs                    |  343 +++-
 SimpleUtil/HMI.Simple.Util/HMI.Simple.Util.csproj     |   40 
 HMI.ParameterManage/ParameterSetting.xaml             |   40 
 HMI.ParameterManage/SettingModal.xaml.cs              |   91 +
 HMI.Core/HMI.Core.csproj                              |   18 
 Plugin.SeqEditor/SettingPanel/CallSeqPanel.xaml       |   58 
 Plugin.DataBoard/Properties/AssemblyInfo.cs           |    2 
 WPFProject/WPFProject.csproj                          |   20 
 HMI.ParameterManage/ParameterSetting.xaml.cs          |    7 
 ConsoleTest/Program.cs                                |   57 
 SimpleUtil/HMI.Simple.Util/ParameterUtil.cs           |    2 
 ConsoleTest/App.config                                |    6 
 Plugin.TsExecution/SingleControl.xaml                 |   23 
 WPFProject/WPFProject.sln                             |  191 ++
 HMI.AlermInfoManage/AlarmInfoManage.xaml.cs           |    9 
 Plugin.SeqEditor/SettingPanel/ViPanel.xaml.cs         |   20 
 Plugin.TestResult/Plugin.TestResult.csproj            |   44 
 Plugin.TsExecution/SingleControl.xaml.cs              |    9 
 SimpleUtil/DIOController/template.ini                 |    9 
 HMI.ParameterManage/ParameterModal.xaml.cs            |   91 +
 SimpleUtil/HMI.Simple.Util/AlarmUtil.cs               |   25 
 HMI.UI/DpUtil/FormGroupHelper.cs                      |   17 
 Plugin.SeqEditor/Entity/EditablePO/ViCallEPO.cs       |   36 
 Plugin.SeqEditor/Entity/SeqUI.cs                      |    1 
 HMI.LogViewer/LogViewer.xaml.cs                       |   87 
 SimpleUtil/HMI.Simple.Util/MSMQHelper.cs              |  139 +
 Plugin.SeqEditor/Plugin.SeqEditor.csproj              |    3 
 HMI.UI/Converter/IndentConverter.cs                   |    2 
 Plugin.SeqEditor/RowNumberConverter.cs                |   36 
 SimpleUtil/DIOController/PCI-Dask64.dll               |    0 
 ConsoleTest/Properties/AssemblyInfo.cs                |   33 
 SimpleUtil/HMI.Simple.Util/Parameter.cs               |    2 
 Plugin.SeqEditor/Constant/StepTypeStr.cs              |    5 
 Plugin.SeqEditor/SeqEditor.xaml                       |   55 
 Plugin.TsExecution/Properties/AssemblyInfo.cs         |    2 
 HMI.ParameterManage/Properties/AssemblyInfo.cs        |    2 
 Plugin.DataBoard/SimpleData.cs                        |    8 
 Plugin.SeqEditor/SettingPanel/ViPanel.xaml            |   48 
 75 files changed, 3,828 insertions(+), 340 deletions(-)

diff --git a/ConsoleTest/App.config b/ConsoleTest/App.config
new file mode 100644
index 0000000..56efbc7
--- /dev/null
+++ b/ConsoleTest/App.config
@@ -0,0 +1,6 @@
+锘�<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
+    </startup>
+</configuration>
\ No newline at end of file
diff --git a/ConsoleTest/ConsoleTest.csproj b/ConsoleTest/ConsoleTest.csproj
new file mode 100644
index 0000000..fbd16a4
--- /dev/null
+++ b/ConsoleTest/ConsoleTest.csproj
@@ -0,0 +1,59 @@
+<?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>{2BDDB984-199B-4913-96BB-39C252E101F2}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>ConsoleTest</RootNamespace>
+    <AssemblyName>ConsoleTest</AssemblyName>
+    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+    <Deterministic>true</Deterministic>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <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' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\SimpleUtil\DIOController\DIOController.csproj">
+      <Project>{34ffbafe-478f-4b6e-95e7-92a949011a9b}</Project>
+      <Name>DIOController</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
diff --git a/ConsoleTest/Program.cs b/ConsoleTest/Program.cs
new file mode 100644
index 0000000..17776f2
--- /dev/null
+++ b/ConsoleTest/Program.cs
@@ -0,0 +1,57 @@
+锘縰sing DIOController;
+using System;
+using System.Text;
+
+namespace ConsoleTest
+{
+    class Program
+    {
+        static void Main(string[] args)
+        {
+            /// ModbusTcp
+            //IDIOController controller = DIOControllerCreator
+            //    .CreateController("C:\\Workspace\\VisualStudio\\WPFProject\\SimpleUtil\\DIOController\\bin\\Release\\modbus.ini");
+            //bool s;
+            //controller.Start(out string msg);
+            //controller.ReadDIBool("0", out bool res, out msg);
+            //controller.ReadDOBool("0", out res, out msg);
+            //controller.WriteBool("0", true, out msg);
+
+            //s = controller.WriteBool("100", new bool[] { false, false }, out msg);
+            //s = controller.ReadDOBool("100", 2, out bool[] ress, out msg);
+
+            //controller.Dispose();
+
+            ///// 7432
+            //controller = controller = DIOControllerCreator
+            //    .CreateController("C:\\Workspace\\VisualStudio\\WPFProject\\SimpleUtil\\DIOController\\bin\\Release\\7432.ini");
+            //controller.Start(out msg);
+            //controller.ReadDIBool("0", out res, out msg);
+            //controller.ReadDOBool("0", out res, out msg);
+            //controller.WriteBool("0", true, out msg);
+            //controller.Dispose();
+            string recvstr = "62 FD 82 39 39 39 37 32 32 36 36 30 38 34 33 39 35 33 38 53 38 44 41 30 30 32 32";
+            string recvData;
+            if (recvstr.Contains("FF"))
+            {
+                recvData = recvstr.Replace(" ", "").Substring(6);
+            }
+            else
+            {
+                byte[] bus = HexToByteArray(recvstr.Replace(" ", "").Substring(6));
+                recvData = Encoding.Default.GetString(bus);
+            }
+        }
+
+        public static byte[] HexToByteArray(string hexString)
+        {
+            hexString = hexString.Replace(" ", "");
+            byte[] buffer = new byte[hexString.Length / 2];
+            for (int i = 0; i < buffer.Length; i++)
+            {
+                buffer[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
+            }
+            return buffer;
+        }
+    }
+}
diff --git a/ConsoleTest/Properties/AssemblyInfo.cs b/ConsoleTest/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..9af5105
--- /dev/null
+++ b/ConsoleTest/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+锘縰sing System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 鏈夊叧绋嬪簭闆嗙殑涓�鑸俊鎭敱浠ヤ笅
+// 鎺у埗銆傛洿鏀硅繖浜涚壒鎬у�煎彲淇敼
+// 涓庣▼搴忛泦鍏宠仈鐨勪俊鎭��
+[assembly: AssemblyTitle("ConsoleTest")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ConsoleTest")]
+[assembly: AssemblyCopyright("Copyright 漏  2025")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 灏� ComVisible 璁剧疆涓� false 浼氫娇姝ょ▼搴忛泦涓殑绫诲瀷
+//瀵� COM 缁勪欢涓嶅彲瑙併�傚鏋滈渶瑕佷粠 COM 璁块棶姝ょ▼搴忛泦涓殑绫诲瀷
+//璇峰皢姝ょ被鍨嬬殑 ComVisible 鐗规�ц缃负 true銆�
+[assembly: ComVisible(false)]
+
+// 濡傛灉姝ら」鐩悜 COM 鍏紑锛屽垯涓嬪垪 GUID 鐢ㄤ簬绫诲瀷搴撶殑 ID
+[assembly: Guid("2bddb984-199b-4913-96bb-39c252e101f2")]
+
+// 绋嬪簭闆嗙殑鐗堟湰淇℃伅鐢变笅鍒楀洓涓�肩粍鎴�: 
+//
+//      涓荤増鏈�
+//      娆$増鏈�
+//      鐢熸垚鍙�
+//      淇鍙�
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/HMI.AlermInfoManage/AlarmInfoManage.xaml.cs b/HMI.AlermInfoManage/AlarmInfoManage.xaml.cs
index c7891c0..b43bacd 100644
--- a/HMI.AlermInfoManage/AlarmInfoManage.xaml.cs
+++ b/HMI.AlermInfoManage/AlarmInfoManage.xaml.cs
@@ -713,11 +713,10 @@
             foreach (AlarmText alarm in this.currentAlarmCachePc)
             {
                 string sqladd2 = string.Format("INSERT INTO Alarm (source, alarmcode, alarminfo, time) VALUES('{0}','{1}','{2}','{3}');", alarm.Source, alarm.AlarmCode, alarm.AlarmInfo, alarm.Time);
-                sqliteHelper.ExecuteSql(sqladd2);
-                //Dispatcher.BeginInvoke(new Action(() =>
-                //{
-                //    Datasource.Add(alarm);
-                //}));
+                if (AlarmShowHelper.ShowAlarm(alarm.AlarmInfo))
+                {
+                    sqliteHelper.ExecuteSql(sqladd2);
+                }
             }
             this.currentAlarmCachePc.Clear();
         }
diff --git a/HMI.Core/Entity/ParameterData.cs b/HMI.Core/Entity/ParameterData.cs
index f0b4e30..7c67c8d 100644
--- a/HMI.Core/Entity/ParameterData.cs
+++ b/HMI.Core/Entity/ParameterData.cs
@@ -1,4 +1,6 @@
-锘縩amespace HMI.Core.Entity
+锘縰sing System.Xml.Serialization;
+
+namespace HMI.Core.Entity
 {
     public class ParameterData : SelectBase
     {
@@ -19,5 +21,14 @@
         public string Source { get; set; }
 
         public string ProductName { get; set; }
+
+        [XmlIgnore]
+        public string ShowGroup
+        {
+            get => string.IsNullOrEmpty(PGroup) ? "鏆傛棤" : PGroup;
+            set
+            {
+            }
+        }
     }
 }
diff --git a/HMI.Core/HMI.Core.csproj b/HMI.Core/HMI.Core.csproj
index 43134dc..7ee41cc 100644
--- a/HMI.Core/HMI.Core.csproj
+++ b/HMI.Core/HMI.Core.csproj
@@ -51,6 +51,24 @@
     <LangVersion>7.3</LangVersion>
     <ErrorReport>prompt</ErrorReport>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <LangVersion>7.3</LangVersion>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</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>
diff --git a/HMI.DataViewer/DataViewer.xaml.cs b/HMI.DataViewer/DataViewer.xaml.cs
index a1e2400..bad13fc 100644
--- a/HMI.DataViewer/DataViewer.xaml.cs
+++ b/HMI.DataViewer/DataViewer.xaml.cs
@@ -304,14 +304,19 @@
 
         private DataTable DoSearchData(DataBase_Setting setting, List<QueryData> datas)
         {
+            string conditon = "WHERE 1=1 ";
             string fields = string.Join(",", Datas?.Select(d => $"[{d.Key}]").ToList());
+            if (datas != null && datas.Count > 0)
+            {
+                conditon = "WHERE " + string.Join(" AND ", datas.Select(d => $"[{d.Key}] {d.Condition} '{d.Value}'").ToList());
+            }
 
-            string conditon = string.Join(" AND ", datas.Select(d => $"[{d.Key}] {d.Condition} '{d.Value}'").ToList());
             string timeCol = setting.TimeCol;
             if (string.IsNullOrEmpty(timeCol))
             {
                 timeCol = "time";
             }
+
             if (!string.IsNullOrEmpty(startTimeInput.Text))
             {
                 conditon += $" AND {timeCol} >= '{startTimeInput.Text}'";
@@ -320,7 +325,6 @@
             {
                 conditon += $" AND {timeCol} < '{endTimeInput.Text}'";
             }
-            conditon = string.IsNullOrEmpty(conditon) ? string.Empty : $" WHERE {conditon}";
 
             SqliteHelper helper = null;
             string sql = string.Empty;
@@ -354,7 +358,9 @@
             }
 
             var datas = Datas?.Where(d => !string.IsNullOrEmpty(d.Value)).ToList();
-            if (datas == null || datas.Count <= 0)
+
+            if ((datas == null || datas.Count <= 0) &&
+                (string.IsNullOrEmpty(startTimeInput.Text) || string.IsNullOrEmpty(endTimeInput.Text)))
             {
                 ToastHelper.Warning(Window.GetWindow(this), this.lang("Dv.QueryCantBeEmpty"));
                 return;
diff --git a/HMI.LogViewer/LogViewer.xaml b/HMI.LogViewer/LogViewer.xaml
index 52a68ba..04ac8c1 100644
--- a/HMI.LogViewer/LogViewer.xaml
+++ b/HMI.LogViewer/LogViewer.xaml
@@ -16,7 +16,43 @@
     <UserControl.Resources>
         <ResourceDictionary>
             <ResourceDictionary.MergedDictionaries>
+                <ResourceDictionary Source="/HMI.UI;component/Style/PanuonListView.xaml"/>
             </ResourceDictionary.MergedDictionaries>
+
+            <Style x:Key="TableBlock" TargetType="TextBlock">
+                <Setter Property="Padding" Value="0"/>
+                <Setter Property="Margin" Value="0"/>
+                <Setter Property="VerticalAlignment" Value="Center"/>
+                <Setter Property="TextWrapping" Value="Wrap"/>
+            </Style>
+
+            <Style x:Key="TableBox" TargetType="TextBox">
+                <Setter Property="Padding" Value="0"/>
+                <Setter Property="Margin" Value="0"/>
+                <Setter Property="VerticalAlignment" Value="Center"/>
+                <Setter Property="VerticalContentAlignment" Value="Center"/>
+                <Setter Property="TextWrapping" Value="Wrap"/>
+                <Setter Property="BorderThickness" Value="0"/>
+                <Setter Property="BorderBrush" Value="Transparent"/>
+                <Setter Property="Background" Value="Transparent"/>
+                <Setter Property="Foreground" Value="{Binding Foreground,RelativeSource={RelativeSource Mode=FindAncestor,
+AncestorLevel=1,AncestorType=ListViewItem}}"/>
+                <Style.Triggers>
+                    <DataTrigger Binding="{Binding IsSelected,RelativeSource={RelativeSource Mode=FindAncestor,
+                        AncestorLevel=1,AncestorType=ListViewItem}}" Value="True">
+                        <Setter Property="Foreground" Value="#FFF"/>
+                    </DataTrigger>
+                    <DataTrigger Binding="{Binding IsMouseOver,RelativeSource={RelativeSource Mode=FindAncestor,
+    AncestorLevel=1,AncestorType=ListViewItem}}" Value="True">
+                        <Setter Property="Foreground" Value="#FFF"/>
+                    </DataTrigger>
+                </Style.Triggers>
+            </Style>
+
+            <Style x:Key="sbCell" TargetType="DataGridCell" BasedOn="{StaticResource {x:Static pu:StyleKeys.DataGridCellStyle}}">
+                <Setter Property="Padding" Value="0"/>
+                <Setter Property="Margin" Value="0"/>
+            </Style>
         </ResourceDictionary>
     </UserControl.Resources>
     <Border Style="{StaticResource CardBoarder}">
@@ -25,6 +61,7 @@
                 <RowDefinition Height="Auto"/>
                 <RowDefinition Height="Auto"/>
                 <RowDefinition/>
+                <RowDefinition Height="Auto"/>
             </Grid.RowDefinitions>
 
             <TextBlock FontSize="{StaticResource TitleFontSize}" 
@@ -66,7 +103,100 @@
                 </StackPanel>
             </DockPanel>
 
-            <DataGrid Grid.Row="2" x:Name="table" Style="{StaticResource DefaultDataGrid}">
+            <ListView Grid.Row="2" Style="{StaticResource DefaultListTable}" x:Name="table"
+                                  VirtualizingPanel.VirtualizationMode="Standard" >
+                <ListView.ItemContainerStyle>
+                    <Style TargetType="ListViewItem" BasedOn="{StaticResource {x:Static pu:StyleKeys.ListViewItemStyle}}">
+                        <Setter Property="Height" Value="{StaticResource nanD}" />
+                        <Style.Triggers>
+                            <DataTrigger Binding="{Binding level}" Value="Warn">
+                                <Setter Property="Foreground" Value="{StaticResource WarningColor}"/>
+                            </DataTrigger>
+                            <DataTrigger Binding="{Binding level}" Value="Error">
+                                <Setter Property="Foreground" Value="{StaticResource DangerColor}"/>
+                            </DataTrigger>
+                            <Trigger Property="IsSelected" Value="True">
+                                <Setter Property="Background" Value="Transparent"/>
+                            </Trigger>
+                            <Trigger Property="IsMouseOver" Value="True">
+                                <Setter Property="Background" Value="Transparent"/>
+                            </Trigger>
+                        </Style.Triggers>
+                    </Style>
+                </ListView.ItemContainerStyle>
+
+                <ListView.View>
+                    <GridView>
+                        <GridViewColumn Width="50">
+                            <GridViewColumn.Header>
+                                <TextBlock Text="#"/>
+                            </GridViewColumn.Header>
+                            <GridViewColumn.CellTemplate>
+                                <DataTemplate>
+                                    <TextBlock Text="{Binding Converter={StaticResource lvRowNumber},
+RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListViewItem,AncestorLevel=1}}"/>
+                                </DataTemplate>
+                            </GridViewColumn.CellTemplate>
+                        </GridViewColumn>
+
+                        <GridViewColumn Width="80">
+                            <GridViewColumn.Header>
+                                <TextBlock Text="{DynamicResource log.level}"/>
+                            </GridViewColumn.Header>
+                            <GridViewColumn.CellTemplate>
+                                <DataTemplate>
+                                    <Border Style="{StaticResource CellBorder}">
+                                        <TextBlock VerticalAlignment="Center" Text="{Binding level}"/>
+                                    </Border>
+                                </DataTemplate>
+                            </GridViewColumn.CellTemplate>
+                        </GridViewColumn>
+
+                        <GridViewColumn Width="150">
+                            <GridViewColumn.Header>
+                                <TextBlock Text="{DynamicResource log.time}"/>
+                            </GridViewColumn.Header>
+                            <GridViewColumn.CellTemplate>
+                                <DataTemplate>
+                                    <Border Style="{StaticResource CellBorder}">
+                                        <TextBlock VerticalAlignment="Center" Text="{Binding time}"/>
+                                    </Border>
+                                </DataTemplate>
+                            </GridViewColumn.CellTemplate>
+                        </GridViewColumn>
+
+                        <GridViewColumn Width="150">
+                            <GridViewColumn.Header>
+                                <TextBlock Text="{DynamicResource log.source}"/>
+                            </GridViewColumn.Header>
+                            <GridViewColumn.CellTemplate>
+                                <DataTemplate>
+                                    <Border Style="{StaticResource CellBorder}">
+                                        <TextBlock VerticalAlignment="Center" Text="{Binding source}"/>
+                                    </Border>
+                                </DataTemplate>
+                            </GridViewColumn.CellTemplate>
+                        </GridViewColumn>
+                        <GridViewColumn Width="1420">
+                            <GridViewColumn.Header>
+                                <TextBlock Text="{DynamicResource log.text}"/>
+                            </GridViewColumn.Header>
+                            <GridViewColumn.CellTemplate>
+                                <DataTemplate>
+                                    <Border Style="{StaticResource CellBorder}">
+                                        <TextBox IsReadOnly="True" Style="{StaticResource TableBox}"
+                                                 Text="{Binding text}"/>
+                                    </Border>
+                                </DataTemplate>
+                            </GridViewColumn.CellTemplate>
+                        </GridViewColumn>
+                    </GridView>
+                </ListView.View>
+            </ListView>
+
+            <!--<DataGrid Grid.Row="2" x:Name="table" 
+                      CellStyle="{StaticResource sbCell}"
+                  RowHeight="{StaticResource nanD}" Style="{StaticResource DefaultDataGrid}">
                 <DataGrid.RowStyle>
                     <Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Static pu:StyleKeys.DataGridRowStyle}}">
                         <Style.Triggers>
@@ -88,36 +218,154 @@
                     </Style>
                 </DataGrid.RowStyle>
                 <DataGrid.Columns>
-                    <DataGridTemplateColumn Header="#" CanUserResize="False">
+                    <DataGridTemplateColumn Header="#" Width="60" CanUserResize="False">
                         <DataGridTemplateColumn.CellTemplate>
                             <DataTemplate>
-                                <TextBlock Text="{Binding Converter={StaticResource rowNumber},
+                                <TextBlock Style="{StaticResource TableBlock}" Text="{Binding Converter={StaticResource rowNumber},
     RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"/>
                             </DataTemplate>
                         </DataGridTemplateColumn.CellTemplate>
                     </DataGridTemplateColumn>
-                    <DataGridTextColumn Width="*" Binding="{Binding level}">
+                    <DataGridTextColumn Width="80" Binding="{Binding level}"
+                                        ElementStyle="{StaticResource TableBlock}">
                         <DataGridTextColumn.Header>
                             <TextBlock Text="{DynamicResource log.level}"/>
                         </DataGridTextColumn.Header>
                     </DataGridTextColumn>
-                    <DataGridTextColumn Width="*" Binding="{Binding time}">
+                    <DataGridTextColumn Width="150" Binding="{Binding time}"
+                                        ElementStyle="{StaticResource TableBlock}">
                         <DataGridTextColumn.Header>
                             <TextBlock Text="{DynamicResource log.time}"/>
                         </DataGridTextColumn.Header>
                     </DataGridTextColumn>
-                    <DataGridTextColumn Width="*" Binding="{Binding source}">
+                    <DataGridTextColumn Width="150" Binding="{Binding source}"
+                                        ElementStyle="{StaticResource TableBlock}">
                         <DataGridTextColumn.Header>
                             <TextBlock Text="{DynamicResource log.source}"/>
                         </DataGridTextColumn.Header>
                     </DataGridTextColumn>
-                    <DataGridTextColumn Width="*" Binding="{Binding text}">
-                        <DataGridTextColumn.Header>
+                    <DataGridTemplateColumn Width="*">
+                        <DataGridTemplateColumn.Header>
                             <TextBlock Text="{DynamicResource log.text}"/>
-                        </DataGridTextColumn.Header>
-                    </DataGridTextColumn>
+                        </DataGridTemplateColumn.Header>
+                        <DataGridTemplateColumn.CellTemplate>
+                            <DataTemplate>
+                                <TextBox IsReadOnly="True" Style="{StaticResource TableBox}" Text="{Binding text}"/>
+                            </DataTemplate>
+                        </DataGridTemplateColumn.CellTemplate>
+                    </DataGridTemplateColumn>
                 </DataGrid.Columns>
-            </DataGrid>
+            </DataGrid>-->
+
+            <!--<StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Right">
+                <pu:Pagination 
+                            Height="36" Margin="10"
+HorizontalAlignment="Left"
+Foreground="Black"
+ItemsBackground="Transparent"
+ItemsCornerRadius="12"
+ItemsSelectedBackground="{DynamicResource SecondPrimaryColor}"
+                            x:Name="page"
+                            CurrentPage="{Binding CurrentPage}" 
+                                        MaxPage="{Binding MaxPage}"/>
+            </StackPanel>-->
+
+            <!--<ListView Grid.Row="2" Style="{StaticResource DefaultListTable}" x:Name="table" VirtualizingPanel.IsContainerVirtualizable="True"
+VirtualizingPanel.IsVirtualizing="True" 
+VirtualizingPanel.VirtualizationMode="Standard">
+                <ListView.ItemContainerStyle>
+                    <Style TargetType="ListViewItem" BasedOn="{StaticResource {x:Static pu:StyleKeys.ListViewItemStyle}}">
+                        <Style.Triggers>
+                            <DataTrigger Binding="{Binding level}" Value="Warn">
+                                <Setter Property="Background" Value="{StaticResource WarningColor}"/>
+                                <Setter Property="Foreground" Value="Black"/>
+                            </DataTrigger>
+                            <DataTrigger Binding="{Binding level}" Value="Error">
+                                <Setter Property="Background" Value="{StaticResource DangerColor}"/>
+                                <Setter Property="Foreground" Value="Black"/>
+                            </DataTrigger>
+                            <Trigger Property="IsSelected" Value="True">
+                                <Setter Property="Background" Value="Transparent"/>
+                            </Trigger>
+                            <Trigger Property="IsMouseOver" Value="True">
+                                <Setter Property="Background" Value="Transparent"/>
+                            </Trigger>
+                        </Style.Triggers>
+                    </Style>
+                </ListView.ItemContainerStyle>
+                <ListView.View>
+                    <GridView AllowsColumnReorder="False">
+                        <GridViewColumn Width="60" Header="#">
+                            <GridViewColumn.CellTemplate>
+                                <DataTemplate>
+                                    <TextBlock Text="{Binding Converter={StaticResource lvRowNumber},
+RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListViewItem,AncestorLevel=1}}"/>
+                                </DataTemplate>
+                            </GridViewColumn.CellTemplate>
+                        </GridViewColumn>
+
+                        <GridViewColumn Width="80">
+                            <GridViewColumn.Header>
+                                <TextBlock Text="{DynamicResource log.level}"/>
+                            </GridViewColumn.Header>
+                            <GridViewColumn.CellTemplate>
+                                <DataTemplate>
+                                    <Border Style="{StaticResource CellBorder}">
+                                        <TextBlock Style="{StaticResource ListTableTextBlock}" 
+                                                           Text="{Binding level}"/>
+                                    </Border>
+                                </DataTemplate>
+                            </GridViewColumn.CellTemplate>
+                        </GridViewColumn>
+                        <GridViewColumn Width="150">
+                            <GridViewColumn.Header>
+                                <TextBlock Text="{DynamicResource log.time}"/>
+                            </GridViewColumn.Header>
+                            <GridViewColumn.CellTemplate>
+                                <DataTemplate>
+                                    <Border Style="{StaticResource CellBorder}">
+                                        <TextBlock Style="{StaticResource ListTableTextBlock}" 
+   Text="{Binding time}"/>
+                                    </Border>
+                                </DataTemplate>
+                            </GridViewColumn.CellTemplate>
+                        </GridViewColumn>
+                        <GridViewColumn Width="150">
+                            <GridViewColumn.Header>
+                                <TextBlock Text="{DynamicResource log.source}"/>
+                            </GridViewColumn.Header>
+                            <GridViewColumn.CellTemplate>
+                                <DataTemplate>
+                                    <Border Style="{StaticResource CellBorder}">
+                                        <TextBlock Style="{StaticResource ListTableTextBlock}" 
+                                                   Text="{Binding source}"/>
+                                    </Border>
+                                </DataTemplate>
+                            </GridViewColumn.CellTemplate>
+                        </GridViewColumn>
+                        <GridViewColumn Width="1410">
+                            <GridViewColumn.Header>
+                                <TextBlock Text="{DynamicResource log.text}"/>
+                            </GridViewColumn.Header>
+                            <GridViewColumn.CellTemplate>
+                                <DataTemplate>
+                                    <Border Style="{StaticResource CellBorder}">
+                                        <TextBlock Style="{StaticResource ListTableTextBlock}" 
+                                                   Text="{Binding text}"/>
+                                    </Border>
+                                </DataTemplate>
+                            </GridViewColumn.CellTemplate>
+                        </GridViewColumn>
+                    </GridView>
+                </ListView.View>
+            </ListView>-->
+            <!--<pu:Pagination HorizontalContentAlignment="Right" Grid.Row="3" Margin="0,10,0,0" Height="30"
+                       FontSize="14"
+HorizontalAlignment="Left"
+Foreground="Black"
+ItemsBackground="Transparent"
+ItemsCornerRadius="12"
+ItemsSelectedBackground="#36AAF7" CurrentPage="1"  MaxPage="10"/>-->
         </Grid>
     </Border>
 </hb:PluginControl>
\ No newline at end of file
diff --git a/HMI.LogViewer/LogViewer.xaml.cs b/HMI.LogViewer/LogViewer.xaml.cs
index da25941..4b9699a 100644
--- a/HMI.LogViewer/LogViewer.xaml.cs
+++ b/HMI.LogViewer/LogViewer.xaml.cs
@@ -6,6 +6,7 @@
 using System.Data;
 using System.IO;
 using System.Linq;
+using System.Threading.Tasks;
 using System.Timers;
 using System.Windows;
 using System.Windows.Controls;
@@ -32,6 +33,26 @@
 
         private Timer autoRfhTimer;
 
+        private int currentPage = 1;
+        public int CurrentPage
+        {
+            get => currentPage;
+            set
+            {
+                Set(ref currentPage, value);
+            }
+        }
+
+        private int maxPage = 0;
+        public int MaxPage
+        {
+            get => maxPage;
+            set
+            {
+                Set(ref currentPage, value);
+            }
+        }
+
 
         public LogViewer()
         {
@@ -39,7 +60,7 @@
             autoRfhTimer = new Timer
             {
                 Enabled = false,
-                Interval = 1000,
+                Interval = 1500,
                 AutoReset = false
             };
             autoRfhTimer.Elapsed += AutoRfhTimer_Elapsed;
@@ -151,11 +172,15 @@
                 endTimeInput.SelectedDateTime });
             foreach (string file in files)
             {
-                SqliteHelper sql = new SqliteHelper(file);
-                dt.Merge(sql.GetDataTable(str));
-                sql.Close();
+                using (SqliteHelper sql = new SqliteHelper(file))
+                {
+                    dt.Merge(sql.GetDataTable(str));
+                }
             }
-            dt.DefaultView.Sort = "time Desc";
+            if (dt.Rows.Count > 0)
+            {
+                dt.DefaultView.Sort = "time Desc";
+            }
             table.ItemsSource = dt.DefaultView;
         }
 
@@ -174,9 +199,9 @@
                     var lastWriteTime = File.GetLastWriteTime(file);
                     bool flag = true;
                     if (range[0] != null) flag &= lastWriteTime >= range[0];
-                    if (range[1] != null) flag &= lastWriteTime <= range[1];
+                    //if (range[1] != null) flag &= lastWriteTime <= range[1];
                     return flag;
-                }).ToArray();
+                }).OrderByDescending(f => f).ToArray();
 
                 return oldFiles;
             }
@@ -223,28 +248,36 @@
         /// </summary>
         private void Refresh100items()
         {
-            try
+            autoRfhTimer.Enabled = false;
+            Task.Run(() =>
             {
-                autoRfhTimer.Enabled = false;
-                string todayLogFile = Path.Combine(PathHelper.LogViewerDir, $"log_{DateTime.Today:yyyy-MM-dd}.db");
-                if (!File.Exists(todayLogFile)) return;
-                string str = "select level,time,source,text from log order by time desc limit 100";
-                SqliteHelper sql = new SqliteHelper(todayLogFile);
-                var dt = sql.GetDataTable(str);
-                this.Dispatcher.BeginInvoke((Action)delegate ()
+                try
                 {
-                    table.ItemsSource = dt.DefaultView;
-                });
-            }
-            catch (Exception ex)
-            {
-                log.Error("Log Auto Refresh Failed.", ex);
-                this.Error($"鑷姩鍒锋柊澶辫触锛亄ex.Message}");
-            }
-            finally
-            {
-                autoRfhTimer.Enabled = AutoRfh;
-            }
+                    string todayLogFile = Path.Combine(PathHelper.LogViewerDir, $"log_{DateTime.Today:yyyy-MM-dd}.db");
+                    if (!File.Exists(todayLogFile)) return;
+                    string str = "select level,time,source,text from log order by time desc limit 100";
+                    using (SqliteHelper sql = new SqliteHelper(todayLogFile))
+                    {
+                        var dt = sql.GetDataTable(str);
+                        this.Dispatcher.BeginInvoke((Action)delegate ()
+                        {
+                            table.ItemsSource = dt.DefaultView;
+                        });
+                    }
+                }
+                catch (Exception ex)
+                {
+                    log.Error("Log Auto Refresh Failed.", ex);
+                    this.Error($"鑷姩鍒锋柊澶辫触锛亄ex.Message}");
+                }
+                finally
+                {
+                    this.Dispatcher.BeginInvoke((Action)delegate ()
+                    {
+                        autoRfhTimer.Enabled = AutoRfh;
+                    });
+                }
+            });
         }
     }
 }
diff --git a/HMI.LogViewer/Properties/AssemblyInfo.cs b/HMI.LogViewer/Properties/AssemblyInfo.cs
index 8b227ca..b732dee 100644
--- a/HMI.LogViewer/Properties/AssemblyInfo.cs
+++ b/HMI.LogViewer/Properties/AssemblyInfo.cs
@@ -49,4 +49,4 @@
 //      淇鍙�
 //
 [assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.5")]
diff --git a/HMI.ParameterManage/Model/XmlModel.cs b/HMI.ParameterManage/Model/XmlModel.cs
index 9b1f6f3..16503c0 100644
--- a/HMI.ParameterManage/Model/XmlModel.cs
+++ b/HMI.ParameterManage/Model/XmlModel.cs
@@ -136,6 +136,16 @@
             var temp = XmlHelper.DeepClone(Products);
             temp.Add(data);
             SaveProduct(temp);
+            if (!string.IsNullOrEmpty(data.ParentId))
+            {
+                var parameters =
+                    ProductManager.GetParametersByProductName<List<ParameterData>>(data.ParentId);
+                foreach (var p in parameters)
+                {
+                    p.ProductName = data.Name;
+                }
+                SaveParameter(data.Name, parameters);
+            }
         }
 
         /// <summary>
@@ -248,6 +258,12 @@
             string fileName = Path.Combine(PathHelper.ProductDataFolder, "Parameter", $"Parameter_{SelectedProduct.Name}.data");
             XmlHelper.SerializeToXml(fileName, datas);
         }
+
+        private void SaveParameter(string product, IList<ParameterData> datas)
+        {
+            string fileName = Path.Combine(PathHelper.ProductDataFolder, "Parameter", $"Parameter_{product}.data");
+            XmlHelper.SerializeToXml(fileName, datas);
+        }
         #endregion
     }
 }
diff --git a/HMI.ParameterManage/ParameterManage.xaml b/HMI.ParameterManage/ParameterManage.xaml
index 61be0e0..d2e3d5e 100644
--- a/HMI.ParameterManage/ParameterManage.xaml
+++ b/HMI.ParameterManage/ParameterManage.xaml
@@ -21,6 +21,11 @@
                 <ResourceDictionary Source="/HMI.UI;component/Style/PanuonDataGrid.xaml"/>
             </ResourceDictionary.MergedDictionaries>
         </ResourceDictionary>-->
+        <CollectionViewSource x:Key="GroupFilter" Source="{Binding Parameters}">
+            <CollectionViewSource.GroupDescriptions>
+                <PropertyGroupDescription PropertyName="ShowGroup" />
+            </CollectionViewSource.GroupDescriptions>
+        </CollectionViewSource>
     </UserControl.Resources>
     <Grid>
         <Grid.ColumnDefinitions>
@@ -107,9 +112,36 @@
                 </DockPanel>
 
 
-                <DataGrid Grid.Row="1" x:Name="parameterTable" Style="{StaticResource DefaultDataGrid}" SelectionMode="Single" 
-                          SelectedItem="{Binding SelectedParameter}"
-                ItemsSource="{Binding Parameters}">
+                <DataGrid Grid.Row="1" x:Name="parameterTable" Style="{StaticResource DefaultDataGrid}" 
+                          SelectionMode="Single" 
+                          ItemsSource="{Binding Source={StaticResource GroupFilter}}"
+                          SelectedItem="{Binding SelectedParameter}">
+                    <DataGrid.GroupStyle>
+                        <GroupStyle>
+                            <GroupStyle.ContainerStyle>
+                                <Style TargetType="{x:Type GroupItem}">
+                                    <Setter Property="Template">
+                                        <Setter.Value>
+                                            <ControlTemplate TargetType="{x:Type GroupItem}">
+                                                <Expander BorderThickness="0" Background="DarkCyan"
+                                      IsExpanded="True">
+                                                    <Expander.Header>
+                                                        <TextBlock Text="{Binding Name}" FontSize="15"
+                                               Margin="8"
+                                               Foreground="#FFF"/>
+                                                    </Expander.Header>
+                                                    <Border Background="#FFF">
+                                                        <ItemsPresenter />
+                                                    </Border>
+                                                </Expander>
+                                            </ControlTemplate>
+                                        </Setter.Value>
+                                    </Setter>
+                                </Style>
+                            </GroupStyle.ContainerStyle>
+                        </GroupStyle>
+                    </DataGrid.GroupStyle>
+
                     <DataGrid.Columns>
                         <DataGridTemplateColumn Header="" Width="Auto" CanUserResize="False">
                             <DataGridTemplateColumn.CellTemplate>
@@ -123,9 +155,14 @@
                         <DataGridTextColumn Header="#" Binding="{Binding Converter={StaticResource rowNumber},
 RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"
         CanUserResize="False"/>
-                        <DataGridTextColumn Width="*" Binding="{Binding Name}">
+                        <DataGridTextColumn Width="150" Binding="{Binding Name}">
                             <DataGridTextColumn.Header>
                                 <TextBlock Text="{DynamicResource Pm.Parameter.Name}"/>
+                            </DataGridTextColumn.Header>
+                        </DataGridTextColumn>
+                        <DataGridTextColumn Width="60" Binding="{Binding Type}">
+                            <DataGridTextColumn.Header>
+                                <TextBlock Text="{DynamicResource Pm.Parameter.Type}"/>
                             </DataGridTextColumn.Header>
                         </DataGridTextColumn>
                         <DataGridTextColumn Width="*" Binding="{Binding Value}">
@@ -133,17 +170,17 @@
                                 <TextBlock Text="{DynamicResource Pm.Parameter.Value}"/>
                             </DataGridTextColumn.Header>
                         </DataGridTextColumn>
-                        <DataGridTextColumn Width="*" Binding="{Binding Unit}">
+                        <DataGridTextColumn Width="80" Binding="{Binding Unit}">
                             <DataGridTextColumn.Header>
                                 <TextBlock Text="{DynamicResource Pm.Parameter.Unit}"/>
                             </DataGridTextColumn.Header>
                         </DataGridTextColumn>
-                        <DataGridTextColumn Width="*" Binding="{Binding Description}">
+                        <DataGridTextColumn Width="120" Binding="{Binding Description}">
                             <DataGridTextColumn.Header>
                                 <TextBlock Text="{DynamicResource Pm.Parameter.Desc}"/>
                             </DataGridTextColumn.Header>
                         </DataGridTextColumn>
-                        <DataGridTextColumn Width="*" Binding="{Binding PGroup}">
+                        <DataGridTextColumn Width="120" Binding="{Binding PGroup}">
                             <DataGridTextColumn.Header>
                                 <TextBlock Text="{DynamicResource Pm.Parameter.Group}"/>
                             </DataGridTextColumn.Header>
diff --git a/HMI.ParameterManage/ParameterManage.xaml.cs b/HMI.ParameterManage/ParameterManage.xaml.cs
index c844215..398bd8b 100644
--- a/HMI.ParameterManage/ParameterManage.xaml.cs
+++ b/HMI.ParameterManage/ParameterManage.xaml.cs
@@ -75,6 +75,7 @@
                     break;
             }
         }
+
         private void OpenProductDialog(ProductData data)
         {
             var win = new ProductModal(Model)
@@ -82,7 +83,7 @@
                 Title = data == null ? this.lang("Pm.Product.Add") : this.lang("Pm.Product.Edit"),
                 Owner = Window.GetWindow(this),
             };
-            if (win.Open(data ?? new ProductData()) == true)
+            if (win.Open(data ?? new ProductData(), data != null) == true)
             {
                 Model.LoadProducts();
             }
@@ -100,7 +101,7 @@
                 Title = data == null ? this.lang("Pm.Parameter.Add") : this.lang("Pm.Parameter.Edit"),
                 Owner = Window.GetWindow(this),
             };
-            if (win.Open(data ?? new ParameterData { ProductName = Model.SelectedProduct.Name }) == true)
+            if (win.Open(Model.SelectedProduct.Name, data ?? new ParameterData { ProductName = Model.SelectedProduct.Name }) == true)
             {
                 Model.LoadParameters();
             }
diff --git a/HMI.ParameterManage/ParameterModal.xaml b/HMI.ParameterManage/ParameterModal.xaml
index 380f54a..2e316cb 100644
--- a/HMI.ParameterManage/ParameterModal.xaml
+++ b/HMI.ParameterManage/ParameterModal.xaml
@@ -33,10 +33,39 @@
                 <TextBox x:Name="TbName" Style="{StaticResource EditorTextBoxStyle}" />
             </pu:FormGroup>
 
+            <pu:FormGroup x:Name="FgType"
+                  Header="{DynamicResource Pm.Parameter.Type}" 
+                  dp:FormGroupHelper.IsRequired="True" GroupName="MyFormGroup">
+                <ComboBox x:Name="CbType" Style="{StaticResource FormComboxStyle}"
+                          SelectionChanged="CbType_SelectionChanged"
+                          SelectedValuePath="Content">
+                    <ComboBoxItem>Int</ComboBoxItem>
+                    <ComboBoxItem>Double</ComboBoxItem>
+                    <ComboBoxItem>Bool</ComboBoxItem>
+                    <ComboBoxItem>String</ComboBoxItem>
+                </ComboBox>
+            </pu:FormGroup>
+
             <pu:FormGroup x:Name="FgValue" Style="{StaticResource RequiredInputFormGroupStyle}" 
                           Header="{DynamicResource Pm.Parameter.Value}" 
 dp:FormGroupHelper.IsRequired="True" GroupName="MyFormGroup">
-                <TextBox x:Name="TbValue" Style="{StaticResource EditorTextBoxStyle}" />
+                <Grid>
+                    <ComboBox x:Name="CbBoolValue" Style="{StaticResource FormComboxStyle}" 
+                              Visibility="Collapsed"
+                              SelectedValuePath="Content">
+                        <ComboBoxItem>True</ComboBoxItem>
+                        <ComboBoxItem>False</ComboBoxItem>
+                    </ComboBox>
+                    <ui:NumberInput x:Name="NiNumberValue" Visibility="Collapsed" Style="{StaticResource EditorTextBoxStyle}"/>
+                    <Grid x:Name="StringValueGrid">
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition/>
+                            <ColumnDefinition Width="Auto"/>
+                        </Grid.ColumnDefinitions>
+                        <TextBox x:Name="TbStringValue" Style="{StaticResource EditorTextBoxStyle}"/>
+                        <Button Grid.Column="1" Click="Button_Click" Style="{StaticResource SearchButton}"/>
+                    </Grid>
+                </Grid>
             </pu:FormGroup>
 
             <pu:FormGroup x:Name="FgUnit" Style="{StaticResource InputFormGroupStyle}" 
diff --git a/HMI.ParameterManage/ParameterModal.xaml.cs b/HMI.ParameterManage/ParameterModal.xaml.cs
index 4c19c35..854380e 100644
--- a/HMI.ParameterManage/ParameterModal.xaml.cs
+++ b/HMI.ParameterManage/ParameterModal.xaml.cs
@@ -2,9 +2,12 @@
 using HMI.ParameterManage.Model;
 using HMI.UI.DpUtil;
 using HMI.UI.Util;
+using Microsoft.Win32;
 using Panuon.WPF.UI;
 using System;
+using System.Collections.Generic;
 using System.ComponentModel;
+using System.Windows.Controls;
 
 namespace HMI.ParameterManage
 {
@@ -70,11 +73,14 @@
 
         private bool ValidateForm()
         {
-            bool flag = FormGroupHelper.ValidateForm(formPanel);
+            bool flag = FormGroupHelper.ValidateForm(formPanel, new Dictionary<string, object> {
+                { "FgValue",GetTargetValue()}
+            });
             if (flag)
             {
                 Data.Name = TbName.Text;
-                Data.Value = TbValue.Text;
+                Data.Type = CbType.Text;
+                Data.Value = GetTargetValue();
                 Data.Unit = TbUnit.Text;
                 Data.Description = TbDescription.Text;
                 Data.ProductName = TbProductName.Text;
@@ -83,16 +89,91 @@
             return flag;
         }
 
-        public bool? Open(ParameterData data)
+        public bool? Open(string productName, ParameterData data)
         {
             Data = data;
             TbName.Text = Data.Name;
-            TbValue.Text = Data.Value;
+            CbType.SelectedValue = Data.Type;
+            UpdateWindow(Data.Type);
+            UpdateForm(Data);
             TbUnit.Text = Data.Unit;
-            TbProductName.Text = Data.ProductName;
+            TbProductName.Text = productName;
             TbDescription.Text = Data.Description;
             TbPGroup.Text = Data.PGroup;
             return this.ShowDialog();
         }
+
+        private string GetTargetValue()
+        {
+            if (CbType.Text == "Int" || Data.Type == "Double")
+            {
+                return NiNumberValue.Text;
+            }
+            else if (CbType.Text == "Bool")
+            {
+                return CbBoolValue.Text;
+            }
+            else
+            {
+                return TbStringValue.Text;
+            }
+        }
+
+        private void UpdateForm(ParameterData data)
+        {
+            if (Data.Type == "Int" || Data.Type == "Int")
+            {
+                NiNumberValue.Text = Data.Value;
+            }
+            else if (Data.Type == "Bool")
+            {
+                CbBoolValue.SelectedValue = Data.Value;
+            }
+            else
+            {
+                TbStringValue.Text = Data.Value;
+            }
+        }
+
+        private void UpdateWindow(string type)
+        {
+            if (type == "Int" || type == "Double")
+            {
+                NiNumberValue.Visibility = System.Windows.Visibility.Visible;
+                StringValueGrid.Visibility = System.Windows.Visibility.Collapsed;
+                CbBoolValue.Visibility = System.Windows.Visibility.Collapsed;
+            }
+            else if (type == "Bool")
+            {
+                NiNumberValue.Visibility = System.Windows.Visibility.Collapsed;
+                StringValueGrid.Visibility = System.Windows.Visibility.Collapsed;
+                CbBoolValue.Visibility = System.Windows.Visibility.Visible;
+            }
+            else
+            {
+                NiNumberValue.Visibility = System.Windows.Visibility.Collapsed;
+                StringValueGrid.Visibility = System.Windows.Visibility.Visible;
+                CbBoolValue.Visibility = System.Windows.Visibility.Collapsed;
+            }
+        }
+
+        private void CbType_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
+        {
+            string val = null;
+            if (e.AddedItems != null && e.AddedItems.Count > 0)
+            {
+                val = ((ComboBoxItem)e.AddedItems[0]).Content.ToString();
+            }
+            UpdateWindow(val);
+        }
+
+        private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
+        {
+            OpenFileDialog ofd = new OpenFileDialog();
+            if (ofd.ShowDialog() == true)
+            {
+                TbStringValue.Text = ofd.FileName;
+            }
+        }
     }
 }
diff --git a/HMI.ParameterManage/ParameterSetting.xaml b/HMI.ParameterManage/ParameterSetting.xaml
index 96eeac9..bb7d71f 100644
--- a/HMI.ParameterManage/ParameterSetting.xaml
+++ b/HMI.ParameterManage/ParameterSetting.xaml
@@ -15,11 +15,17 @@
              Background="{StaticResource WorkspaceBackground}"
              d:DesignHeight="450" d:DesignWidth="800">
     <UserControl.Resources>
-        <!--<ResourceDictionary>
+        <ResourceDictionary>
             <ResourceDictionary.MergedDictionaries>
-                <ResourceDictionary Source="/HMI.UI;component/Style/PanuonDataGrid.xaml"/>
+                <!--<pu:StyleDictionary Includes="Expander" />-->
             </ResourceDictionary.MergedDictionaries>
-        </ResourceDictionary>-->
+
+            <CollectionViewSource x:Key="GroupFilter" Source="{Binding Datasource}">
+                <CollectionViewSource.GroupDescriptions>
+                    <PropertyGroupDescription PropertyName="ShowGroup" />
+                </CollectionViewSource.GroupDescriptions>
+            </CollectionViewSource>
+        </ResourceDictionary>
     </UserControl.Resources>
     <Border Style="{StaticResource CardBoarder}">
         <Grid dp:GridHelper.Space="10" Cursor="">
@@ -56,7 +62,33 @@
             </DockPanel>
 
             <DataGrid Grid.Row="2" x:Name="table" Style="{StaticResource DefaultDataGrid}"
-                      ItemsSource="{Binding Datasource}">
+                      ItemsSource="{Binding Source={StaticResource GroupFilter}}">
+                <DataGrid.GroupStyle>
+                    <GroupStyle>
+                        <GroupStyle.ContainerStyle>
+                            <Style TargetType="{x:Type GroupItem}">
+                                <Setter Property="Template">
+                                    <Setter.Value>
+                                        <ControlTemplate TargetType="{x:Type GroupItem}">
+                                            <Expander BorderThickness="0" Background="DarkCyan"
+                                                      IsExpanded="True">
+                                                <Expander.Header>
+                                                    <TextBlock Text="{Binding Name}" FontSize="15"
+                                                               Margin="8"
+                                                               Foreground="#FFF"/>
+                                                </Expander.Header>
+                                                <Border Background="#FFF">
+                                                    <ItemsPresenter />
+                                                </Border>
+                                            </Expander>
+                                        </ControlTemplate>
+                                    </Setter.Value>
+                                </Setter>
+                            </Style>
+                        </GroupStyle.ContainerStyle>
+                    </GroupStyle>
+                </DataGrid.GroupStyle>
+
                 <DataGrid.Columns>
                     <DataGridTemplateColumn Header="" Width="Auto" CanUserResize="False">
                         <DataGridTemplateColumn.CellTemplate>
diff --git a/HMI.ParameterManage/ParameterSetting.xaml.cs b/HMI.ParameterManage/ParameterSetting.xaml.cs
index b720d3a..4039bf7 100644
--- a/HMI.ParameterManage/ParameterSetting.xaml.cs
+++ b/HMI.ParameterManage/ParameterSetting.xaml.cs
@@ -9,6 +9,7 @@
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Linq;
+using System.Text.RegularExpressions;
 using System.Windows;
 using System.Windows.Controls;
 
@@ -29,6 +30,8 @@
                 Set(ref datasource, value);
             }
         }
+
+        public List<string> groups = new List<string>();
 
         public ParameterSetting()
         {
@@ -77,10 +80,12 @@
             {
                 Datasource = ParameterManager.GetCommonParameter<ObservableCollection<ParameterData>>()
                 ?? new ObservableCollection<ParameterData>();
+                groups = Datasource.Where(d => !string.IsNullOrEmpty(d.ShowGroup)).Select(d => d.ShowGroup).Distinct().ToList();
             }
             catch (Exception ex)
             {
                 Datasource = new ObservableCollection<ParameterData>();
+                groups = new List<string>();
                 log.Error("Refresh Data Failed.", ex);
                 ToastHelper.Error(Window.GetWindow(this), $"{this.lang("App.RefreshFailed")}: {ex.Message}");
             }
@@ -101,7 +106,7 @@
                     Title = title,
                     Owner = Window.GetWindow(this)
                 };
-                if (modal.Open(data ?? new ParameterData(), Datasource) == true)
+                if (modal.Open(data ?? new ParameterData(), Datasource, groups) == true)
                 {
                     if (index == -1)
                     {
diff --git a/HMI.ParameterManage/ProductModal.xaml b/HMI.ParameterManage/ProductModal.xaml
index 10d4dd4..dd48773 100644
--- a/HMI.ParameterManage/ProductModal.xaml
+++ b/HMI.ParameterManage/ProductModal.xaml
@@ -34,7 +34,9 @@
 
             <pu:FormGroup x:Name="FgParentId" Style="{StaticResource InputFormGroupStyle}" 
                   Header="{DynamicResource Pm.Product.Extend}" GroupName="MyFormGroup">
-                <TextBox x:Name="TbParentId" Style="{StaticResource EditorTextBoxStyle}" />
+                <!--<TextBox x:Name="TbParentId" Style="{StaticResource EditorTextBoxStyle}" />-->
+                <ComboBox x:Name="CbParent" Style="{StaticResource FormComboxStyle}"
+                          pu:ComboBoxHelper.ClearButtonVisibility="Visible"/>
             </pu:FormGroup>
         </StackPanel>
     </Grid>
diff --git a/HMI.ParameterManage/ProductModal.xaml.cs b/HMI.ParameterManage/ProductModal.xaml.cs
index bececf3..9210a3d 100644
--- a/HMI.ParameterManage/ProductModal.xaml.cs
+++ b/HMI.ParameterManage/ProductModal.xaml.cs
@@ -5,6 +5,9 @@
 using Panuon.WPF.UI;
 using System;
 using System.ComponentModel;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
 
 namespace HMI.ParameterManage
 {
@@ -77,16 +80,20 @@
             {
                 Data.Name = TbName.Text;
                 Data.IsMaster = TbIsMaster.IsChecked == true;
+                Data.ParentId = CbParent.Text;
             }
             return flag;
         }
 
-        public bool? Open(ProductData data)
+        public bool? Open(ProductData data, bool isEdit)
         {
             Data = data;
             TbName.Text = Data.Name;
             TbIsMaster.IsChecked = Data.IsMaster;
-            TbParentId.Text = Data.ParentId;
+            FgParentId.Visibility = isEdit ? Visibility.Collapsed : Visibility.Visible;
+
+            CbParent.ItemsSource = DataModel.Products.Select(e => e.Name).ToList();
+            //TbParentId.Text = Data.ParentId;
 
             return this.ShowDialog();
         }
diff --git a/HMI.ParameterManage/Properties/AssemblyInfo.cs b/HMI.ParameterManage/Properties/AssemblyInfo.cs
index 7275233..a661fe3 100644
--- a/HMI.ParameterManage/Properties/AssemblyInfo.cs
+++ b/HMI.ParameterManage/Properties/AssemblyInfo.cs
@@ -49,4 +49,4 @@
 //      淇鍙�
 //
 [assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.2")]
diff --git a/HMI.ParameterManage/SettingModal.xaml b/HMI.ParameterManage/SettingModal.xaml
index ab004fa..37370f6 100644
--- a/HMI.ParameterManage/SettingModal.xaml
+++ b/HMI.ParameterManage/SettingModal.xaml
@@ -29,7 +29,9 @@
             <pu:FormGroup x:Name="FgType"
               Header="{DynamicResource Pm.Parameter.Type}" 
               dp:FormGroupHelper.IsRequired="True" GroupName="MyFormGroup">
-                <ComboBox x:Name="CbType" Style="{StaticResource FormComboxStyle}" SelectedValuePath="Content">
+                <ComboBox x:Name="CbType" Style="{StaticResource FormComboxStyle}" 
+                          SelectionChanged="CbType_SelectionChanged"
+                          SelectedValuePath="Content">
                     <ComboBoxItem>Int</ComboBoxItem>
                     <ComboBoxItem>Double</ComboBoxItem>
                     <ComboBoxItem>Bool</ComboBoxItem>
@@ -40,7 +42,23 @@
             <pu:FormGroup x:Name="FgValue" Style="{StaticResource RequiredInputFormGroupStyle}" 
                           Header="{DynamicResource Pm.Parameter.Value}" 
 dp:FormGroupHelper.IsRequired="True" GroupName="MyFormGroup">
-                <TextBox x:Name="TbValue" Style="{StaticResource EditorTextBoxStyle}" />
+                <Grid>
+                    <ComboBox x:Name="CbBoolValue" Style="{StaticResource FormComboxStyle}" 
+                              Visibility="Collapsed"
+                              SelectedValuePath="Content">
+                        <ComboBoxItem>True</ComboBoxItem>
+                        <ComboBoxItem>False</ComboBoxItem>
+                    </ComboBox>
+                    <ui:NumberInput x:Name="NiNumberValue" Visibility="Collapsed" Style="{StaticResource EditorTextBoxStyle}"/>
+                    <Grid x:Name="StringValueGrid">
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition/>
+                            <ColumnDefinition Width="Auto"/>
+                        </Grid.ColumnDefinitions>
+                        <TextBox x:Name="TbStringValue" Style="{StaticResource EditorTextBoxStyle}"/>
+                        <Button Grid.Column="1" Click="Button_Click" Style="{StaticResource SearchButton}"/>
+                    </Grid>
+                </Grid>
             </pu:FormGroup>
 
             <pu:FormGroup x:Name="FgUnit" Style="{StaticResource InputFormGroupStyle}" 
@@ -58,7 +76,7 @@
             <pu:FormGroup x:Name="FgGroup" Style="{StaticResource InputFormGroupStyle}"
                           Header="{DynamicResource Pm.Parameter.Group}" 
                           GroupName="MyFormGroup">
-                <TextBox x:Name="TbGroup" Style="{StaticResource EditorTextBoxStyle}"/>
+                <ComboBox x:Name="TbGroup" IsEditable="True" Style="{StaticResource FormComboxStyle}"/>
             </pu:FormGroup>
 
             <pu:FormGroup x:Name="FgSource" Style="{StaticResource InputFormGroupStyle}" 
diff --git a/HMI.ParameterManage/SettingModal.xaml.cs b/HMI.ParameterManage/SettingModal.xaml.cs
index edd574b..20925c9 100644
--- a/HMI.ParameterManage/SettingModal.xaml.cs
+++ b/HMI.ParameterManage/SettingModal.xaml.cs
@@ -2,11 +2,15 @@
 using HMI.Core.Util;
 using HMI.UI.DpUtil;
 using HMI.UI.Util;
+using Microsoft.Win32;
 using Panuon.WPF.UI;
 using System;
+using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.ComponentModel;
 using System.Linq;
+using System.Text.RegularExpressions;
+using System.Windows.Controls;
 
 namespace HMI.ParameterManage
 {
@@ -82,12 +86,14 @@
 
         private bool ValidateForm()
         {
-            bool flag = FormGroupHelper.ValidateForm(formPanel);
+            bool flag = FormGroupHelper.ValidateForm(formPanel, new Dictionary<string, object> {
+                { "FgValue",GetTargetValue()}
+            });
             if (flag)
             {
                 Data.Name = TbName.Text;
                 Data.Type = CbType.Text;
-                Data.Value = TbValue.Text;
+                Data.Value = GetTargetValue();
                 Data.Unit = TbUnit.Text;
                 Data.Description = TbDescription.Text;
                 Data.PGroup = TbGroup.Text;
@@ -96,18 +102,95 @@
             return flag;
         }
 
-        public bool? Open(ParameterData data, ObservableCollection<ParameterData> datasource)
+        public bool? Open(ParameterData data, ObservableCollection<ParameterData> datasource,List<string> groups)
         {
             Datasource = datasource;
             Data = data;
+            TbGroup.ItemsSource = groups;
+
             TbName.Text = Data.Name;
             CbType.SelectedValue = Data.Type;
-            TbValue.Text = Data.Value;
+            UpdateWindow(Data.Type);
+            UpdateForm(Data);
+
             TbUnit.Text = Data.Unit;
             TbDescription.Text = Data.Description;
             TbGroup.Text = Data.PGroup;
             TbSource.Text = Data.Source;
             return this.ShowDialog();
         }
+
+        private string GetTargetValue()
+        {
+            if (CbType.Text == "Int" || Data.Type == "Double")
+            {
+                return NiNumberValue.Text;
+            }
+            else if (CbType.Text == "Bool")
+            {
+                return CbBoolValue.Text;
+            }
+            else
+            {
+                return TbStringValue.Text;
+            }
+        }
+
+        private void UpdateForm(ParameterData data)
+        {
+            if (Data.Type == "Int" || Data.Type == "Int")
+            {
+                NiNumberValue.Text = Data.Value;
+            }
+            else if (Data.Type == "Bool")
+            {
+                CbBoolValue.SelectedValue = Data.Value;
+            }
+            else
+            {
+                TbStringValue.Text = Data.Value;
+            }
+        }
+
+        private void UpdateWindow(string type)
+        {
+            if (type == "Int" || type == "Double")
+            {
+                NiNumberValue.Visibility = System.Windows.Visibility.Visible;
+                StringValueGrid.Visibility = System.Windows.Visibility.Collapsed;
+                CbBoolValue.Visibility = System.Windows.Visibility.Collapsed;
+            }
+            else if (type == "Bool")
+            {
+                NiNumberValue.Visibility = System.Windows.Visibility.Collapsed;
+                StringValueGrid.Visibility = System.Windows.Visibility.Collapsed;
+                CbBoolValue.Visibility = System.Windows.Visibility.Visible;
+            }
+            else
+            {
+                NiNumberValue.Visibility = System.Windows.Visibility.Collapsed;
+                StringValueGrid.Visibility = System.Windows.Visibility.Visible;
+                CbBoolValue.Visibility = System.Windows.Visibility.Collapsed;
+            }
+        }
+
+        private void CbType_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
+        {
+            string val = null;
+            if (e.AddedItems != null && e.AddedItems.Count > 0)
+            {
+                val = ((ComboBoxItem)e.AddedItems[0]).Content.ToString();
+            }
+            UpdateWindow(val);
+        }
+
+        private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
+        {
+            OpenFileDialog ofd = new OpenFileDialog();
+            if (ofd.ShowDialog() == true)
+            {
+                TbStringValue.Text = ofd.FileName;
+            }
+        }
     }
 }
diff --git a/HMI.UI/Converter/IndentConverter.cs b/HMI.UI/Converter/IndentConverter.cs
index d31dc09..0db73e5 100644
--- a/HMI.UI/Converter/IndentConverter.cs
+++ b/HMI.UI/Converter/IndentConverter.cs
@@ -10,7 +10,7 @@
         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
         {
             int level = (int)value;
-            return new Thickness(level * 10, 0, 0, 0);
+            return new Thickness(level * 5, 0, 0, 0);
         }
 
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
diff --git a/HMI.UI/DpUtil/FormGroupHelper.cs b/HMI.UI/DpUtil/FormGroupHelper.cs
index bdfd5bd..bc45159 100644
--- a/HMI.UI/DpUtil/FormGroupHelper.cs
+++ b/HMI.UI/DpUtil/FormGroupHelper.cs
@@ -1,5 +1,6 @@
 锘縰sing HMI.Core.Util;
 using Panuon.WPF.UI;
+using System.Collections.Generic;
 using System.Windows;
 using System.Windows.Controls;
 
@@ -49,7 +50,7 @@
             DependencyProperty.RegisterAttached("ValidateMethod", typeof(ValidateMethodDelegate), typeof(FormGroupHelper),
             new PropertyMetadata(null));
 
-        public static bool ValidateForm(StackPanel fgPanel)
+        public static bool ValidateForm(StackPanel fgPanel, Dictionary<string, object> values = null)
         {
             if (fgPanel.Children == null) return true;
             bool res = true;
@@ -57,6 +58,7 @@
             {
                 if (child is FormGroup fg)
                 {
+                    string fgName = fg.Name;
                     if (fg.Visibility != Visibility.Visible)
                     {
                         ClearValue(fg);
@@ -64,8 +66,17 @@
                     }
                     fg.ValidateResult = ValidateResult.None;
                     fg.Message = null;
-                    object content = fg.Content;
-                    object value = GetValidateValue(content);
+                    object value;
+                    if (values != null && values.ContainsKey(fgName))
+                    {
+                        value = values[fgName];
+                    }
+                    else
+                    {
+                        object content = fg.Content;
+                        value = GetValidateValue(content);
+                    }
+
                     if (GetIsRequired(fg) && (value == null || string.IsNullOrEmpty(value.ToString())))
                     {
                         fg.ValidateResult = ValidateResult.Error;
diff --git a/Plugin.DataBoard/DataBoard.xaml.cs b/Plugin.DataBoard/DataBoard.xaml.cs
index 099edc3..57aa86f 100644
--- a/Plugin.DataBoard/DataBoard.xaml.cs
+++ b/Plugin.DataBoard/DataBoard.xaml.cs
@@ -1,5 +1,6 @@
 锘縰sing HMI.Base;
 using HMI.Core.Util;
+using HMI.UI.Util;
 using HMI.Util;
 using Microsoft.Web.WebView2.Core;
 using System;
@@ -95,6 +96,26 @@
             return BeanUtil.ReadBeanFromDataTable<SerialData>(dt);
         }
 
+        private List<SerialData> SelectResultDataByTime(DateTime start, DateTime end)
+        {
+            string[] files = DbFileHelper.GetDbFiles(BaseFolder, start, end);
+            if (files == null || files.Length <= 0)
+            {
+                return new List<SerialData>();
+            }
+            string sql = $"SELECT * FROM testResult WHERE time BETWEEN '{start:yyyy-MM-dd HH:mm:ss}' AND '{end:yyyy-MM-dd HH:mm:ss}';";
+
+            DataTable dt = new DataTable();
+            foreach (string file in files)
+            {
+                using (SqliteHelper helper = new SqliteHelper(file))
+                {
+                    dt.Merge(helper.GetDataTable(sql));
+                }
+            }
+            return BeanUtil.ReadBeanFromDataTable<SerialData>(dt);
+        }
+
         private void webview2_Loaded(object sender, RoutedEventArgs e)
         {
             string path = Path.Combine(PathHelper.AppFolder, "Libs", "Static", "test.html");
@@ -118,156 +139,272 @@
 
         private void RefreshChart0(DateTime start, DateTime end)
         {
-            dtp00.SelectedDateTime = start;
-            dtp01.SelectedDateTime = end;
-            List<SerialData> datas = SelectSerialDataByTime(start, end);
-
-            datas.OrderByDescending(e => e.time);
-            int all = 0, output = 0;
-            HashSet<string> snCache = new HashSet<string>();
-            foreach (var data in datas)
+            try
             {
-                if (snCache.Contains(data.sn)) continue;
-                snCache.Add(data.sn);
-                all++;
-                if (data.status == "Passed") output++;
-            }
-            var fields = $"['{this.lang("bd.input")}','{this.lang("bd.output")}']";
+                dtp00.SelectedDateTime = start;
+                dtp01.SelectedDateTime = end;
+                List<SerialData> datas = SelectSerialDataByTime(start, end);
 
-            webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart0({fields}, [{all},{output}])");
+                datas.OrderByDescending(e => e.time);
+                int all = 0, output = 0;
+                HashSet<string> snCache = new HashSet<string>();
+                foreach (var data in datas)
+                {
+                    if (snCache.Contains(data.sn)) continue;
+                    snCache.Add(data.sn);
+                    all++;
+                    if (data.status == "Passed") output++;
+                }
+                var fields = $"['{this.lang("bd.input")}','{this.lang("bd.output")}']";
+
+                webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart0({fields}, [{all},{output}])");
+            }
+            catch (Exception ex)
+            {
+                log.Error("RefreshChart0 Error.", ex);
+                ToastHelper.Error("琛�1鍒锋柊澶辫触锛�");
+            }
         }
 
         private void RefreshChart1(DateTime start, DateTime end)
         {
-            dtp10.SelectedDateTime = start;
-            dtp11.SelectedDateTime = end;
-            List<SerialData> datas = SelectSerialDataByTime(start, end);
+            try
+            {
+                dtp10.SelectedDateTime = start;
+                dtp11.SelectedDateTime = end;
+                List<SerialData> datas = SelectResultDataByTime(start, end);
 
-            datas = datas.OrderByDescending(e => e.time).ToList();
-            Dictionary<string, int> pieData = new Dictionary<string, int> {
+                datas = datas.OrderByDescending(e => e.time).ToList();
+                Dictionary<string, int?> pieData = new Dictionary<string, int?> {
                 { "Passed",0},
                 { "Failed",0},
-                { "Action",0},
-                { "Wait",0},
+                //{ "Action",0},
+                //{ "Wait",0},
             };
-            HashSet<string> snCache = new HashSet<string>();
-            foreach (var data in datas)
-            {
-                if (snCache.Contains(data.sn)) continue;
-                snCache.Add(data.sn);
-                if (pieData.ContainsKey(data.status))
+                //if (datas == null || datas.Count <= 0)
+                //{
+                //    pieData = new Dictionary<string, int?> {
+                //    { "Passed",null},
+                //    { "Failed",null},
+                //};
+                //}
+
+                HashSet<string> snCache = new HashSet<string>();
+                foreach (var data in datas)
                 {
-                    pieData[data.status]++;
+                    if (snCache.Contains(data.sn)) continue;
+                    snCache.Add(data.sn);
+                    if (pieData.ContainsKey(data.result))
+                    {
+                        pieData[data.result]++;
+                    }
                 }
+                string res = "[";
+                foreach (var key in pieData.Keys)
+                {
+                    res += $"{{name:'{key}',value:{pieData[key]}}},";
+                }
+                res += "]";
+                webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart1({res})");
             }
-            string res = "[";
-            foreach (var key in pieData.Keys)
+            catch (Exception ex)
             {
-                res += $"{{name:'{key}',value:{pieData[key]}}},";
+                log.Error("RefreshChart1 Error.", ex);
+                ToastHelper.Error("琛�2鍒锋柊澶辫触锛�");
             }
-            res += "]";
-            webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart1({res})");
         }
+
+        //private void RefreshChart2(DateTime start, DateTime end)
+        //{
+        //    dtp20.SelectedDateTime = start;
+        //    dtp21.SelectedDateTime = end;
+        //    List<SerialData> datas = SelectSerialDataByTime(start, end);
+
+        //    var groups =
+        //        datas.Where(e => e.status == "Passed" || e.status == "Failed").GroupBy(d => d.time.ToString("yyyy-MM-dd"));
+
+        //    Dictionary<string, PassRateData> res = new Dictionary<string, PassRateData>();
+
+        //    foreach (var group in groups)
+        //    {
+        //        Dictionary<string, string> snStatusCache = new Dictionary<string, string>();
+        //        double all = 0, oneTimePass = 0, passed = 0;
+        //        var groupDatas = group.ToList();
+        //        groupDatas = groupDatas.OrderBy(e => e.time).ToList();
+
+        //        foreach (var data in groupDatas)
+        //        {
+        //            if (snStatusCache.ContainsKey(data.sn))
+        //            {
+        //                if (snStatusCache[data.sn] != "Passed" && data.status == "Passed")
+        //                {
+        //                    passed++;
+        //                }
+        //                else if (snStatusCache[data.sn] == "Passed" && data.status == "Passed")
+        //                {
+        //                    if (oneTimePass > 0) oneTimePass--;
+        //                }
+        //            }
+        //            else
+        //            {
+        //                all++;
+        //                if (data.status == "Passed")
+        //                {
+        //                    passed++;
+        //                    oneTimePass++;
+        //                }
+        //                snStatusCache.Add(data.sn, data.status);
+        //            }
+        //        }
+        //        res.Add(group.Key, new PassRateData
+        //        {
+        //            time = group.Key,
+        //            onePassRate = oneTimePass / all * 100,
+        //            passRate = passed / all * 100,
+        //        });
+        //    }
+
+
+
+        //    string fields = "[", vals0 = "[", vals1 = "[";
+        //    foreach (var key in res.Keys)
+        //    {
+        //        fields += $"'{key}',";
+        //        vals0 += $"{res[key].onePassRate},";
+        //        vals1 += $"{res[key].passRate},";
+        //    }
+        //    fields += "]";
+        //    vals0 += "]";
+        //    vals1 += "]";
+        //    var names = $"['{this.lang("bd.onePassRate")}','{this.lang("bd.passRate")}']";
+        //    webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart2({fields},{names},{vals0},{vals1})");
+        //}
 
         private void RefreshChart2(DateTime start, DateTime end)
         {
-            dtp20.SelectedDateTime = start;
-            dtp21.SelectedDateTime = end;
-            List<SerialData> datas = SelectSerialDataByTime(start, end);
-
-            var groups =
-                datas.GroupBy(d => d.time.ToString("yyyy-MM-dd"));
-
-            Dictionary<string, PassRateData> res = new Dictionary<string, PassRateData>();
-
-            foreach (var group in groups)
+            try
             {
-                Dictionary<string, string> snStatusCache = new Dictionary<string, string>();
-                double all = 0, oneTimePass = 0, passed = 0;
-                var groupDatas = group.ToList();
-                groupDatas = groupDatas.OrderBy(e => e.time).ToList();
+                dtp20.SelectedDateTime = start;
+                dtp21.SelectedDateTime = end;
+                List<SerialData> datas = SelectResultDataByTime(start, end);
 
-                foreach (var data in groupDatas)
+                var groups =
+                    datas.GroupBy(d => d.time.ToString("yyyy-MM-dd"));
+
+                Dictionary<string, PassRateData> res = new Dictionary<string, PassRateData>();
+
+                foreach (var group in groups)
                 {
-                    if (snStatusCache.ContainsKey(data.sn))
+                    Dictionary<string, string> snStatusCache = new Dictionary<string, string>();
+                    double all = 0, oneTimePass = 0, passed = 0;
+                    var groupDatas = group.ToList();
+                    groupDatas = groupDatas.OrderByDescending(e => e.time).ToList();
+
+                    foreach (var data in groupDatas)
                     {
-                        if (snStatusCache[data.sn] != "Passed" && data.status == "Passed")
+                        if (!snStatusCache.ContainsKey(data.sn))
                         {
-                            passed++;
+                            snStatusCache.Add(data.sn, data.result);
+                            all++;
+                            if (data.result == "Passed")
+                            {
+                                passed++;
+                                oneTimePass++;
+                            }
                         }
-                        else if (snStatusCache[data.sn] == "Passed" && data.status == "Passed")
+                        else
                         {
-                            if (oneTimePass > 0) oneTimePass--;
+                            if (snStatusCache[data.sn] == "Passed")
+                            {
+                                if (oneTimePass > 0) oneTimePass--;
+                                snStatusCache[data.sn] = "NoOnePass";
+                            }
                         }
                     }
-                    else
+                    res.Add(group.Key, new PassRateData
                     {
-                        all++;
-                        if (data.status == "Passed")
-                        {
-                            passed++;
-                            oneTimePass++;
-                        }
-                        snStatusCache.Add(data.sn, data.status);
-                    }
+                        time = group.Key,
+                        onePassRate = oneTimePass / all * 100,
+                        passRate = passed / all * 100,
+                    });
                 }
-                res.Add(group.Key, new PassRateData
+
+
+
+                string fields = "[", vals0 = "[", vals1 = "[";
+                foreach (var key in res.Keys)
                 {
-                    time = group.Key,
-                    onePassRate = oneTimePass / all * 100,
-                    passRate = passed / all * 100,
-                });
+                    fields += $"'{key}',";
+                    vals0 += $"{res[key].onePassRate},";
+                    vals1 += $"{res[key].passRate},";
+                }
+                fields += "]";
+                vals0 += "]";
+                vals1 += "]";
+                var names = $"['{this.lang("bd.onePassRate")}','{this.lang("bd.passRate")}']";
+                webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart2({fields},{names},{vals0},{vals1})");
             }
-
-
-
-            string fields = "[", vals0 = "[", vals1 = "[";
-            foreach (var key in res.Keys)
+            catch (Exception ex)
             {
-                fields += $"'{key}',";
-                vals0 += $"{res[key].onePassRate},";
-                vals1 += $"{res[key].passRate},";
+                log.Error("RefreshChart2 Error.", ex);
+                ToastHelper.Error("琛�3鍒锋柊澶辫触锛�");
             }
-            fields += "]";
-            vals0 += "]";
-            vals1 += "]";
-            var names = $"['{this.lang("bd.onePassRate")}','{this.lang("bd.passRate")}']";
-            webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart2({fields},{names},{vals0},{vals1})");
         }
 
         private void RefreshChart3(DateTime start, DateTime end)
         {
-            dtp30.SelectedDateTime = start;
-            dtp31.SelectedDateTime = end;
-            List<SerialData> datas = SelectSerialDataByTime(start, end);
-
-            datas = datas.OrderByDescending(e => e.time).ToList();
-            Dictionary<string, int> pieData = new Dictionary<string, int>();
-
-            HashSet<string> snCache = new HashSet<string>();
-            foreach (var data in datas)
+            try
             {
-                //if (snCache.Contains(data.sn)) continue;
-                if (data.status != "Failed") continue;
+                dtp30.SelectedDateTime = start;
+                dtp31.SelectedDateTime = end;
+                List<SerialData> datas = SelectSerialDataByTime(start, end);
 
-                snCache.Add(data.sn);
-                if (pieData.ContainsKey(data.step))
+                datas = datas.OrderByDescending(e => e.time).ToList();
+
+
+
+                Dictionary<string, SimpleData> pieData = new Dictionary<string, SimpleData>();
+                List<SimpleData> datasource = new List<SimpleData>();
+                //HashSet<string> snCache = new HashSet<string>();
+
+                foreach (var data in datas)
                 {
-                    pieData[data.step]++;
+                    //if (snCache.Contains(data.sn)) continue;
+                    if (data.status != "Failed") continue;
+                    if (pieData.ContainsKey(data.step))
+                    {
+                        pieData[data.step].Value++;
+                    }
+                    else
+                    {
+                        pieData[data.step] = new SimpleData
+                        {
+                            Name = data.step,
+                            Value = 1
+                        };
+                        datasource.Add(pieData[data.step]);
+                    }
                 }
-                else
+                datasource = datasource.OrderByDescending(e => e.Value).ToList();
+                if (datasource.Count > 10)
                 {
-                    pieData[data.step] = 1;
+                    datasource = datasource.Take(10).ToList();
                 }
+
+                string names = string.Empty, vals = string.Empty;
+                foreach (var data in datasource)
+                {
+                    names += $"'{data.Name}',";
+                    vals += $"{data.Value},";
+                }
+
+                webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart3([{names}],[{vals}])");
             }
-            string names = string.Empty, vals = string.Empty;
-            foreach (var key in pieData.Keys)
+            catch (Exception ex)
             {
-                names += $"'{key}',";
-                vals += $"{pieData[key]},";
+                log.Error("RefreshChart3 Error.", ex);
+                ToastHelper.Error("琛�4鍒锋柊澶辫触锛�");
             }
-
-            webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart3([{names}],[{vals}])");
         }
 
         private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
diff --git a/Plugin.DataBoard/Libs/Static/test.html b/Plugin.DataBoard/Libs/Static/test.html
index 431dfe4..9b2e204 100644
--- a/Plugin.DataBoard/Libs/Static/test.html
+++ b/Plugin.DataBoard/Libs/Static/test.html
@@ -51,6 +51,13 @@
         var dom0 = document.getElementById('chart0');
 
         var opt0 = {
+            title: {
+                text: '鎶曞叆浜у嚭缁熻',
+                left: 'center'
+            },
+            tooltip: {
+                show: true,
+            },
             color: color,
             xAxis: {
                 type: 'category',
@@ -58,7 +65,7 @@
             },
             yAxis: {
                 type: 'value',
-                interval: 1
+                minInterval: 1
             },
             series: [
                 {
@@ -80,6 +87,10 @@
         var dom1 = document.getElementById('chart1');
 
         var opt1 = {
+            title: {
+                text: '浜у搧鐘舵�佺粺璁�',
+                left: 'center'
+            },
             tooltip: {
                 trigger: 'item'
             },
@@ -125,6 +136,17 @@
         var dom2 = document.getElementById('chart2');
 
         var opt2 = {
+            title: {
+                text: '鑹巼缁熻',
+                left: 'center'
+            },
+            tooltip: {
+                trigger: 'axis',
+                axisPointer: {
+                    type: 'line'
+                },
+                show: true
+            },
             legend: {
                 orient: 'vertical',
                 left: 'left'
@@ -169,18 +191,52 @@
         var dom3 = document.getElementById('chart3');
 
         var opt3 = {
+            title: {
+                text: 'TOP10涓嶈壇缁熻',
+                left: 'center'
+            },
+            tooltip: {
+                trigger: 'axis',
+                axisPointer: {
+                    type: 'shadow'
+                },
+                show: true,
+                formatter: '椤圭洰锛歿b}</br>璁℃暟锛歿c}'
+            },
             color: color,
+            //xAxis: {
+            //    type: 'category',
+            //    axisTick: {
+            //        alignWithLabel: true
+            //    },
+            //    data: []
+            //},
+            //yAxis: {
+            //    type: 'value',
+            //    interval: 1
+            //},
             xAxis: {
-                type: 'category',
-                data: []
+                type: 'value',
+                minInterval: 1,
             },
             yAxis: {
-                type: 'value',
-                interval: 1
+                type: 'category',
+                inverse: true,
+                axisLabel: {
+                    show: false
+                },
+                data: []
             },
             series: [
                 {
                     data: [],
+                    label: {
+                        show: true,
+                        formatter: '{b}',
+                        distance: 10,
+                        fontSize: 14,
+                        position: 'insideLeft'
+                    },
                     type: 'bar',
                     barMaxWidth: 50
                 }
@@ -189,7 +245,7 @@
         var chart3 = echarts.init(dom3);
 
         function drawChart3(label, data) {
-            opt3.xAxis.data = label;
+            opt3.yAxis.data = label;
             opt3.series[0].data = data;
             chart3.setOption(opt3);
         }
diff --git a/Plugin.DataBoard/Plugin.DataBoard.csproj b/Plugin.DataBoard/Plugin.DataBoard.csproj
index 9696880..37ffdf2 100644
--- a/Plugin.DataBoard/Plugin.DataBoard.csproj
+++ b/Plugin.DataBoard/Plugin.DataBoard.csproj
@@ -92,6 +92,7 @@
     <Compile Include="OptionData.cs" />
     <Compile Include="PassRateData.cs" />
     <Compile Include="SerialData.cs" />
+    <Compile Include="SimpleData.cs" />
     <Page Include="DataBoard.xaml">
       <Generator>MSBuild:Compile</Generator>
       <SubType>Designer</SubType>
diff --git a/Plugin.DataBoard/Properties/AssemblyInfo.cs b/Plugin.DataBoard/Properties/AssemblyInfo.cs
index f9905fa..0038bd3 100644
--- a/Plugin.DataBoard/Properties/AssemblyInfo.cs
+++ b/Plugin.DataBoard/Properties/AssemblyInfo.cs
@@ -50,5 +50,5 @@
 //      淇鍙�
 //
 [assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.1")]
 [assembly: PluginClassName("Plugin.DataBoard.DataBoard")]
diff --git a/Plugin.DataBoard/SerialData.cs b/Plugin.DataBoard/SerialData.cs
index 82c4f2b..f3d08ff 100644
--- a/Plugin.DataBoard/SerialData.cs
+++ b/Plugin.DataBoard/SerialData.cs
@@ -1,16 +1,14 @@
 锘縰sing System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace Plugin.DataBoard
 {
     public class SerialData
     {
         public string sn { get; set; }
+        public string model { get; set; }
         public string station { get; set; }
         public string status { get; set; }
+        public string result { get; set; }
         public string step { get; set; }
         public DateTime time { get; set; }
     }
diff --git a/Plugin.DataBoard/SimpleData.cs b/Plugin.DataBoard/SimpleData.cs
new file mode 100644
index 0000000..0f33917
--- /dev/null
+++ b/Plugin.DataBoard/SimpleData.cs
@@ -0,0 +1,8 @@
+锘縩amespace Plugin.DataBoard
+{
+    public class SimpleData
+    {
+        public string Name { get; set; }
+        public int Value { get; set; }
+    }
+}
diff --git a/Plugin.SeqEditor/AssemblyInfo.cs b/Plugin.SeqEditor/AssemblyInfo.cs
index cc29e7f..87411db 100644
--- a/Plugin.SeqEditor/AssemblyInfo.cs
+++ b/Plugin.SeqEditor/AssemblyInfo.cs
@@ -1,3 +1,4 @@
+using System.Reflection;
 using System.Windows;
 
 [assembly:ThemeInfo(
diff --git a/Plugin.SeqEditor/Constant/StepTypeStr.cs b/Plugin.SeqEditor/Constant/StepTypeStr.cs
index 4b6b28b..1c10924 100644
--- a/Plugin.SeqEditor/Constant/StepTypeStr.cs
+++ b/Plugin.SeqEditor/Constant/StepTypeStr.cs
@@ -21,4 +21,9 @@
 
 
     }
+
+    public abstract class AdapterName
+    {
+        public const string VICall = "G Flexible VI Adapter";
+    }
 }
diff --git a/Plugin.SeqEditor/Entity/EditablePO/ViCallEPO.cs b/Plugin.SeqEditor/Entity/EditablePO/ViCallEPO.cs
new file mode 100644
index 0000000..5888ba5
--- /dev/null
+++ b/Plugin.SeqEditor/Entity/EditablePO/ViCallEPO.cs
@@ -0,0 +1,36 @@
+锘縰sing NationalInstruments.TestStand.Interop.API;
+
+namespace Plugin.SeqEditor.Entity.EditablePO
+{
+    public class ViCallEPO : BaseEPO
+    {
+        public Step Step { get; private set; }
+        public PropertyObject PropertyObject { get; private set; }
+
+        public ViCallEPO(StepUI stepUI)
+        {
+            StepUI = stepUI;
+            Step = StepUI?.step;
+            PropertyObject = Step?.AsPropertyObject();
+        }
+
+        public object TimeInterval
+        {
+            get
+            {
+                //var str = PropertyObject?.GetValString("TimeExpr", 0);
+                //if (string.IsNullOrEmpty(str)) return null;
+                //double.TryParse(str, out double value);
+                //return value;
+                return PropertyObject?.GetSubProperties("TS.SData.ViCall", 0);
+            }
+            set
+            {
+                if (PropertyObject != null)
+                {
+
+                }
+            }
+        }
+    }
+}
diff --git a/Plugin.SeqEditor/Entity/SeqUI.cs b/Plugin.SeqEditor/Entity/SeqUI.cs
index c6c2430..08582ac 100644
--- a/Plugin.SeqEditor/Entity/SeqUI.cs
+++ b/Plugin.SeqEditor/Entity/SeqUI.cs
@@ -15,6 +15,7 @@
         }
 
         public Sequence sequence { get; private set; }
+
         public SeqUI(Sequence sequence)
         {
             this.sequence = sequence;
diff --git a/Plugin.SeqEditor/Entity/StepUI.cs b/Plugin.SeqEditor/Entity/StepUI.cs
index c3cd66e..84275ef 100644
--- a/Plugin.SeqEditor/Entity/StepUI.cs
+++ b/Plugin.SeqEditor/Entity/StepUI.cs
@@ -180,6 +180,22 @@
             }
         }
 
+        public string CallSeqPath
+        {
+            get
+            {
+                return step?.Module?.AsPropertyObject()?.GetValString("SFPath", 0); ;
+            }
+        }
+
+        public string CallSeqName
+        {
+            get
+            {
+                return step?.Module?.AsPropertyObject()?.GetValString("SeqName", 0); ;
+            }
+        }
+
         [ObservableProperty]
         private string group;
 
diff --git a/Plugin.SeqEditor/Plugin.SeqEditor.csproj b/Plugin.SeqEditor/Plugin.SeqEditor.csproj
index ce581ba..1fa5240 100644
--- a/Plugin.SeqEditor/Plugin.SeqEditor.csproj
+++ b/Plugin.SeqEditor/Plugin.SeqEditor.csproj
@@ -5,7 +5,8 @@
 		<LangVersion>10.0</LangVersion>
 		<ImplicitUsings>enable</ImplicitUsings>
 		<UseWPF>true</UseWPF>
-		<Platforms>AnyCPU;x64</Platforms>
+		<Platforms>AnyCPU;x64;x86</Platforms>
+		<FileVersion>1.0.0.1</FileVersion>
 	</PropertyGroup>
 	<ItemGroup>
 	  <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
diff --git a/Plugin.SeqEditor/RowNumberConverter.cs b/Plugin.SeqEditor/RowNumberConverter.cs
new file mode 100644
index 0000000..d3260f7
--- /dev/null
+++ b/Plugin.SeqEditor/RowNumberConverter.cs
@@ -0,0 +1,36 @@
+锘縰sing HMI.UI;
+using Plugin.SeqEditor.Constant;
+using Plugin.SeqEditor.Entity;
+using System.Globalization;
+using System.Windows.Data;
+
+namespace Plugin.SeqEditor
+{
+    public class RowNumberConverter : IValueConverter
+    {
+        public int current = 0;
+        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (value is TreeListViewItem row && row.DataContext is StepUI step)
+            {
+                if (step.Type != StepTypeStr.SequenceCall)
+                {
+                    return (++current).ToString();
+                }
+
+                return null;
+            }
+            return null;
+        }
+
+        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            return value;
+        }
+
+        public void Reset()
+        {
+            current = 0;
+        }
+    }
+}
diff --git a/Plugin.SeqEditor/SeqEditor.xaml b/Plugin.SeqEditor/SeqEditor.xaml
index 0120dad..c976529 100644
--- a/Plugin.SeqEditor/SeqEditor.xaml
+++ b/Plugin.SeqEditor/SeqEditor.xaml
@@ -36,6 +36,8 @@
 
             <uic:IndentConverter x:Key="IndentConverter"/>
 
+            <local:RowNumberConverter x:Key="treeNumber"/>
+
             <Style TargetType="pu:FormGroup">
                 <Setter Property="Padding" Value="0,10"/>
                 <Setter Property="HeaderFontSize" Value="14"/>
@@ -154,18 +156,16 @@
         <Grid dp:GridHelper.Space="10" Cursor="">
             <Grid.RowDefinitions>
                 <RowDefinition Height="Auto"/>
-                <RowDefinition Height="Auto"/>
                 <RowDefinition/>
             </Grid.RowDefinitions>
             <Grid.ColumnDefinitions>
-                <ColumnDefinition Width="0"/>
                 <ColumnDefinition Width="8.5*"/>
                 <ColumnDefinition Width="1.5*"/>
             </Grid.ColumnDefinitions>
 
-            <DockPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Margin="0,0,0,10">
+            <DockPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,0,10">
                 <StackPanel DockPanel.Dock="Right"  Orientation="Horizontal"
-        dp:StackPanelHelper.ChildSpace="10">
+        dp:StackPanelHelper.ChildSpace="10" Margin="0,5">
                     <Button Style="{StaticResource AddBtn}" Content="{DynamicResource se.open}" Command="{Binding OpenSeqFileCommand}"/>
                     <Button Style="{StaticResource SaveBtn}" Content="{DynamicResource se.save}" Command="{Binding SaveSeqFileCommand}"/>
                     <Button Style="{StaticResource SaveBtn}" pu:ButtonHelper.Icon="&#xe60b;"
@@ -174,13 +174,13 @@
                     <Button Style="{StaticResource DelBtn}" Content="{DynamicResource se.close}"
                             pu:ButtonHelper.Icon="&#xe609;"
                             Command="{Binding CloseSeqFileCommand}"/>
+                    <!--<Button Style="{StaticResource DelBtn}" Content="涓�閿睍寮�"
+                            x:Name="treeAll"
+                            Click="Button_Click"/>-->
                 </StackPanel>
 
-                <TextBlock DockPanel.Dock="Left" FontSize="{StaticResource TitleFontSize}" 
-           VerticalAlignment="Center" HorizontalAlignment="Left" Text="{DynamicResource se.title}"/>
-
-                <TextBlock DockPanel.Dock="Left" FontSize="{StaticResource ContentFontSize2}" 
-                           Margin="20,0,0,0"
+                <TextBlock DockPanel.Dock="Right" FontSize="{StaticResource ContentFontSize2}" 
+                           Margin="20,0,20,0"
 VerticalAlignment="Bottom" LineHeight="{StaticResource TitleFontSize}" HorizontalAlignment="Left">
                 <Run Text="{Binding CurrentFileName}"/>
                 <Run DataContext="{Binding CurrentSeqUI}">
@@ -195,6 +195,20 @@
                     </Run.Style>
                 </Run>
                 </TextBlock>
+
+                <!--<TextBlock DockPanel.Dock="Left" FontSize="{StaticResource TitleFontSize}" 
+           VerticalAlignment="Center" HorizontalAlignment="Left" Text="{DynamicResource se.title}"/>-->
+
+                <pu:FormGroup DockPanel.Dock="Left" Header="姝ラ绫诲瀷" Style="{StaticResource InputFormGroupStyle}">
+                    <StackPanel Orientation="Horizontal">
+                        <ui:MultiComboBox SelectedValues="{Binding TargetType}"
+                          pu:ComboBoxHelper.ClearButtonVisibility="Collapsed"
+                          Width="450" Margin="0,0,10,0" x:Name="CbFilter" IsEditable="True" IsReadOnly="True" >
+
+                        </ui:MultiComboBox>
+                        <Button Style="{StaticResource RfhBtn}" Command="{Binding RefreshCommand}"/>
+                    </StackPanel>
+                </pu:FormGroup>
             </DockPanel>
 
             <!--<pu:FormGroup Header="{DynamicResource se.seq}" Orientation="Vertical" Grid.Row="1" Grid.Column="0">
@@ -208,19 +222,10 @@
                     </DataGrid.Columns>
                 </DataGrid>
             </pu:FormGroup>-->
-            <pu:FormGroup Grid.Row="1" Grid.Column="1" Header="姝ラ绫诲瀷" Style="{StaticResource InputFormGroupStyle}">
-                <StackPanel Orientation="Horizontal">
-                    <ui:MultiComboBox SelectedValues="{Binding TargetType}"
-                                      pu:ComboBoxHelper.ClearButtonVisibility="Collapsed"
-                                      Width="450" Margin="0,0,10,0" x:Name="CbFilter" IsEditable="True" IsReadOnly="True" >
-
-                    </ui:MultiComboBox>
-                    <Button Style="{StaticResource RfhBtn}" Command="{Binding RefreshCommand}"/>
-                </StackPanel>
-            </pu:FormGroup>
 
 
-            <pu:FormGroup Header="{Binding CurrentSeqTitle}" Orientation="Vertical" Grid.Row="2" Grid.Column="1">
+
+            <pu:FormGroup Header="{Binding CurrentSeqTitle}" Orientation="Vertical" Grid.Row="1" Grid.Column="0">
                 <!--<DataGrid ItemsSource="{Binding Source={StaticResource cvs}}"
                           RowStyle="{StaticResource StepRow}"
                           SelectedItem="{Binding CurrentStepUI}">
@@ -380,9 +385,10 @@
                 </ui:TreeDataGrid>-->
 
 
-                <ui:TreeListView Grid.Row="1" Grid.Column="1" ItemsSource="{Binding AllSteps}"
+                <ui:TreeListView Grid.Row="1" Grid.Column="0" ItemsSource="{Binding AllSteps}"
                                  dd:DragDrop.IsDragSource="True"
                                  FontSize="14"
+                                 x:Name="treeList"
                                  pu:TreeViewHelper.ItemsHeight="{DynamicResource nanD}"
                                  dd:DragDrop.IsDropTarget="True"
                                  dd:DragDrop.DropTargetAdornerBrush="Red"
@@ -457,7 +463,8 @@
       Grid.Column="0"
 IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ui:TreeListViewItem,AncestorLevel=1}}"
 ClickMode="Press"/>
-                                            <TextBlock Margin="5,0,0,0" Padding="6,0" Text="{Binding CustomIndex}"/>
+                                            <TextBlock Margin="5,0,0,0" Padding="6,0" 
+                                                       Text="{Binding CustomIndex}"/>
                                         </StackPanel>
                                     </Border>
 
@@ -539,7 +546,7 @@
                         </GridViewColumn>
 
                         <GridViewColumn Header="鎻忚堪" HeaderContainerStyle="{StaticResource gvh}"
-                                        Width="400"
+                                        Width="500"
                 HeaderTemplate="{StaticResource gvht}">
                             <GridViewColumn.CellTemplate>
                                 <DataTemplate>
@@ -563,7 +570,7 @@
 
             </pu:FormGroup>
 
-            <StackPanel Grid.Row="2"  Grid.Column="2">
+            <StackPanel Grid.Row="1" Grid.Column="1">
                 <pu:FormGroup Header="{DynamicResource se.propertySetting}" Orientation="Vertical" 
              Padding="0,10" >
                     <Border x:Name="editPanelContainer" Background="#FFF">
diff --git a/Plugin.SeqEditor/SeqEditor.xaml.cs b/Plugin.SeqEditor/SeqEditor.xaml.cs
index 3d95679..7bef44c 100644
--- a/Plugin.SeqEditor/SeqEditor.xaml.cs
+++ b/Plugin.SeqEditor/SeqEditor.xaml.cs
@@ -1,9 +1,12 @@
 using HMI.Base;
 using HMI.UI;
 using Panuon.WPF.UI;
+using Plugin.SeqEditor.Entity;
 using Plugin.SeqEditor.Util;
 using Plugin.SeqEditor.ViewModel;
+using System.Web.UI.WebControls;
 using System.Windows;
+using System.Windows.Controls;
 using System.Windows.Data;
 using System.Windows.Input;
 
@@ -79,10 +82,62 @@
         //var width = treeListView.ActualWidth;
 
         //columns[0].Width = columns[0].Width + (width - columns[0].Width - columns[1].Width - columns[2].Width - columns[3].Width);
-        
+
         //foreach (var col in columns) { 
         //    col.Width = 
         //}
     }
+
+    public void HandleStatus(ItemContainerGenerator cg, StepUI step, bool status)
+    {
+        DependencyObject dObject = cg.ContainerFromItem(step);
+        if (status == true)
+        {
+            if (dObject is TreeViewItem item)
+            {
+                if (step.Children != null && step.Children.Count > 0)
+                {
+                    if (item.IsExpanded != status)
+                    {
+                        item.IsExpanded = status;
+                        item.UpdateLayout();
+                    }
+                    foreach (var child in step.Children)
+                    {
+                        HandleStatus(item.ItemContainerGenerator, child, status);
+                    }
+                }
+            }
+        }
+        else
+        {
+            if (dObject is TreeViewItem item)
+            {
+                if (step.Children != null && step.Children.Count > 0)
+                {
+                    foreach (var child in step.Children)
+                    {
+                        HandleStatus(item.ItemContainerGenerator, child, status);
+                    }
+                    item.IsExpanded = status;
+                }
+            }
+        }
+    }
+
+    public bool expandAll = false;
+    private void Button_Click(object sender, RoutedEventArgs e)
+    {
+        treeList.UpdateLayout();
+        foreach (var item in treeList.Items)
+        {
+            if (item is StepUI step)
+            {
+                HandleStatus(treeList.ItemContainerGenerator, step, !expandAll);
+            }
+        }
+        expandAll = !expandAll;
+        //treeAll.Content = expandAll ? "一键收起" : "一键展开";
+    }
 }
 
diff --git a/Plugin.SeqEditor/SettingPanel/CallSeqPanel.xaml b/Plugin.SeqEditor/SettingPanel/CallSeqPanel.xaml
new file mode 100644
index 0000000..792e15e
--- /dev/null
+++ b/Plugin.SeqEditor/SettingPanel/CallSeqPanel.xaml
@@ -0,0 +1,58 @@
+锘�<UserControl x:Class="Plugin.SeqEditor.SettingPanel.CallSeqPanel"
+             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.SeqEditor.SettingPanel"
+             mc:Ignorable="d" 
+             xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+             xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+             xmlns:ui="clr-namespace:HMI.UI;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"
+             Padding="5"
+             d:DesignHeight="450" d:DesignWidth="800">
+    <Grid>
+        <StackPanel>
+            <pu:FormGroup Header="{DynamicResource se.stepName}" Orientation="Vertical" 
+                          Style="{StaticResource InputFormGroupStyle}">
+                <TextBox IsReadOnly="True" Style="{StaticResource EditorTextBoxStyle}" Text="{Binding Name}" />
+            </pu:FormGroup>
+
+            <pu:FormGroup Header="{DynamicResource se.stepType}" Orientation="Vertical" 
+                          Style="{StaticResource InputFormGroupStyle}">
+                <TextBox IsReadOnly="True" Style="{StaticResource EditorTextBoxStyle}" Text="{Binding Type,Mode=OneWay}" />
+            </pu:FormGroup>
+
+            <pu:FormGroup Header="鏂囦欢" Orientation="Vertical" 
+              Style="{StaticResource InputFormGroupStyle}">
+                <TextBox IsReadOnly="True" Style="{StaticResource EditorTextBoxStyle}" 
+                         Text="{Binding CallSeqPath,Mode=OneWay}" />
+            </pu:FormGroup>
+
+            <pu:FormGroup Header="搴忓垪" Orientation="Vertical" 
+  Style="{StaticResource InputFormGroupStyle}">
+                <TextBox IsReadOnly="True" Style="{StaticResource EditorTextBoxStyle}" 
+                         Text="{Binding CallSeqName,Mode=OneWay}" />
+            </pu:FormGroup>
+
+            <pu:FormGroup Header="{DynamicResource se.runMode}" Orientation="Vertical" 
+                          Style="{StaticResource InputFormGroupStyle}">
+
+                <ComboBox x:Name="CbRunMode" Style="{StaticResource FormComboxStyle}"
+                          VirtualizingPanel.IsVirtualizing="True"
+                          pu:ComboBoxHelper.ClearButtonVisibility="Collapsed"
+                SelectedValue="{Binding RunMode}" 
+            DisplayMemberPath="DisplayName" SelectedValuePath="DataValue"/>
+            </pu:FormGroup>
+
+            <!--<pu:FormGroup Header="{DynamicResource se.adapter}" 
+        Orientation="Vertical"
+        Style="{StaticResource InputFormGroupStyle}">
+                <ComboBox x:Name="CbAdapter" Style="{StaticResource FormComboxStyle}" IsEnabled="False" SelectedValue="{Binding Adapter}" 
+                          DisplayMemberPath="DisplayName" SelectedValuePath="DataValue"/>
+            </pu:FormGroup>-->
+        </StackPanel>
+    </Grid>
+</UserControl>
diff --git a/Plugin.SeqEditor/SettingPanel/CallSeqPanel.xaml.cs b/Plugin.SeqEditor/SettingPanel/CallSeqPanel.xaml.cs
new file mode 100644
index 0000000..8afe4ff
--- /dev/null
+++ b/Plugin.SeqEditor/SettingPanel/CallSeqPanel.xaml.cs
@@ -0,0 +1,39 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using NationalInstruments.TestStand.Interop.API;
+using Plugin.SeqEditor.Entity;
+using Plugin.SeqEditor.Util;
+using System.ComponentModel;
+using System.Windows.Controls;
+
+namespace Plugin.SeqEditor.SettingPanel
+{
+    /// <summary>
+    /// CommonProperty.xaml 鐨勪氦浜掗�昏緫
+    /// </summary>
+    [INotifyPropertyChanged]
+    public partial class CallSeqPanel : UserControl
+    {
+        public event EventHandler SettingChanged;
+
+        public StepUI stepUI;
+        public Step step;
+        public PropertyObject propertyObject;
+
+        protected void CustomPropertyChanged(string name)
+        {
+            OnPropertyChanged(name);
+            SettingChanged?.Invoke(this, EventArgs.Empty);
+        }
+
+        public CallSeqPanel(StepUI stepUI)
+        {
+            this.stepUI = stepUI;
+            this.step = stepUI.step;
+            propertyObject = this.step?.AsPropertyObject();
+            this.DataContext = stepUI;
+            InitializeComponent();
+            CbRunMode.ItemsSource = RunModeData.ItemSource;
+            //CbAdapter.ItemsSource = StepAdapterData.ItemSource;
+        }
+    }
+}
diff --git a/Plugin.SeqEditor/SettingPanel/ViPanel.xaml b/Plugin.SeqEditor/SettingPanel/ViPanel.xaml
new file mode 100644
index 0000000..3811564
--- /dev/null
+++ b/Plugin.SeqEditor/SettingPanel/ViPanel.xaml
@@ -0,0 +1,48 @@
+锘�<UserControl x:Class="Plugin.SeqEditor.SettingPanel.ViPanel"
+             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.SeqEditor.SettingPanel"
+             mc:Ignorable="d" 
+             xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+             xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+             xmlns:ui="clr-namespace:HMI.UI;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"
+             Padding="5"
+             d:DesignHeight="450" d:DesignWidth="800">
+    <StackPanel>
+        <pu:FormGroup Header="{DynamicResource se.stepName}" 
+              Orientation="Vertical"
+              Style="{StaticResource InputFormGroupStyle}">
+
+            <TextBox IsReadOnly="True" Style="{StaticResource EditorTextBoxStyle}" Text="{Binding StepName}" />
+        </pu:FormGroup>
+
+        <pu:FormGroup Header="{DynamicResource se.stepType}" 
+      Orientation="Vertical"
+      Style="{StaticResource InputFormGroupStyle}">
+
+            <TextBox IsReadOnly="True" Style="{StaticResource EditorTextBoxStyle}" Text="{Binding StepType,Mode=OneWay}" />
+        </pu:FormGroup>
+
+        <pu:FormGroup Header="{DynamicResource se.runMode}" 
+                      Orientation="Vertical"
+                      Style="{StaticResource InputFormGroupStyle}">
+
+            <ComboBox x:Name="CbRunMode" 
+                      Style="{StaticResource FormComboxStyle}"
+                      SelectedValue="{Binding RunMode}" 
+                  DisplayMemberPath="DisplayName" SelectedValuePath="DataValue"/>
+        </pu:FormGroup>
+
+        <pu:FormGroup Header="{DynamicResource se.waitInterval}" 
+              Orientation="Vertical"
+              Style="{StaticResource InputFormGroupStyle}">
+            <ui:NumberInput Style="{StaticResource EditorTextBoxStyle}" 
+                            Text="{Binding TimeInterval,UpdateSourceTrigger=PropertyChanged}"/>
+        </pu:FormGroup>
+    </StackPanel>
+</UserControl>
diff --git a/Plugin.SeqEditor/SettingPanel/ViPanel.xaml.cs b/Plugin.SeqEditor/SettingPanel/ViPanel.xaml.cs
new file mode 100644
index 0000000..6b7c4cf
--- /dev/null
+++ b/Plugin.SeqEditor/SettingPanel/ViPanel.xaml.cs
@@ -0,0 +1,20 @@
+锘縰sing Plugin.SeqEditor.Entity;
+using Plugin.SeqEditor.Entity.EditablePO;
+using Plugin.SeqEditor.Util;
+using System.Windows.Controls;
+
+namespace Plugin.SeqEditor.SettingPanel
+{
+    /// <summary>
+    /// WaitPanel.xaml 鐨勪氦浜掗�昏緫
+    /// </summary>
+    public partial class ViPanel : UserControl
+    {
+        public ViPanel(ViCallEPO epo)
+        {
+            this.DataContext = epo;
+            InitializeComponent();
+            CbRunMode.ItemsSource = RunModeData.ItemSource;
+        }
+    }
+}
diff --git a/Plugin.SeqEditor/Util/Step2EPO.cs b/Plugin.SeqEditor/Util/Step2EPO.cs
index 86f229a..21fa9c3 100644
--- a/Plugin.SeqEditor/Util/Step2EPO.cs
+++ b/Plugin.SeqEditor/Util/Step2EPO.cs
@@ -34,10 +34,15 @@
                 case StepTypeStr.NumericLimitTest:
                     epo = new NumValTestEPO(step);
                     return new NumValTestPanel((NumValTestEPO)epo);
-                //case StepTypeStr.Action:
+                case StepTypeStr.SequenceCall:
+                    return new CallSeqPanel(step);
                 //    return new ActionPanel(step);
                 //case StepTypeStr.SequenceCall:
                 //    return new ActionPanel(step);
+                //case StepTypeStr.Action:
+                //    if (step.Adapter == AdapterName.VICall)
+                //        return new ViPanel(new ViCallEPO(step));
+                //    else return new ActionPanel(step);
                 default:
                     return new ActionPanel(step);
             }
diff --git a/Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs b/Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs
index 69b5ee8..fe22156 100644
--- a/Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs
+++ b/Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs
@@ -12,6 +12,7 @@
 using Plugin.SeqEditor.Util;
 using System.Collections.ObjectModel;
 using System.IO;
+using System.Runtime.InteropServices;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Data;
@@ -60,6 +61,9 @@
 
         private Engine engine;
         private SequenceFile sequenceFile;
+
+        public Dictionary<string, SequenceFile> cacheFiles = new Dictionary<string, SequenceFile>();
+
         private bool isLoaded;
         private ILog log;
         public SeqEditor control { get; private set; }
@@ -68,6 +72,15 @@
 
         private HashSet<string> edits = new HashSet<string>();
         public Dictionary<Sequence, ObservableCollection<StepUI>> sequenceCache { get; private set; } = new();
+
+        private HashSet<string> indexType = new HashSet<string> {
+            StepTypeStr.PassFailTest,
+            StepTypeStr.NumericLimitTest,
+            StepTypeStr.NI_MultipleNumericLimitTest,
+            StepTypeStr.StringValueTest,
+            StepTypeStr.NI_Wait,
+            StepTypeStr.Action
+    };
 
         public SeqEditorViewModel(SeqEditor control, ILog log)
         {
@@ -87,18 +100,23 @@
                 {
                     engine.ReleaseSequenceFileEx(sequenceFile);
                 }
+                foreach (var file in cacheFiles.Values)
+                {
+                    engine.ReleaseSequenceFileEx(file);
+                }
                 engine.ShutDown(true);
                 // 涓嶅姞寤舵椂浼氬脊绐梞d
-                System.Threading.Thread.Sleep(2500);
+                //System.Threading.Thread.Sleep(2500);
             }
         }
 
         private ObservableCollection<StepUI> LoadSteps(Sequence seq, string group = null)
         {
-            if (sequenceCache.ContainsKey(seq))
-            {
-                return sequenceCache[seq];
-            }
+            //if (sequenceCache.ContainsKey(seq))
+            //{
+            //    return sequenceCache[seq];
+            //}
+
             //setupSteps.Clear();
             //var steps = new ObservableCollection<StepUI>();
             //int num = seq.GetNumSteps(StepGroups.StepGroup_Setup);
@@ -231,10 +249,39 @@
                     }
                     ui.Children = LoadSteps(sunSequence, group);
                 }
+                else
+                {
+                    string seqName = po.GetValString("SeqName", 0);
+                    if (!Path.IsPathRooted(sfPath))
+                    {
+                        sfPath = Path.Combine(Path.GetDirectoryName(CurrentFilePath), sfPath);
+                    }
+                    SequenceFile diffSequence = null;
+                    try
+                    {
+                        if (cacheFiles.ContainsKey(sfPath))
+                        {
+                            diffSequence = cacheFiles[sfPath];
+                        }
+                        else if (File.Exists(sfPath))
+                        {
+                            diffSequence = engine.GetSequenceFileEx(sfPath);
+                            cacheFiles[sfPath] = diffSequence;
+                        }
+                    }
+                    catch (Exception ex)
+                    {
+                        log.Warn("Read Diff SubSequence Failed.", ex);
+                    }
+                    if (diffSequence != null)
+                    {
+                        Sequence sunSequence = diffSequence.GetSequenceByName(seqName);
+                        ui.Children = LoadSteps(sunSequence, group);
+                    }
+                }
             }
             else
             {
-                ui.CustomIndex = ++indexCache;
             }
             if (CurrentSeqUI != null)
             {
@@ -309,6 +356,10 @@
             {
                 sequenceFile?.Save(CurrentFilePath);
                 CurrentSeqUI.IsChanged = false;
+                foreach (var key in cacheFiles.Keys)
+                {
+                    cacheFiles[key]?.Save(key);
+                }
                 ToastHelper.Success(LangUtil.Get("App.SaveSuccess"));
             }
             catch (Exception ex)
@@ -332,6 +383,10 @@
                 {
                     sequenceFile.Save(sfd.FileName);
                     CurrentFilePath = sfd.FileName;
+                    foreach (var key in cacheFiles.Keys)
+                    {
+                        cacheFiles[key]?.Save(key);
+                    }
                     ToastHelper.Success(LangUtil.Get("App.SaveSuccess"));
                     CurrentSeqUI.IsChanged = false;
                 }
@@ -369,9 +424,14 @@
             if (engine != null && sequenceFile != null)
             {
                 engine.ReleaseSequenceFileEx(sequenceFile);
+                foreach (var file in cacheFiles.Values)
+                {
+                    engine.ReleaseSequenceFileEx(file);
+                }
                 sequenceFile = null;
             }
 
+            cacheFiles.Clear();
             setupSteps.Clear();
             mainSteps.Clear();
             cleanupSteps.Clear();
@@ -552,7 +612,38 @@
         {
             indexCache = 0;
             sequenceCache.Clear();
-            AllSteps = LoadSteps(CurrentSeqUI.sequence);
+            foreach (var file in cacheFiles.Values)
+            {
+                try
+                {
+                    engine.ReleaseSequenceFileEx(file);
+                    Marshal.ReleaseComObject(file);
+                }
+                catch (Exception ex)
+                {
+                    log.Error("RefreshData Release Last CacheFile Failed.", ex);
+                }
+            }
+            var converter = control.Resources["treeNumber"] as RowNumberConverter;
+            converter.Reset();
+            var temp = LoadSteps(CurrentSeqUI.sequence);
+            SetIndex(temp);
+            AllSteps = temp;
+        }
+
+        void SetIndex(IEnumerable<StepUI> datas)
+        {
+            foreach (var data in datas)
+            {
+                if (indexType.Contains(data.Type))
+                {
+                    data.CustomIndex = ++indexCache;
+                }
+                if (data.Children != null && data.Children.Count > 0)
+                {
+                    SetIndex(data.Children);
+                }
+            }
         }
 
         partial void OnAllStepsChanged(ObservableCollection<StepUI> data)
diff --git a/Plugin.TestResult/Plugin.TestResult.csproj b/Plugin.TestResult/Plugin.TestResult.csproj
index f24e6c6..764cf99 100644
--- a/Plugin.TestResult/Plugin.TestResult.csproj
+++ b/Plugin.TestResult/Plugin.TestResult.csproj
@@ -51,6 +51,24 @@
     <LangVersion>7.3</LangVersion>
     <ErrorReport>prompt</ErrorReport>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <LangVersion>7.3</LangVersion>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <LangVersion>7.3</LangVersion>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
   <ItemGroup>
     <Reference Include="GLWpfControl, Version=3.3.0.0, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\OpenTK.GLWpfControl.3.3.0\lib\net452\GLWpfControl.dll</HintPath>
@@ -61,37 +79,18 @@
     <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>
-      <EmbedInteropTypes>True</EmbedInteropTypes>
-      <HintPath>..\Libs\NationalInstruments.TestStand.Interop.AdapterAPI.dll</HintPath>
-    </Reference>
     <Reference Include="NationalInstruments.TestStand.Interop.API, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <EmbedInteropTypes>True</EmbedInteropTypes>
       <HintPath>..\Libs\NationalInstruments.TestStand.Interop.API.dll</HintPath>
     </Reference>
-    <Reference Include="NationalInstruments.TestStand.Interop.SequenceAnalyzer, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <EmbedInteropTypes>True</EmbedInteropTypes>
-      <HintPath>..\Libs\NationalInstruments.TestStand.Interop.SequenceAnalyzer.dll</HintPath>
-    </Reference>
-    <Reference Include="NationalInstruments.TestStand.Interop.UI, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <EmbedInteropTypes>True</EmbedInteropTypes>
-      <HintPath>..\Libs\NationalInstruments.TestStand.Interop.UI.dll</HintPath>
-    </Reference>
     <Reference Include="NationalInstruments.TestStand.Interop.UI.AxControls, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\Libs\NationalInstruments.TestStand.Interop.UI.AxControls.dll</HintPath>
     </Reference>
-    <Reference Include="NationalInstruments.TestStand.Interop.UI.Support, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL">
+    <Reference Include="NationalInstruments.TestStand.Utility, Version=25.0.0.49152, Culture=neutral, processorArchitecture=AMD64">
       <SpecificVersion>False</SpecificVersion>
-      <EmbedInteropTypes>True</EmbedInteropTypes>
-      <HintPath>..\Libs\NationalInstruments.TestStand.Interop.UI.Support.dll</HintPath>
-    </Reference>
-    <Reference Include="NationalInstruments.TestStand.Utility">
-      <HintPath>..\Libs\NationalInstruments.TestStand.Utility.dll</HintPath>
+      <HintPath>..\..\..\..\Program Files\National Instruments\TestStand 2020\API\DotNET\Assemblies\CurrentVersion\NationalInstruments.TestStand.Utility.dll</HintPath>
     </Reference>
     <Reference Include="OpenTK, Version=3.3.1.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\OpenTK.3.3.1\lib\net20\OpenTK.dll</HintPath>
@@ -142,9 +141,6 @@
     <Reference Include="System.Configuration" />
     <Reference Include="System.Data" />
     <Reference Include="System.Drawing" />
-    <Reference Include="System.Drawing.Common, Version=4.0.0.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\System.Drawing.Common.4.7.3\lib\net461\System.Drawing.Common.dll</HintPath>
-    </Reference>
     <Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
       <SpecificVersion>False</SpecificVersion>
diff --git a/Plugin.TestResult/ViewControl.xaml.cs b/Plugin.TestResult/ViewControl.xaml.cs
index 9c023ab..13cb7c7 100644
--- a/Plugin.TestResult/ViewControl.xaml.cs
+++ b/Plugin.TestResult/ViewControl.xaml.cs
@@ -228,7 +228,7 @@
             }
             testResultView.SetProductSource(productSource);
 
-            string model = testResultView.engine.Globals.GetValString("ProductModel", 0);
+            string model = testResultView.engine.Globals.GetValString("ProductModel", 1);
             if (!string.IsNullOrEmpty(model))
             {
                 this.modelSelect.SelectedItem = model;
diff --git a/Plugin.TsExecution/Plugin.TsExecution.csproj b/Plugin.TsExecution/Plugin.TsExecution.csproj
index eb60ee6..aa02534 100644
--- a/Plugin.TsExecution/Plugin.TsExecution.csproj
+++ b/Plugin.TsExecution/Plugin.TsExecution.csproj
@@ -51,6 +51,24 @@
     <LangVersion>7.3</LangVersion>
     <ErrorReport>prompt</ErrorReport>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <LangVersion>7.3</LangVersion>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <LangVersion>7.3</LangVersion>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
   <ItemGroup>
     <Reference Include="GLWpfControl, Version=3.3.0.0, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\OpenTK.GLWpfControl.3.3.0\lib\net452\GLWpfControl.dll</HintPath>
@@ -208,6 +226,10 @@
       <Project>{AFEA100A-9223-448D-AB10-3015D93DD98C}</Project>
       <Name>HMI.Util</Name>
     </ProjectReference>
+    <ProjectReference Include="..\Plugin.TsSupport\Plugin.TsSupport.csproj">
+      <Project>{3068124E-F12B-473E-99A0-2DA5A0385D05}</Project>
+      <Name>Plugin.TsSupport</Name>
+    </ProjectReference>
     <ProjectReference Include="..\SimpleUtil\HMI.MQUtil\HMI.MQUtil.csproj">
       <Project>{f8b8b6b6-821b-4ff6-b556-9cab840ea57a}</Project>
       <Name>HMI.MQUtil</Name>
diff --git a/Plugin.TsExecution/Properties/AssemblyInfo.cs b/Plugin.TsExecution/Properties/AssemblyInfo.cs
index e2b8012..66e36ba 100644
--- a/Plugin.TsExecution/Properties/AssemblyInfo.cs
+++ b/Plugin.TsExecution/Properties/AssemblyInfo.cs
@@ -50,5 +50,5 @@
 //      淇鍙�
 //
 [assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.1")]
 [assembly: PluginClassName("Plugin.TsExecution.TsExecution")]
diff --git a/Plugin.TsExecution/SingleControl.xaml b/Plugin.TsExecution/SingleControl.xaml
index 11d834d..06c8185 100644
--- a/Plugin.TsExecution/SingleControl.xaml
+++ b/Plugin.TsExecution/SingleControl.xaml
@@ -339,12 +339,13 @@
 
             <DataGrid Grid.Row="0" Style="{StaticResource DefaultDataGrid}" 
                       Margin="5,0,5,5"
+                      pu:DataGridHelper.ColumnHeaderFontWeight="Normal"
                   pu:DataGridHelper.ColumnHeaderFontSize="{Binding ActualWidth,
             ElementName=control,
-Converter={StaticResource fc}, ConverterParameter='15,1093,15,22'}"
+Converter={StaticResource fc}, ConverterParameter='11,1093,14'}"
             FontSize="{Binding ActualWidth,
             ElementName=control,
-Converter={StaticResource fc}, ConverterParameter='15,1093,15,20'}"
+Converter={StaticResource fc}, ConverterParameter='11,1093,14'}"
                   pu:DataGridHelper.ColumnHeaderPadding="3"
                   dp:DataGridHelper.ShowRowNumber="True"
                   VirtualizingPanel.IsContainerVirtualizable="True"
@@ -352,7 +353,7 @@
                   VirtualizingPanel.VirtualizationMode="Recycling"
                   RowHeight="{StaticResource nanD}"
                   ColumnHeaderHeight="{Binding ActualWidth,ElementName=control,
-Converter={StaticResource fc}, ConverterParameter='30,1093,-1,45'}"
+Converter={StaticResource fc}, ConverterParameter='32,1093,30,45'}"
                   ItemsSource="{Binding Datasource}"
                   x:Name="table">
                 <DataGrid.Resources>
@@ -375,44 +376,44 @@
                     <DataGridTextColumn Header="#" 
                                         ElementStyle="{StaticResource TableTextBlock}"
                         Binding="{Binding Header, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}, Mode=FindAncestor}}" 
-                                    Width="60"/>
-                    <DataGridTextColumn Width="*" Binding="{Binding Name}" 
+                                    Width="0.4*"/>
+                    <DataGridTextColumn Width="2.5*" Binding="{Binding Name}" 
                                         ElementStyle="{StaticResource TableTextBlock}">
                         <DataGridTextColumn.Header>
                             <TextBlock Text="{DynamicResource Test.Name}"/>
                         </DataGridTextColumn.Header>
                     </DataGridTextColumn>
-                    <DataGridTextColumn Width="100" Binding="{Binding Unit}" 
+                    <DataGridTextColumn Width="0.8*" Binding="{Binding Unit}" 
                                         ElementStyle="{StaticResource TableTextBlock}">
                         <DataGridTextColumn.Header>
                             <TextBlock Text="{DynamicResource Test.Unit}"/>
                         </DataGridTextColumn.Header>
                     </DataGridTextColumn>
-                    <DataGridTextColumn Width="*" Binding="{Binding Value}" 
+                    <DataGridTextColumn Width="2*" Binding="{Binding Value}" 
                                         ElementStyle="{StaticResource TableTextBlock}">
                         <DataGridTextColumn.Header>
                             <TextBlock Text="{DynamicResource Test.Value}"/>
                         </DataGridTextColumn.Header>
                     </DataGridTextColumn>
-                    <DataGridTextColumn Width="*" Binding="{Binding LimitDown}" 
+                    <DataGridTextColumn Width="1.5*" Binding="{Binding LimitDown}" 
                                         ElementStyle="{StaticResource TableTextBlock}">
                         <DataGridTextColumn.Header>
                             <TextBlock Text="{DynamicResource Test.LimitDown}"/>
                         </DataGridTextColumn.Header>
                     </DataGridTextColumn>
-                    <DataGridTextColumn Width="*" Binding="{Binding LimitUp}" 
+                    <DataGridTextColumn Width="1.5*" Binding="{Binding LimitUp}" 
                                         ElementStyle="{StaticResource TableTextBlock}">
                         <DataGridTextColumn.Header>
                             <TextBlock Text="{DynamicResource Test.LimitUp}"/>
                         </DataGridTextColumn.Header>
                     </DataGridTextColumn>
-                    <DataGridTextColumn Width="180" Binding="{Binding ConsumeTime}"
+                    <DataGridTextColumn Width="0.6*" Binding="{Binding ConsumeTime}"
                     ElementStyle="{StaticResource TableTextBlock}">
                         <DataGridTextColumn.Header>
                             <TextBlock Text="{DynamicResource Test.ConsumeTime}"/>
                         </DataGridTextColumn.Header>
                     </DataGridTextColumn>
-                    <DataGridTemplateColumn Width="120">
+                    <DataGridTemplateColumn Width="1*">
                         <DataGridTemplateColumn.Header>
                             <TextBlock Text="{DynamicResource Test.Result}"/>
                         </DataGridTemplateColumn.Header>
diff --git a/Plugin.TsExecution/SingleControl.xaml.cs b/Plugin.TsExecution/SingleControl.xaml.cs
index 293f3f6..a31533f 100644
--- a/Plugin.TsExecution/SingleControl.xaml.cs
+++ b/Plugin.TsExecution/SingleControl.xaml.cs
@@ -101,6 +101,13 @@
             set { Set(ref barcode, value); }
         }
 
+        private string model = string.Empty;
+        public string Model
+        {
+            get { return model; }
+            set { Set(ref model, value); }
+        }
+
         private string elapseTime = "00:00:00";
         public string ElapseTime
         {
@@ -302,7 +309,7 @@
                     var now = DateTime.Now;
                     var span = now - StepStartTime;
                     StepStartTime = now;
-                    data.ConsumeTime = $"{span.Seconds}s";
+                    data.ConsumeTime = $"{(span.TotalMilliseconds / 1000d).ToString("F2")}s";
                     Datasource.Add(data);
                     table.ScrollIntoView(data);
                 }));
diff --git a/Plugin.TsExecution/TsExecution.xaml b/Plugin.TsExecution/TsExecution.xaml
index 07384b6..72fd7e1 100644
--- a/Plugin.TsExecution/TsExecution.xaml
+++ b/Plugin.TsExecution/TsExecution.xaml
@@ -48,22 +48,27 @@
 SelectedItem="{Binding SelectedProduct}" x:Name="CbProduct"/>
                     </pu:FormGroup>
 
-                    <CheckBox Grid.Column="1"
+                    <CheckBox x:Name="CbEnableMes"
         IsChecked="{Binding EnableMes,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
         Content="{DynamicResource Ts.EnableMes}"
         />
-                    <CheckBox Grid.Column="2" 
+                    <CheckBox x:Name="CbEnableNGPause"
               IsChecked="{Binding EnableNGPause,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
               Content="{DynamicResource Ts.EnableNGPause}"
               />
-                    <CheckBox Grid.Column="3" 
+                    <CheckBox x:Name="CbEnableDebugMode"
               IsChecked="{Binding EnableDebugMode,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
               Content="{DynamicResource Ts.DebugMode}"/>
-                    <CheckBox Grid.Column="4" 
+
+                    <CheckBox x:Name="CbDisableScanner"
+IsChecked="{Binding DisableScanner,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
+Content="灞忚斀鎵爜"/>
+
+                    <CheckBox x:Name="CbEnableSimpleMode"
 IsChecked="{Binding EnableSimpleMode,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
 Content="{DynamicResource Ts.EnableSimpleMode}"/>
 
-                    <CheckBox Grid.Column="4" 
+                    <CheckBox x:Name="CbUI_ShowInfoDock"
 IsChecked="{Binding UI_ShowInfoDock,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
 Content="{DynamicResource Ts.UI_ShowInfoDock}"/>
 
diff --git a/Plugin.TsExecution/TsExecution.xaml.cs b/Plugin.TsExecution/TsExecution.xaml.cs
index 724fe97..83c45f0 100644
--- a/Plugin.TsExecution/TsExecution.xaml.cs
+++ b/Plugin.TsExecution/TsExecution.xaml.cs
@@ -13,6 +13,7 @@
 using NationalInstruments.TestStand.Interop.API;
 using NationalInstruments.TestStand.Interop.UI.Ax;
 using Panuon.WPF.UI;
+using Plugin.TsSupport;
 using ScottPlot;
 using ScottPlot.Plottables;
 using System;
@@ -249,6 +250,19 @@
             }
         }
 
+        private bool _DisableScanner;
+        public bool DisableScanner
+        {
+            get => _DisableScanner;
+            set
+            {
+                if (WriteConfig("DisableScanner", value))
+                {
+                    Set(ref _DisableScanner, value);
+                }
+            }
+        }
+
         private string dataLogPath;
         private SqliteHelper sqliteHelper;
 
@@ -284,6 +298,7 @@
             sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS serialData (
                     id INTEGER PRIMARY KEY AUTOINCREMENT,
                     sn TEXT NOT NULL,
+                    model TEXT,
                     station TEXT NOT NULL,
                     step TEXT NOT NULL,
                     limitDown TEXT,
@@ -296,6 +311,48 @@
                     consumeTime TEXT, 
                     totalConsumeTime TEXT, 
                     time DATETIME NOT NULL);");
+            sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS testResult (
+                    id INTEGER PRIMARY KEY AUTOINCREMENT,
+                    sn TEXT NOT NULL,
+                    model TEXT,
+                    station TEXT NOT NULL,
+                    result TEXT NOT NULL, 
+                    time DATETIME NOT NULL);");
+            try
+            {
+                sqliteHelper.ExecuteSql("alter table serialData add column 'model' TEXT default NULL;");
+            }
+            catch
+            {
+
+            }
+
+            try
+            {
+                sqliteHelper.ExecuteSql("alter table serialData add column 'position' TEXT default NULL;");
+            }
+            catch
+            {
+
+            }
+            try
+            {
+                sqliteHelper.ExecuteSql("alter table testResult add column 'position' TEXT default NULL;");
+            }
+            catch
+            {
+
+            }
+
+            try
+            {
+                sqliteHelper.ExecuteSql("alter table testResult add column 'status' TEXT default NULL;");
+            }
+            catch
+            {
+
+            }
+
             base.InitFinish();
         }
 
@@ -430,13 +487,14 @@
         /// </summary>
         private void InitTsEngine()
         {
-            AxApplicationMgr = new AxApplicationMgr();
+            AxApplicationMgr = TestAppManager.GetAxApplicationMgr();
             AxApplicationMgr.EndExecution += AxApplicationMgr_EndExecution;
             AxApplicationMgr.ExitApplication += new EventHandler(this.AxApplicationMgr_ExitApplication);
             AxApplicationMgr.UIMessageEvent +=
                 new _ApplicationMgrEvents_UIMessageEventEventHandler(this.AxApplicationMgr_UIMessageEvent);
             AxApplicationMgr.ExecutionClosed +=
                 new _ApplicationMgrEvents_ExecutionClosedEventHandler(this.AxApplicationMgr_ExecutionClosed);
+
             ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).BeginInit();
             host.Child = AxApplicationMgr;
             ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).EndInit();
@@ -444,7 +502,25 @@
 
         private void AxApplicationMgr_EndExecution(object sender, _ApplicationMgrEvents_EndExecutionEvent e)
         {
-            ReleaseSequenceFile();
+            log.Info("AxApplicationMgr_EndExecution");
+            if (ReleaseSequenceFile())
+            {
+                log.Info("Release SeqFile Success!");
+            }
+            else
+            {
+                log.Warn("Release SeqFile Fail!");
+            }
+        }
+
+        /// <summary>
+        /// 杩涚▼缁撴潫浜嬩欢
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void AxApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e)
+        {
+            //ReleaseSequenceFile();
         }
 
         private void PluginControl_Loaded(object sender, RoutedEventArgs e)
@@ -542,7 +618,7 @@
                 this.AxApplicationMgr.IsEditor = true;
                 this.AxApplicationMgr.LoginOnStart = false;
                 this.AxApplicationMgr.Start();
-                this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq");
+                //this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq");
             }
             catch (Exception ex)
             {
@@ -571,28 +647,104 @@
         private void ReadConfig()
         {
             ParameterData value;
+
+
+            bool flag = false;
             try
             {
-                value = ParameterManager.GetCommonParameterByName("EnableMes");
-                _enableMes = bool.Parse(value.Value);
-                Set("EnableMes");
+                value = ParameterManager.GetCommonParameterByName("DefaultEnableMes");
+                if (value != null)
+                {
+                    flag = bool.Parse(value.Value);
+                }
             }
             catch
             {
-                _enableMes = false;
-                Set("EnableMes");
+                flag = false;
             }
+
+            if (flag)
+            {
+                EnableMes = true;
+            }
+            else
+            {
+                try
+                {
+                    value = ParameterManager.GetCommonParameterByName("EnableMes");
+                    if (value == null)
+                    {
+                        CbEnableMes.Visibility = Visibility.Collapsed;
+                    }
+                    else
+                    {
+                        _enableMes = bool.Parse(value.Value);
+                        Set("EnableMes");
+                    }
+                }
+                catch
+                {
+                    _enableMes = false;
+                    Set("EnableMes");
+                }
+            }
+
 
             try
             {
                 value = ParameterManager.GetCommonParameterByName("EnableNGPause");
-                _enableNGPause = bool.Parse(value.Value);
-                Set("EnableNGPause");
+                if (value == null)
+                {
+                    CbEnableNGPause.Visibility = Visibility.Collapsed;
+                }
+                else
+                {
+                    _enableNGPause = bool.Parse(value.Value);
+                    Set("EnableNGPause");
+                }
             }
             catch
             {
                 _enableNGPause = false;
                 Set("EnableNGPause");
+            }
+
+            try
+            {
+                value = ParameterManager.GetCommonParameterByName("EnableDebugMode");
+                if (value == null)
+                {
+                    CbEnableDebugMode.Visibility = Visibility.Collapsed;
+                }
+                else
+                {
+                    _enableDebugMode = bool.Parse(value.Value);
+                    Set("EnableDebugMode");
+                }
+            }
+            catch
+            {
+                _enableDebugMode = false;
+                Set("EnableDebugMode");
+            }
+
+            try
+            {
+                value = ParameterManager.GetCommonParameterByName("DisableScanner");
+                if (value == null)
+                {
+                    CbDisableScanner.Visibility = Visibility.Collapsed;
+                }
+                else
+                {
+                    _DisableScanner = bool.Parse(value.Value);
+                    Set("DisableScanner");
+                }
+            }
+            catch
+            {
+                _DisableScanner = false;
+                Set("DisableScanner");
             }
 
             try
@@ -607,22 +759,18 @@
                 Set("EnableCanLog");
             }
 
-            try
-            {
-                value = ParameterManager.GetCommonParameterByName("EnableDebugMode");
-                _enableDebugMode = bool.Parse(value.Value);
-                Set("EnableDebugMode");
-            }
-            catch
-            {
-                _enableDebugMode = false;
-                Set("EnableDebugMode");
-            }
 
             try
             {
                 value = ParameterManager.GetCommonParameterByName("EnableSimpleMode");
-                EnableSimpleMode = bool.Parse(value.Value);
+                if (value == null)
+                {
+                    CbEnableSimpleMode.Visibility = Visibility.Collapsed;
+                }
+                else
+                {
+                    EnableSimpleMode = bool.Parse(value.Value);
+                }
             }
             catch
             {
@@ -632,7 +780,14 @@
             try
             {
                 value = ParameterManager.GetCommonParameterByName("UI_ShowInfoDock");
-                UI_ShowInfoDock = bool.Parse(value.Value);
+                if (value == null)
+                {
+                    CbUI_ShowInfoDock.Visibility = Visibility.Collapsed;
+                }
+                else
+                {
+                    UI_ShowInfoDock = bool.Parse(value.Value);
+                }
             }
             catch
             {
@@ -846,8 +1001,9 @@
             {
                 engine?.Globals.SetValString("StationState.ProductModel", 1, SelectedProduct?.Name);
                 engine?.CommitGlobalsToDisk(promptOnSaveConflicts: false);
-                this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq");
-                this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 0, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType);
+                //this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq");
+                this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Users\Public\Documents\National Instruments\TestStand 2020 (64-bit)\Components\Models\ParallelModel.seq");
+                this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 2, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType);
                 this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null);
                 IsTesting = true;
             }
@@ -976,16 +1132,6 @@
             //this.Close();
         }
 
-        /// <summary>
-        /// 杩涚▼缁撴潫浜嬩欢
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e"></param>
-        private void AxApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e)
-        {
-            ReleaseSequenceFile();
-        }
-
         public void UpdatePositionStatus(int index, string status)
         {
             this.tsSockets[index].UpdateStatus(status);
@@ -1009,21 +1155,30 @@
                 TestItems[4], TestItems[5], TestItems[6]);
         }
 
-        public void SetPositionBarcode(int index, string barcode)
+        public void SetPositionBarcode(int index, string strData)
         {
-            this.tsSockets[index].Barcode = barcode;
+            if (strData.Contains(";"))
+            {
+                var strs = strData.Split(';');
+                this.tsSockets[index].Barcode = strs[0];
+                this.tsSockets[index].Model = strs[1];
+            }
+            else
+            {
+                this.tsSockets[index].Barcode = strData;
+            }
         }
 
-        public void SavePositionCSV(int index)
+        public void SavePositionCSV(int index, string csvPath)
         {
-            var time = DateTime.Now;
-            string status = this.tsSockets[index].Status == "Passed" ? "PASS" : "FAIL";
-            string csvPath = Path.Combine(csvDir, SelectedProduct?.Name ?? "鏈煡浜у搧", time.ToString("yyyyMMdd"), status,
-                $"{this.tsSockets[index].Barcode}-{time.ToString("HHmmss")}.csv");
+            //var time = DateTime.Now;
+            //string status = this.tsSockets[index].Status == "Passed" ? "PASS" : "FAIL";
+            //string csvPath = Path.Combine(csvDir, SelectedProduct?.Name ?? "鏈煡浜у搧", time.ToString("yyyyMMdd"), status,
+            //    $"{this.tsSockets[index].Barcode}-{time.ToString("HHmmss")}.csv");
             this.tsSockets[index].WriteToCSV(csvPath);
         }
 
-        public void SavePositionDB(int index)
+        public void SavePositionDB(int index, string status)
         {
             var socket = this.tsSockets[index];
             var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
@@ -1032,9 +1187,11 @@
             List<string> sqls = new List<string>();
             foreach (var data in socket.Datasource)
             {
-                sqls.Add($@"INSERT INTO serialData (sn,station,step,limitDown,limitUp,unit,value,status,finalStatus,consumeTime,totalConsumeTime,time) VALUES
-('{snr}','','{data.Name}','{data.LimitDown}','{data.LimitUp}','{data.Unit}','{data.Value}','{data.Result}','{socket.Status}','{data.ConsumeTime}','{socket.ElapseTime}','{time}')");
+                sqls.Add($@"INSERT INTO serialData (sn,model,station,step,limitDown,limitUp,unit,value,status,finalStatus,consumeTime,totalConsumeTime,time) VALUES
+('{snr}','{socket.Model}','','{data.Name}','{data.LimitDown}','{data.LimitUp}','{data.Unit}','{data.Value}','{data.Result}','{socket.Status}','{data.ConsumeTime}','{socket.ElapseTime}','{time}')");
             }
+            sqls.Add($@"INSERT INTO testResult (sn,model,station,result,time,position,status) VALUES 
+('{snr}','{socket.Model}','','{socket.Status}','{time}','{index}','{status}')");
             sqliteHelper.ExecuteBatchSql(sqls);
         }
 
@@ -1122,14 +1279,17 @@
                     this.tsSockets[index].SetTestProcess(ProcessVal);
                     break;
                 case 10031://瀵煎嚭CSV
-                    SavePositionCSV(index);
-                    SavePositionDB(index);
+                    string[] datas = strData.Split(';');
+                    SavePositionCSV(index, datas[0]);
+                    SavePositionDB(index, datas[1]);
                     break;
                 case 10032://鎸変笅鏍囨殏鍋滄祴璇�
                     this.tsSockets[index].ShowPausePanel();
                     break;
                 case 10033:
                     ShowAlarm(strData);
+                    break;
+                case 10099:
                     break;
                 default:
                     break;
@@ -1198,7 +1358,10 @@
             string name = product.Name;
             List<ParameterData> parameters = ProductManager.GetParametersByProductName(name);
             testSeqFile = parameters.FirstOrDefault(p => p.Name == "TestSequence")?.Value?.ToString();
-            StartSequence();
+            if (AutoExecuteSeq)
+            {
+                StartSequence();
+            }
         }
 
         private void ClearNum()
@@ -1229,6 +1392,11 @@
             }
         }
 
+        public override void DoClose(object sender, EventArgs e)
+        {
+            base.DoClose(sender, e);
+        }
+
         /// <summary>
         /// 閲婃斁鎵�鏈夌殑搴忓垪鏂囦欢
         /// </summary>
@@ -1238,18 +1406,35 @@
             {
                 lock (this)
                 {
-                    if (this.testSeq == null)
-                        return true;
-                    if (this.engine.ReleaseSequenceFileEx(this.testSeq, 4))
+                    //execution.Abort();
+                    int count = 10;
+                    while (count > 0)
                     {
-                        this.testSeq = null;
+                        try
+                        {
+                            if (this.testSeq == null)
+                                return true;
+
+                            if (this.engine.ReleaseSequenceFileEx(this.testSeq, 4))
+                            {
+                                this.testSeq = null;
+                            }
+                            if (this.engine.ReleaseSequenceFileEx(this.modeSeq, 4))
+                            {
+                                this.modeSeq = null;
+                            }
+                            this.engine.UnloadAllModules();
+                            return this.testSeq == null && this.modeSeq == null;
+                        }
+                        catch (Exception ex)
+                        {
+                            log.Warn($"ReleaseSequenceFile In {count} Times Fail.", ex);
+                            count--;
+                            System.Threading.Thread.Sleep(1000);
+                        }
                     }
-                    if (this.engine.ReleaseSequenceFileEx(this.modeSeq, 4))
-                    {
-                        this.modeSeq = null;
-                    }
-                    this.engine.UnloadAllModules();
-                    return true;
+                    log.Warn($"ReleaseSequenceFile Failed.");
+                    return false;
                 }
             }
             catch (Exception ex)
diff --git a/SimpleUtil/DIOController/DIOController.csproj b/SimpleUtil/DIOController/DIOController.csproj
new file mode 100644
index 0000000..21817a0
--- /dev/null
+++ b/SimpleUtil/DIOController/DIOController.csproj
@@ -0,0 +1,70 @@
+<?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>{34FFBAFE-478F-4B6E-95E7-92A949011A9B}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>DIOController</RootNamespace>
+    <AssemblyName>DIOController</AssemblyName>
+    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <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>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Dask.cs" />
+    <Compile Include="DaskHelper.cs" />
+    <Compile Include="DIOControllerCreator.cs" />
+    <Compile Include="IDIOController.cs" />
+    <Compile Include="IniFileHelper.cs" />
+    <Compile Include="ModBusTcpController.cs" />
+    <Compile Include="PCIController.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\hslCommunicationV12.0.3甯︽簮鐮乨emo\HslCommunication\HslCommunication.csproj">
+      <Project>{aa30059e-7269-415c-9df2-55c310dd5548}</Project>
+      <Name>HslCommunication</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="PCI-Dask64.dll">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="template.ini">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
diff --git a/SimpleUtil/DIOController/DIOControllerCreator.cs b/SimpleUtil/DIOController/DIOControllerCreator.cs
new file mode 100644
index 0000000..eafecd5
--- /dev/null
+++ b/SimpleUtil/DIOController/DIOControllerCreator.cs
@@ -0,0 +1,31 @@
+锘縰sing System;
+using System.IO;
+
+namespace DIOController
+{
+    public class DIOControllerCreator
+    {
+        public static IDIOController CreateController(string iniFile)
+        {
+            if (!File.Exists(iniFile)) throw new Exception("鏈壘鍒伴厤缃枃浠�");
+            string type = IniFileHelper.ReadIniData("Config", "Type", "", iniFile);
+            switch (type)
+            {
+                case "ModbusTcp":
+                    string ip = IniFileHelper.ReadIniData("Config", "Ip", "127.0.0.1", iniFile);
+                    string portStr = IniFileHelper.ReadIniData("Config", "Port", "502", iniFile);
+                    int port = int.Parse(portStr);
+                    return new ModBusTcpController
+                    {
+                        Ip = ip,
+                        Port = port
+                    };
+                case "PCI_7432":
+                    string name = IniFileHelper.ReadIniData("Config", "Name", "PCI_7432", iniFile);
+                    return new PCIController { Name = name };
+                default:
+                    throw new Exception("鏃犳晥鐨勬帶鍒跺櫒绫诲瀷");
+            }
+        }
+    }
+}
diff --git a/SimpleUtil/DIOController/Dask.cs b/SimpleUtil/DIOController/Dask.cs
new file mode 100644
index 0000000..f8a0d60
--- /dev/null
+++ b/SimpleUtil/DIOController/Dask.cs
@@ -0,0 +1,803 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace DIOController
+{
+    public delegate void CallbackDelegate();
+
+    public class DASK
+    {
+        //ADLink PCI Card Type
+        public const ushort PCI_6208V = 1;
+        public const ushort PCI_6208A = 2;
+        public const ushort PCI_6308V = 3;
+        public const ushort PCI_6308A = 4;
+        public const ushort PCI_7200 = 5;
+        public const ushort PCI_7230 = 6;
+        public const ushort PCI_7233 = 7;
+        public const ushort PCI_7234 = 8;
+        public const ushort PCI_7248 = 9;
+        public const ushort PCI_7249 = 10;
+        public const ushort PCI_7250 = 11;
+        public const ushort PCI_7252 = 12;
+        public const ushort PCI_7296 = 13;
+        public const ushort PCI_7300A_RevA = 14;
+        public const ushort PCI_7300A_RevB = 15;
+        public const ushort PCI_7432 = 16;
+        public const ushort PCI_7433 = 17;
+        public const ushort PCI_7434 = 18;
+        public const ushort PCI_8554 = 19;
+        public const ushort PCI_9111DG = 20;
+        public const ushort PCI_9111HR = 21;
+        public const ushort PCI_9112 = 22;
+        public const ushort PCI_9113 = 23;
+        public const ushort PCI_9114DG = 24;
+        public const ushort PCI_9114HG = 25;
+        public const ushort PCI_9118DG = 26;
+        public const ushort PCI_9118HG = 27;
+        public const ushort PCI_9118HR = 28;
+        public const ushort PCI_9810 = 29;
+        public const ushort PCI_9812 = 30;
+        public const ushort PCI_7396 = 31;
+        public const ushort PCI_9116 = 32;
+        public const ushort PCI_7256 = 33;
+        public const ushort PCI_7258 = 34;
+        public const ushort PCI_7260 = 35;
+        public const ushort PCI_7452 = 36;
+        public const ushort PCI_7442 = 37;
+
+        public const ushort MAX_CARD = 32;
+
+        //Error Number
+        public const short NoError = 0;
+        public const short ErrorUnknownCardType = -1;
+        public const short ErrorInvalidCardNumber = -2;
+        public const short ErrorTooManyCardRegistered = -3;
+        public const short ErrorCardNotRegistered = -4;
+        public const short ErrorFuncNotSupport = -5;
+        public const short ErrorInvalidIoChannel = -6;
+        public const short ErrorInvalidAdRange = -7;
+        public const short ErrorContIoNotAllowed = -8;
+        public const short ErrorDiffRangeNotSupport = -9;
+        public const short ErrorLastChannelNotZero = -10;
+        public const short ErrorChannelNotDescending = -11;
+        public const short ErrorChannelNotAscending = -12;
+        public const short ErrorOpenDriverFailed = -13;
+        public const short ErrorOpenEventFailed = -14;
+        public const short ErrorTransferCountTooLarge = -15;
+        public const short ErrorNotDoubleBufferMode = -16;
+        public const short ErrorInvalidSampleRate = -17;
+        public const short ErrorInvalidCounterMode = -18;
+        public const short ErrorInvalidCounter = -19;
+        public const short ErrorInvalidCounterState = -20;
+        public const short ErrorInvalidBinBcdParam = -21;
+        public const short ErrorBadCardType = -22;
+        public const short ErrorInvalidDaRefVoltage = -23;
+        public const short ErrorAdTimeOut = -24;
+        public const short ErrorNoAsyncAI = -25;
+        public const short ErrorNoAsyncAO = -26;
+        public const short ErrorNoAsyncDI = -27;
+        public const short ErrorNoAsyncDO = -28;
+        public const short ErrorNotInputPort = -29;
+        public const short ErrorNotOutputPort = -30;
+        public const short ErrorInvalidDioPort = -31;
+        public const short ErrorInvalidDioLine = -32;
+        public const short ErrorContIoActive = -33;
+        public const short ErrorDblBufModeNotAllowed = -34;
+        public const short ErrorConfigFailed = -35;
+        public const short ErrorInvalidPortDirection = -36;
+        public const short ErrorBeginThreadError = -37;
+        public const short ErrorInvalidPortWidth = -38;
+        public const short ErrorInvalidCtrSource = -39;
+        public const short ErrorOpenFile = -40;
+        public const short ErrorAllocateMemory = -41;
+        public const short ErrorDaVoltageOutOfRange = -42;
+        public const short ErrorDaExtRefNotAllowed = -43;
+        public const short ErrorDIODataWidthError = -44;
+        public const short ErrorTaskCodeError = -45;
+        public const short ErrortriggercountError = -46;
+        public const short ErrorInvalidTriggerMode = -47;
+        public const short ErrorInvalidTriggerType = -48;
+        public const short ErrorInvalidCounterValue = -50;
+        public const short ErrorInvalidEventHandle = -60;
+        public const short ErrorNoMessageAvailable = -61;
+        public const short ErrorEventMessgaeNotAdded = -62;
+        //Error number for driver API 
+        public const short ErrorConfigIoctl = -201;
+        public const short ErrorAsyncSetIoctl = -202;
+        public const short ErrorDBSetIoctl = -203;
+        public const short ErrorDBHalfReadyIoctl = -204;
+        public const short ErrorContOPIoctl = -205;
+        public const short ErrorContStatusIoctl = -206;
+        public const short ErrorPIOIoctl = -207;
+        public const short ErrorDIntSetIoctl = -208;
+        public const short ErrorWaitEvtIoctl = -209;
+        public const short ErrorOpenEvtIoctl = -210;
+        public const short ErrorCOSIntSetIoctl = -211;
+        public const short ErrorMemMapIoctl = -212;
+        public const short ErrorMemUMapSetIoctl = -213;
+        public const short ErrorCTRIoctl = -214;
+        public const short ErrorGetResIoctl = -215;
+
+        //Synchronous Mode
+        public const ushort SYNCH_OP = 1;
+        public const ushort ASYNCH_OP = 2;
+
+        //AD Range
+        public const ushort AD_B_10_V = 1;
+        public const ushort AD_B_5_V = 2;
+        public const ushort AD_B_2_5_V = 3;
+        public const ushort AD_B_1_25_V = 4;
+        public const ushort AD_B_0_625_V = 5;
+        public const ushort AD_B_0_3125_V = 6;
+        public const ushort AD_B_0_5_V = 7;
+        public const ushort AD_B_0_05_V = 8;
+        public const ushort AD_B_0_005_V = 9;
+        public const ushort AD_B_1_V = 10;
+        public const ushort AD_B_0_1_V = 11;
+        public const ushort AD_B_0_01_V = 12;
+        public const ushort AD_B_0_001_V = 13;
+        public const ushort AD_U_20_V = 14;
+        public const ushort AD_U_10_V = 15;
+        public const ushort AD_U_5_V = 16;
+        public const ushort AD_U_2_5_V = 17;
+        public const ushort AD_U_1_25_V = 18;
+        public const ushort AD_U_1_V = 19;
+        public const ushort AD_U_0_1_V = 20;
+        public const ushort AD_U_0_01_V = 21;
+        public const ushort AD_U_0_001_V = 22;
+
+        //Clock Mode
+        public const ushort TRIG_SOFTWARE = 0;
+        public const ushort TRIG_INT_PACER = 1;
+        public const ushort TRIG_EXT_STROBE = 2;
+        public const ushort TRIG_HANDSHAKE = 3;
+        public const ushort TRIG_CLK_10MHZ = 4;  //PCI-7300A
+        public const ushort TRIG_CLK_20MHZ = 5;  //PCI-7300A
+        public const ushort TRIG_DO_CLK_TIMER_ACK = 6;  //PCI-7300A Rev. B
+        public const ushort TRIG_DO_CLK_10M_ACK = 7;  //PCI-7300A Rev. B
+        public const ushort TRIG_DO_CLK_20M_ACK = 8;  //PCI-7300A Rev. B
+                                                      //Virtual Sampling Rate for using external clock as the clock source
+        public const double CLKSRC_EXT_SampRate = 10000;
+
+        //-------- Constants for PCI-6208A/PCI-6308A/PCI-6308V -------------------
+        //Output Mode
+        public const ushort P6208_CURRENT_0_20MA = 0;
+        public const ushort P6208_CURRENT_4_20MA = 3;
+        public const ushort P6208_CURRENT_5_25MA = 1;
+        public const ushort P6308_CURRENT_0_20MA = 0;
+        public const ushort P6308_CURRENT_4_20MA = 3;
+        public const ushort P6308_CURRENT_5_25MA = 1;
+        //AO Setting
+        public const ushort P6308V_AO_CH0_3 = 0;
+        public const ushort P6308V_AO_CH4_7 = 1;
+        public const ushort P6308V_AO_UNIPOLAR = 0;
+        public const ushort P6308V_AO_BIPOLAR = 1;
+        //-------- Constants for PCI-7200 --------------------
+        //InputMode
+        public const ushort DI_WAITING = 0x02;
+        public const ushort DI_NOWAITING = 0x00;
+
+        public const ushort DI_TRIG_RISING = 0x04;
+        public const ushort DI_TRIG_FALLING = 0x00;
+
+        public const ushort IREQ_RISING = 0x08;
+        public const ushort IREQ_FALLING = 0x00;
+
+        //Output Mode
+        public const ushort OREQ_ENABLE = 0x10;
+        public const ushort OREQ_DISABLE = 0x00;
+
+        public const ushort OTRIG_HIGH = 0x20;
+        public const ushort OTRIG_LOW = 0x00;
+
+        //-------- Constants for PCI-7248/7296/7396/7442 ---------------
+        //DIO Port Direction
+        public const ushort INPUT_PORT = 1;
+        public const ushort OUTPUT_PORT = 2;
+        //DIO Line Direction
+        public const ushort INPUT_LINE = 1;
+        public const ushort OUTPUT_LINE = 2;
+
+        //Channel & Port
+        public const ushort Channel_P1A = 0;
+        public const ushort Channel_P1B = 1;
+        public const ushort Channel_P1C = 2;
+        public const ushort Channel_P1CL = 3;
+        public const ushort Channel_P1CH = 4;
+        public const ushort Channel_P1AE = 10;
+        public const ushort Channel_P1BE = 11;
+        public const ushort Channel_P1CE = 12;
+        public const ushort Channel_P2A = 5;
+        public const ushort Channel_P2B = 6;
+        public const ushort Channel_P2C = 7;
+        public const ushort Channel_P2CL = 8;
+        public const ushort Channel_P2CH = 9;
+        public const ushort Channel_P2AE = 15;
+        public const ushort Channel_P2BE = 16;
+        public const ushort Channel_P2CE = 17;
+        public const ushort Channel_P3A = 10;
+        public const ushort Channel_P3B = 11;
+        public const ushort Channel_P3C = 12;
+        public const ushort Channel_P3CL = 13;
+        public const ushort Channel_P3CH = 14;
+        public const ushort Channel_P4A = 15;
+        public const ushort Channel_P4B = 16;
+        public const ushort Channel_P4C = 17;
+        public const ushort Channel_P4CL = 18;
+        public const ushort Channel_P4CH = 19;
+        public const ushort Channel_P5A = 20;
+        public const ushort Channel_P5B = 21;
+        public const ushort Channel_P5C = 22;
+        public const ushort Channel_P5CL = 23;
+        public const ushort Channel_P5CH = 24;
+        public const ushort Channel_P6A = 25;
+        public const ushort Channel_P6B = 26;
+        public const ushort Channel_P6C = 27;
+        public const ushort Channel_P6CL = 28;
+        public const ushort Channel_P6CH = 29;
+        //the following are used for PCI7396
+        public const ushort Channel_P1 = 30;
+        public const ushort Channel_P2 = 31;
+        public const ushort Channel_P3 = 32;
+        public const ushort Channel_P4 = 33;
+        public const ushort Channel_P1E = 34; //only used by DIO_PortConfig function
+        public const ushort Channel_P2E = 35; //only used by DIO_PortConfig function
+        public const ushort Channel_P3E = 36; //only used by DIO_PortConfig function
+        public const ushort Channel_P4E = 37; //only used by DIO_PortConfig function
+                                              //7442
+        public const ushort P7442_CH0 = 0;
+        public const ushort P7442_CH1 = 1;
+        public const ushort P7442_TTL0 = 2;
+        public const ushort P7442_TTL1 = 3;
+        //-------- Constants for PCI-7300A -------------------
+        //Wait Status
+        public const ushort P7300_WAIT_NO = 0;
+        public const ushort P7300_WAIT_TRG = 1;
+        public const ushort P7300_WAIT_FIFO = 2;
+        public const ushort P7300_WAIT_BOTH = 3;
+
+        //Terminator control
+        public const ushort P7300_TERM_OFF = 0;
+        public const ushort P7300_TERM_ON = 1;
+
+        //DI control signals polarity for PCI-7300A Rev. B
+        public const ushort P7300_DIREQ_POS = 0x00000000;
+        public const ushort P7300_DIREQ_NEG = 0x00000001;
+        public const ushort P7300_DIACK_POS = 0x00000000;
+        public const ushort P7300_DIACK_NEG = 0x00000002;
+        public const ushort P7300_DITRIG_POS = 0x00000000;
+        public const ushort P7300_DITRIG_NEG = 0x00000004;
+
+        //DO control signals polarity for PCI-7300A Rev. B
+        public const ushort P7300_DOREQ_POS = 0x00000000;
+        public const ushort P7300_DOREQ_NEG = 0x00000008;
+        public const ushort P7300_DOACK_POS = 0x00000000;
+        public const ushort P7300_DOACK_NEG = 0x00000010;
+        public const ushort P7300_DOTRIG_POS = 0x00000000;
+        public const ushort P7300_DOTRIG_NEG = 0x00000020;
+        //-------- Constants for PCI-7432/7433/7434 ---------------
+        public const ushort PORT_DI_LOW = 0;
+        public const ushort PORT_DI_HIGH = 1;
+        public const ushort PORT_DO_LOW = 0;
+        public const ushort PORT_DO_HIGH = 1;
+        public const ushort P7432R_DO_LED = 1;
+        public const ushort P7433R_DO_LED = 0;
+        public const ushort P7434R_DO_LED = 2;
+        public const ushort P7432R_DI_SLOT = 1;
+        public const ushort P7433R_DI_SLOT = 2;
+        public const ushort P7434R_DI_SLOT = 0;
+        //-- Dual-Interrupt Source control for PCI-7248/96 & 7432/33 & 7230 & 8554 & 7396 &7256 &7260 ---
+        public const short INT1_DISABLE = -1;    //INT1 Disabled
+        public const short INT1_COS = 0;    //INT1 COS : only available for PCI-7396, PCI-7256, PCI-7260
+        public const short INT1_FP1C0 = 1;    //INT1 by Falling edge of P1C0 : only available for PCI7248/96/7396
+        public const short INT1_RP1C0_FP1C3 = 2;    //INT1 by P1C0 Rising or P1C3 Falling : only available for PCI7248/96/7396
+        public const short INT1_EVENT_COUNTER = 3;    //INT1 by Event Counter down to zero : only available for PCI7248/96/7396
+        public const short INT1_EXT_SIGNAL = 1;    //INT1 by external signal : only available for PCI7432/7433/7230/8554
+        public const short INT1_COUT12 = 1;    //INT1 COUT12 : only available for PCI8554
+        public const short INT1_CH0 = 1;    //INT1 CH0 : only available for PCI7256, PCI7260
+        public const short INT1_COS0 = 1;    //INT1 COS0 : only available for PCI-7452/PCI-7442
+        public const short INT1_COS1 = 2;    //INT1 COS1 : only available for PCI-7452/PCI-7442
+        public const short INT1_COS2 = 4;    //INT1 COS2 : only available for PCI-7452/PCI-7442
+        public const short INT1_COS3 = 8;    //INT1 COS3 : only available for PCI-7452/PCI-7442
+        public const short INT2_DISABLE = -1;    //INT2 Disabled
+        public const short INT2_COS = 0;    //INT2 COS : only available for PCI-7396
+        public const short INT2_FP2C0 = 1;    //INT2 by Falling edge of P2C0 : only available for PCI7248/96/7396
+        public const short INT2_RP2C0_FP2C3 = 2;    //INT2 by P2C0 Rising or P2C3 Falling : only available for PCI7248/96/7396
+        public const short INT2_TIMER_COUNTER = 3;    //INT2 by Timer Counter down to zero : only available for PCI7248/96/7396
+        public const short INT2_EXT_SIGNAL = 1;    //INT2 by external signal : only available for PCI7432/7433/7230/8554
+        public const short INT2_CH1 = 2;      //INT2 CH1 : only available for PCI7256, PCI7260
+        public const short INT2_WDT = 4;      //INT2 by WDT
+
+        public const ushort ManualResetIEvt = 0x4000;//interrupt event is manually reset by user
+        public const ushort WDT_OVRFLOW_SAFETYOUT = 0x8000;// enable safteyout while WDT overflow
+                                                           //-------- Constants for PCI-8554 --------------------
+                                                           //Clock Source of Cunter N
+        public const ushort ECKN = 0;
+        public const ushort COUTN_1 = 1;
+        public const ushort CK1 = 2;
+        public const ushort COUT10 = 3;
+
+        //Clock Source of CK1
+        public const ushort CK1_C8M = 0;
+        public const ushort CK1_COUT11 = 1;
+
+        //Debounce Clock
+        public const ushort DBCLK_COUT11 = 0;
+        public const ushort DBCLK_2MHZ = 1;
+
+        //-------- Constants for PCI-9111 --------------------
+        //Dual Interrupt Mode
+        public const ushort P9111_INT1_EOC = 0;       //Ending of AD conversion
+        public const ushort P9111_INT1_FIFO_HF = 1;       //FIFO Half Full
+        public const ushort P9111_INT2_PACER = 0;       //Every Timer tick
+        public const ushort P9111_INT2_EXT_TRG = 1;       //ExtTrig High->Low
+
+        //Channel Count
+        public const ushort P9111_CHANNEL_DO = 0;
+        public const ushort P9111_CHANNEL_EDO = 1;
+        public const ushort P9111_CHANNEL_DI = 0;
+        public const ushort P9111_CHANNEL_EDI = 1;
+
+        //EDO function
+        public const ushort P9111_EDO_INPUT = 1;   //EDO port set as Input port
+        public const ushort P9111_EDO_OUT_EDO = 2;   //EDO port set as Output port
+        public const ushort P9111_EDO_OUT_CHN = 3;   //EDO port set as channel number ouput port
+
+        //Trigger Mode
+        public const ushort P9111_TRGMOD_SOFT = 0x00;   //Software Trigger Mode
+        public const ushort P9111_TRGMOD_PRE = 0x01;   //Pre-Trigger Mode
+        public const ushort P9111_TRGMOD_POST = 0x02;   //Post Trigger Mode
+
+        //AO Setting
+        public const ushort P9111_AO_UNIPOLAR = 0;
+        public const ushort P9111_AO_BIPOLAR = 1;
+
+        //-------- Constants for PCI-9118 --------------------
+        public const ushort P9118_AI_BiPolar = 0x00;
+        public const ushort P9118_AI_UniPolar = 0x01;
+
+        public const ushort P9118_AI_SingEnded = 0x00;
+        public const ushort P9118_AI_Differential = 0x02;
+
+        public const ushort P9118_AI_ExtG = 0x04;
+
+        public const ushort P9118_AI_ExtTrig = 0x08;
+
+        public const ushort P9118_AI_DtrgNegative = 0x00;
+        public const ushort P9118_AI_DtrgPositive = 0x10;
+
+        public const ushort P9118_AI_EtrgNegative = 0x00;
+        public const ushort P9118_AI_EtrgPositive = 0x20;
+
+        public const ushort P9118_AI_BurstModeEn = 0x40;
+        public const ushort P9118_AI_SampleHold = 0x80;
+        public const ushort P9118_AI_PostTrgEn = 0x100;
+        public const ushort P9118_AI_AboutTrgEn = 0x200;
+
+        //-------- Constants for PCI-9116 --------------------
+        public const ushort P9116_AI_LocalGND = 0x00;
+        public const ushort P9116_AI_UserCMMD = 0x01;
+        public const ushort P9116_AI_SingEnded = 0x00;
+        public const ushort P9116_AI_Differential = 0x02;
+        public const ushort P9116_AI_BiPolar = 0x00;
+        public const ushort P9116_AI_UniPolar = 0x04;
+
+        public const ushort P9116_TRGMOD_SOFT = 0x00;   //Software Trigger Mode
+        public const ushort P9116_TRGMOD_POST = 0x10;   //Post Trigger Mode
+        public const ushort P9116_TRGMOD_DELAY = 0x20;   //Delay Trigger Mode
+        public const ushort P9116_TRGMOD_PRE = 0x30;   //Pre-Trigger Mode
+        public const ushort P9116_TRGMOD_MIDL = 0x40;   //Middle Trigger Mode
+        public const ushort P9116_AI_TrgPositive = 0x00;
+        public const ushort P9116_AI_TrgNegative = 0x80;
+        public const ushort P9116_AI_ExtTimeBase = 0x100;
+        public const ushort P9116_AI_IntTimeBase = 0x000;
+        public const ushort P9116_AI_DlyInSamples = 0x200;
+        public const ushort P9116_AI_DlyInTimebase = 0x000;
+        public const ushort P9116_AI_ReTrigEn = 0x400;
+        public const ushort P9116_AI_MCounterEn = 0x800;
+        public const ushort P9116_AI_SoftPolling = 0x0000;
+        public const ushort P9116_AI_INT = 0x1000;
+        public const ushort P9116_AI_DMA = 0x2000;
+
+        //-------- Constants for PCI-9812 --------------------
+        //Trigger Mode
+        public const ushort P9812_TRGMOD_SOFT = 0x00;   //Software Trigger Mode
+        public const ushort P9812_TRGMOD_POST = 0x01;   //Post Trigger Mode
+        public const ushort P9812_TRGMOD_PRE = 0x02;   //Pre-Trigger Mode
+        public const ushort P9812_TRGMOD_DELAY = 0x03;   //Delay Trigger Mode
+        public const ushort P9812_TRGMOD_MIDL = 0x04;   //Middle Trigger Mode
+
+        public const ushort P9812_AIEvent_Manual = 0x08;   //Middle Trigger Mode
+
+        //Trigger Source
+        public const ushort P9812_TRGSRC_CH0 = 0x00;   //trigger source --CH0
+        public const ushort P9812_TRGSRC_CH1 = 0x08;   //trigger source --CH1
+        public const ushort P9812_TRGSRC_CH2 = 0x10;   //trigger source --CH2
+        public const ushort P9812_TRGSRC_CH3 = 0x18;   //trigger source --CH3
+        public const ushort P9812_TRGSRC_EXT_DIG = 0x20;   //External Digital Trigger
+
+        //Trigger Polarity
+        public const ushort P9812_TRGSLP_POS = 0x00;   //Positive slope trigger
+        public const ushort P9812_TRGSLP_NEG = 0x40;   //Negative slope trigger
+
+        //Frequency Selection
+        public const ushort P9812_AD2_GT_PCI = 0x80;   //Freq. of A/D clock > PCI clock freq.
+        public const ushort P9812_AD2_LT_PCI = 0x00;   //Freq. of A/D clock < PCI clock freq.
+
+        //Clock Source
+        public const ushort P9812_CLKSRC_INT = 0x000;   //Internal clock
+        public const ushort P9812_CLKSRC_EXT_SIN = 0x100;  //External SIN wave clock
+        public const ushort P9812_CLKSRC_EXT_DIG = 0x200;  //External Square wave clock
+
+        //EMG shdn ctrl code
+        public const ushort EMGSHDN_OFF = 0;     //off
+        public const ushort EMGSHDN_ON = 1; //on
+        public const ushort EMGSHDN_RECOVERY = 2; //recovery
+
+        //Hot Reset Hold ctrl code
+        public const ushort HRH_OFF = 0; //off
+        public const ushort HRH_ON = 1; //on
+
+        //-------- Timer/Counter -----------------------------
+        //Counter Mode (8254)
+        public const ushort TOGGLE_OUTPUT = 0;     //Toggle output from low to high on terminal count
+        public const ushort PROG_ONE_SHOT = 1;     //Programmable one-shot
+        public const ushort RATE_GENERATOR = 2;     //Rate generator
+        public const ushort SQ_WAVE_RATE_GENERATOR = 3;     //Square wave rate generator
+        public const ushort SOFT_TRIG = 4;     //Software-triggered strobe
+        public const ushort HARD_TRIG = 5;     //Hardware-triggered strobe
+
+        //General Purpose Timer/Counter
+        //Counter Mode
+        public const ushort General_Counter = 0x00; //general counter
+        public const ushort Pulse_Generation = 0x01; //pulse generation
+                                                     //GPTC clock source
+        public const ushort GPTC_CLKSRC_EXT = 0x08;
+        public const ushort GPTC_CLKSRC_INT = 0x00;
+        public const ushort GPTC_GATESRC_EXT = 0x10;
+        public const ushort GPTC_GATESRC_INT = 0x00;
+        public const ushort GPTC_UPDOWN_SELECT_EXT = 0x20;
+        public const ushort GPTC_UPDOWN_SELECT_SOFT = 0x00;
+        public const ushort GPTC_UP_CTR = 0x40;
+        public const ushort GPTC_DOWN_CTR = 0x00;
+        public const ushort GPTC_ENABLE = 0x80;
+        public const ushort GPTC_DISABLE = 0x00;
+
+        //Watchdog Timer
+        //Counter action
+        public const ushort WDT_DISARM = 0;
+        public const ushort WDT_ARM = 1;
+        public const ushort WDT_RESTART = 2;
+
+        //Pattern ID
+        public const ushort INIT_PTN = 0;
+        public const ushort EMGSHDN_PTN = 1;
+
+        //16-bit binary or 4-decade BCD counter
+        public const ushort BIN = 0;
+        public const ushort BCD = 1;
+
+        //Pattern ID for 7442
+        public const ushort INIT_PTN_CH0 = 0;
+        public const ushort INIT_PTN_CH1 = 1;
+        public const ushort SAFTOUT_PTN_CH0 = 4;
+        public const ushort SAFTOUT_PTN_CH1 = 5;
+
+        //DAQ Event type for the event message  
+        public const ushort AIEnd = 0;
+        public const ushort DIEnd = 0;
+        public const ushort DOEnd = 0;
+        public const ushort DBEvent = 1;
+
+        public const ushort RegBySlot = 0x8000;
+
+        /*------------------------------------------------------------------
+        ** PCIS-DASK Function prototype
+        ------------------------------------------------------------------*/
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short Register_Card(ushort CardType, ushort card_num);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short Release_Card(ushort CardNumber);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short GetActualRate(ushort CardNumber, double fSampleRate, out double fActualRate);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short EMGShutDownControl(ushort CardNumber, byte ctrl);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short EMGShutDownStatus(ushort CardNumber, out byte sts);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short HotResetHoldControl(ushort wCardNumber, byte enable);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short HotResetHoldStatus(ushort wCardNumber, out byte sts);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short GetInitPattern(ushort CardNumber, byte patID, out uint pattern);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short SetInitPattern(ushort wCardNumber, byte patID, uint pattern);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short IdentifyLED_Control(ushort CardNumber, byte ctrl);
+        /*---------------------------------------------------------------------------*/
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_9111_Config(ushort CardNumber, ushort TrigSource, ushort TrgMode, ushort TraceCnt);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_9112_Config(ushort CardNumber, ushort TrigSource);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_9113_Config(ushort CardNumber, ushort TrigSource);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_9114_Config(ushort CardNumber, ushort TrigSource);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_9116_Config(ushort CardNumber, ushort ConfigCtrl, ushort TrigCtrl, ushort PostCnt, ushort MCnt, ushort ReTrgCnt);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_9118_Config(ushort CardNumber, ushort ModeCtrl, ushort FunCtrl, ushort BurstCnt, ushort PostCnt);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_9812_Config(ushort CardNumber, ushort TrgMode, ushort TrgSrc, ushort TrgPol, ushort ClkSel, ushort TrgLevel, ushort PostCnt);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_9812_SetDiv(ushort wCardNumber, uint PacerVal);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_9114_PreTrigConfig(ushort CardNumber, ushort PreTrgEn, ushort TraceCnt);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_9116_CounterInterval(ushort wCardNumber, uint ScanIntrv, uint SampIntrv);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_InitialMemoryAllocated(ushort CardNumber, out uint MemSize);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_ReadChannel(ushort CardNumber, ushort Channel, ushort AdRange, out ushort Value);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_VReadChannel(ushort CardNumber, ushort Channel, ushort AdRange, out double voltage);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_VoltScale(ushort CardNumber, ushort AdRange, ushort reading, out double voltage);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_ContReadChannel(ushort CardNumber, ushort Channel, ushort AdRange,
+                   ushort[] Buffer, uint ReadCount, double SampleRate, ushort SyncMode);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_ContReadMultiChannels(ushort CardNumber, ushort NumChans, ushort[] Chans,
+                   ushort[] AdRanges, ushort[] Buffer, uint ReadCount,
+                   double SampleRate, ushort SyncMode);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_ContScanChannels(ushort CardNumber, ushort Channel, ushort AdRange,
+                   ushort[] Buffer, uint ReadCount, double SampleRate, ushort SyncMode);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_ContReadChannelToFile(ushort CardNumber, ushort Channel, ushort AdRange,
+                   string FileName, uint ReadCount, double SampleRate, ushort SyncMode);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_ContReadMultiChannelsToFile(ushort CardNumber, ushort NumChans, ushort[] Chans,
+                   ushort[] AdRanges, string[] FileName, uint ReadCount,
+                   double SampleRate, ushort SyncMode);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_ContScanChannelsToFile(ushort CardNumber, ushort Channel, ushort AdRange,
+                   string FileName, uint ReadCount, double SampleRate, ushort SyncMode);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_ContStatus(ushort CardNumber, out ushort Status);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_ContVScale(ushort wCardNumber, ushort adRange, ushort[] readingArray, double[] voltageArray, int count);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_AsyncCheck(ushort CardNumber, out byte Stopped, out uint AccessCnt);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_AsyncClear(ushort CardNumber, out uint AccessCnt);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_AsyncDblBufferHalfReady(ushort CardNumber, out byte HalfReady, out byte StopFlag);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_AsyncDblBufferMode(ushort CardNumber, bool Enable);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_AsyncDblBufferTransfer(ushort CardNumber, ushort[] Buffer);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_AsyncDblBufferOverrun(ushort CardNumber, ushort op, out ushort overrunFlag);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_EventCallBack(ushort CardNumber, ushort mode, ushort EventType, MulticastDelegate callbackAddr);
+        /*---------------------------------------------------------------------------*/
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AO_6208A_Config(ushort CardNumber, ushort V2AMode);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AO_6308A_Config(ushort CardNumber, ushort V2AMode);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AO_6308V_Config(ushort wCardNumber, ushort Channel, ushort wOutputPolarity, double refVoltage);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AO_9111_Config(ushort CardNumber, ushort OutputPolarity);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AO_9112_Config(ushort CardNumber, ushort Channel, double refVoltage);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AO_WriteChannel(ushort CardNumber, ushort Channel, short Value);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AO_VWriteChannel(ushort CardNumber, ushort Channel, double Voltage);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AO_VoltScale(ushort CardNumber, ushort Channel, double Voltage, out short binValue);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AO_SimuWriteChannel(ushort wCardNumber, ushort wGroup, short[] pwBuffer);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AO_SimuVWriteChannel(ushort wCardNumber, ushort wGroup, double[] VBuffer);
+        /*---------------------------------------------------------------------------*/
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_7200_Config(ushort CardNumber, ushort TrigSource, ushort ExtTrigEn, ushort TrigPol, ushort I_REQ_Pol);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_7300A_Config(ushort CardNumber, ushort PortWidth, ushort TrigSource, ushort WaitStatus, ushort Terminator, ushort I_REQ_Pol, bool clear_fifo, bool disable_di);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_7300B_Config(ushort CardNumber, ushort PortWidth, ushort TrigSource, ushort WaitStatus, ushort Terminator, ushort I_Cntrl_Pol, bool clear_fifo, bool disable_di);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_InitialMemoryAllocated(ushort CardNumber, out uint DmaSize);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_ReadLine(ushort CardNumber, ushort Port, ushort Line, out ushort State);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_ReadPort(ushort CardNumber, ushort Port, out uint Value);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_ContReadPort(ushort CardNumber, ushort Port, byte[] Buffer,
+                   uint ReadCount, double SampleRate, ushort SyncMode);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_ContReadPort(ushort CardNumber, ushort Port, ushort[] Buffer,
+                   uint ReadCount, double SampleRate, ushort SyncMode);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_ContReadPort(ushort CardNumber, ushort Port, uint[] Buffer,
+                   uint ReadCount, double SampleRate, ushort SyncMode);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_ContReadPortToFile(ushort CardNumber, ushort Port, string FileName,
+                                      uint ReadCount, double SampleRate, ushort SyncMode);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_ContStatus(ushort CardNumber, out ushort Status);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_AsyncCheck(ushort CardNumber, out byte Stopped, out uint AccessCnt);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_AsyncClear(ushort CardNumber, out uint AccessCnt);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_AsyncDblBufferHalfReady(ushort CardNumber, out byte HalfReady);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_AsyncDblBufferMode(ushort CardNumber, bool Enable);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_AsyncDblBufferTransfer(ushort CardNumber, byte[] Buffer);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_AsyncDblBufferTransfer(ushort CardNumber, short[] Buffer);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_AsyncDblBufferTransfer(ushort CardNumber, uint[] Buffer);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_ContMultiBufferSetup(ushort wCardNumber, byte[] pwBuffer, uint dwReadCount, out ushort BufferId);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_ContMultiBufferSetup(ushort wCardNumber, short[] pwBuffer, uint dwReadCount, out ushort BufferId);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_ContMultiBufferSetup(ushort wCardNumber, uint[] pwBuffer, uint dwReadCount, out ushort BufferId);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_ContMultiBufferStart(ushort wCardNumber, ushort wPort, double fSampleRate);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_AsyncMultiBufferNextReady(ushort CardNumber, out byte bNextReady, out ushort wBufferId);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_AsyncDblBufferOverrun(ushort CardNumber, ushort op, out ushort overrunFlag);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_EventCallBack(ushort CardNumber, short mode, short EventType, MulticastDelegate callbackAddr);
+        /*---------------------------------------------------------------------------*/
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_7200_Config(ushort CardNumber, ushort TrigSource, ushort OutReqEn, ushort OutTrigSig);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_7300A_Config(ushort CardNumber, ushort PortWidth, ushort TrigSource, ushort WaitStatus, ushort Terminator, ushort O_REQ_Pol);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_7300B_Config(ushort CardNumber, ushort PortWidth, ushort TrigSource, ushort WaitStatus, ushort Terminator, ushort O_Cntrl_Pol, uint FifoThreshold);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_InitialMemoryAllocated(ushort CardNumber, out uint MemSize);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_WriteLine(ushort CardNumber, ushort Port, ushort Line, ushort Value);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_WritePort(ushort CardNumber, byte Port, uint Value);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_WritePort(ushort CardNumber, ushort Port, uint Value);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_WritePort(ushort CardNumber, uint Port, uint Value);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_WriteExtTrigLine(ushort CardNumber, ushort Value);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_ReadLine(ushort CardNumber, ushort Port, ushort Line, out ushort Value);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_ReadPort(ushort CardNumber, ushort Port, out uint Value);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_ContWritePort(ushort CardNumber, ushort Port, byte[] Buffer,
+                   uint WriteCount, ushort Iterations, double SampleRate, ushort SyncMode);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_ContWritePort(ushort CardNumber, ushort Port, ushort[] Buffer,
+                   uint WriteCount, ushort Iterations, double SampleRate, ushort SyncMode);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_ContWritePort(ushort CardNumber, ushort Port, uint[] Buffer,
+                   uint WriteCount, ushort Iterations, double SampleRate, ushort SyncMode);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_PGStart(ushort CardNumber, byte[] Buffer, uint WriteCount, double SampleRate);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_PGStart(ushort CardNumber, short[] Buffer, uint WriteCount, double SampleRate);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_PGStart(ushort CardNumber, uint[] Buffer, uint WriteCount, double SampleRate);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_PGStop(ushort CardNumber);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_ContStatus(ushort CardNumber, out ushort Status);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_AsyncCheck(ushort CardNumber, out byte Stopped, out uint AccessCnt);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_AsyncClear(ushort CardNumber, out uint AccessCnt);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short EDO_9111_Config(ushort CardNumber, ushort EDO_Fun);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_ContMultiBufferSetup(ushort CardNumber, byte[] pwBuffer, uint dwWriteCount, out ushort BufferId);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_ContMultiBufferSetup(ushort CardNumber, short[] pwBuffer, uint dwWriteCount, out ushort BufferId);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_ContMultiBufferSetup(ushort CardNumber, uint[] pwBuffer, uint dwWriteCount, out ushort BufferId);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_AsyncMultiBufferNextReady(ushort CardNumber, out byte bNextReady, out ushort wBufferId);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_ContMultiBufferStart(ushort wCardNumber, ushort wPort, double fSampleRate);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_EventCallBack(ushort CardNumber, short mode, short EventType, MulticastDelegate callbackAddr);
+        /*---------------------------------------------------------------------------*/
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DIO_PortConfig(ushort CardNumber, ushort Port, ushort Direction);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DIO_LinesConfig(ushort wCardNumber, ushort wPort, ushort wLinesdirmap);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DIO_LineConfig(ushort wCardNumber, ushort wPort, ushort wLine, ushort wDirection);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DIO_SetDualInterrupt(ushort CardNumber, short Int1Mode, short Int2Mode, long hEvent);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DIO_SetCOSInterrupt(ushort CardNumber, ushort Port, ushort ctlA, ushort ctlB, ushort ctlC);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DIO_INT1_EventMessage(ushort CardNumber, short Int1Mode, long windowHandle, long message, MulticastDelegate callbackAddr);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DIO_INT2_EventMessage(ushort CardNumber, short Int2Mode, long windowHandle, long message, MulticastDelegate callbackAddr);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DIO_7300SetInterrupt(ushort CardNumber, short AuxDIEn, short T2En, long hEvent);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DIO_AUXDI_EventMessage(ushort CardNumber, short AuxDIEn, long windowHandle, uint message, MulticastDelegate callbackAddr);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DIO_T2_EventMessage(ushort CardNumber, short T2En, long windowHandle, uint message, MulticastDelegate callbackAddr);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DIO_GetCOSLatchData(ushort wCardNumber, out ushort CosLData);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DIO_SetCOSInterrupt32(ushort wCardNumber, byte Port, uint ctl, out long hEvent, bool bManualReset);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DIO_GetCOSLatchDataInt32(ushort wCardNumber, byte Port, out uint CosLData);
+        /*---------------------------------------------------------------------------*/
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short CTR_Setup(ushort CardNumber, ushort Ctr, ushort Mode, uint Count, ushort BinBcd);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short CTR_Clear(ushort CardNumber, ushort Ctr, ushort State);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short CTR_Read(ushort CardNumber, ushort Ctr, out uint Value);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short CTR_Update(ushort CardNumber, ushort Ctr, uint Count);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short CTR_8554_ClkSrc_Config(ushort CardNumber, ushort Ctr, ushort ClockSource);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short CTR_8554_CK1_Config(ushort CardNumber, ushort ClockSource);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short CTR_8554_Debounce_Config(ushort CardNumber, ushort DebounceClock);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short GCTR_Setup(ushort wCardNumber, ushort wGCtr, ushort wGCtrCtrl, uint dwCount);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short GCTR_Clear(ushort wCardNumber, ushort wGCtr);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short GCTR_Read(ushort wCardNumber, ushort wGCtr, out uint pValue);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short WDT_Setup(ushort CardNumber, ushort wCtr, float ovflowSec, out float actualSec, out long hEvent);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short WDT_Control(ushort wCardNumber, ushort wCtr, ushort action);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short WDT_Status(ushort wCardNumber, ushort Ctr, out uint pValue);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short WDT_Reload(ushort wCardNumber, float ovflowSec, out float actualSec);
+        /*---------------------------------------------------------------------------*/
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_GetEvent(ushort wCardNumber, out long hEvent);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AO_GetEvent(ushort wCardNumber, out long hEvent);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_GetEvent(ushort wCardNumber, out long hEvent);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_GetEvent(ushort wCardNumber, out long hEvent);
+        /*---------------------------------------------------------------------------*/
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short AI_GetView(ushort wCardNumber, uint[] pView);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DI_GetView(ushort wCardNumber, uint[] pView);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short DO_GetView(ushort wCardNumber, uint[] pView);
+        /*---------------------------------------------------------------------------*/
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short GetCardType(ushort wCardNumber, out ushort cardType);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short GetCardIndexFromID(ushort wCardNumber, out ushort cardType, out ushort cardIndex);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short GetBaseAddr(ushort wCardNumber, uint[] BaseAddr, uint[] BaseAddr2);
+        [DllImport("PCI-Dask64.dll")]
+        public static extern short GetLCRAddr(ushort wCardNumber, uint[] LcrAddr);
+    }
+}
\ No newline at end of file
diff --git a/SimpleUtil/DIOController/DaskHelper.cs b/SimpleUtil/DIOController/DaskHelper.cs
new file mode 100644
index 0000000..3c12c2f
--- /dev/null
+++ b/SimpleUtil/DIOController/DaskHelper.cs
@@ -0,0 +1,132 @@
+锘縩amespace DIOController
+{
+   public class DaskHelper
+    {
+        public static ushort CardType(string name)
+        {
+            ushort cardtype = 0;
+            switch (name)
+            {
+                case "PCI_6208V":
+                    cardtype = 1;
+                    break;
+                case "PCI_6208A":
+                    cardtype = 2;
+                    break;
+                case "PCI_6308V":
+                    cardtype = 3;
+                    break;
+                case "PCI_6308A":
+                    cardtype = 4;
+                    break;
+                case "PCI_7200":
+                    cardtype = 5;
+                    break;
+                case "PCI_7230":
+                    cardtype = 6;
+                    break;
+                case "PCI_7233":
+                    cardtype = 7;
+                    break;
+                case "PCI_7234":
+                    cardtype = 8;
+                    break;
+                case "PCI_7248":
+                    cardtype = 9;
+                    break;
+                case "PCI_7249":
+                    cardtype = 10;
+                    break;
+                case "PCI_7250":
+                    cardtype = 11;
+                    break;
+                case "PCI_7252":
+                    cardtype = 12;
+                    break;
+                case "PCI_7296":
+                    cardtype = 13;
+                    break;
+                case "PCI_7300A_RevA":
+                    cardtype = 14;
+                    break;
+                case "PCI_7300A_RevB":
+                    cardtype = 15;
+                    break;
+                case "PCI_7432":
+                    cardtype = 16;
+                    break;
+                case "PCI_7433":
+                    cardtype = 17;
+                    break;
+                case "PCI_7434":
+                    cardtype = 18;
+                    break;
+                case "PCI_8554":
+                    cardtype = 19;
+                    break;
+                case "PCI_9111DG":
+                    cardtype = 20;
+                    break;
+                case "PCI_9111HR":
+                    cardtype = 21;
+                    break;
+                case "PCI_9112":
+                    cardtype = 22;
+                    break;
+                case "PCI_9113":
+                    cardtype = 23;
+                    break;
+                case "PCI_9114DG":
+                    cardtype = 24;
+                    break;
+                case "PCI_9114HG":
+                    cardtype = 25;
+                    break;
+                case "PCI_9118DG":
+                    cardtype = 26;
+                    break;
+                case "PCI_9118HG":
+                    cardtype = 27;
+                    break;
+                case "PCI_9118HR":
+                    cardtype = 28;
+                    break;
+                case "PCI_9810":
+                    cardtype = 29;
+                    break;
+                case "PCI_9812":
+                    cardtype = 30;
+                    break;
+                case "PCI_7396":
+                    cardtype = 31;
+                    break;
+                case "PCI_9116":
+                    cardtype = 32;
+                    break;
+                case "PCI_7256":
+                    cardtype = 33;
+                    break;
+                case "PCI_7258":
+                    cardtype = 34;
+                    break;
+                case "PCI_7260":
+                    cardtype = 35;
+                    break;
+                case "PCI_7452":
+                    cardtype = 36;
+                    break;
+                case "PCI_7442":
+                    cardtype = 37;
+                    break;
+                case "MAX_CARD":
+                    cardtype = 32;
+                    break;
+                default:
+                    cardtype = 16;
+                    break;
+            }
+
+            return cardtype;
+        }
+    }
+}
diff --git a/SimpleUtil/DIOController/IDIOController.cs b/SimpleUtil/DIOController/IDIOController.cs
new file mode 100644
index 0000000..7246d1f
--- /dev/null
+++ b/SimpleUtil/DIOController/IDIOController.cs
@@ -0,0 +1,20 @@
+锘縰sing System;
+
+namespace DIOController
+{
+    public interface IDIOController : IDisposable
+    {
+        bool Start(out string msg);
+
+        bool ReadDIBool(string address, out bool res, out string msg);
+        bool ReadDIBool(string address, int length, out bool[] res, out string msg);
+
+        bool ReadDOBool(string address, out bool res, out string msg);
+        bool ReadDOBool(string address, int length, out bool[] res, out string msg);
+
+        bool WriteBool(string address, bool value, out string msg);
+        bool WriteBool(string address, bool[] value, out string msg);
+
+        bool Close();
+    }
+}
diff --git a/SimpleUtil/DIOController/IniFileHelper.cs b/SimpleUtil/DIOController/IniFileHelper.cs
new file mode 100644
index 0000000..0c7fc99
--- /dev/null
+++ b/SimpleUtil/DIOController/IniFileHelper.cs
@@ -0,0 +1,94 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace DIOController
+{
+    public class IniFileHelper
+    {
+        static List<string> sections = new List<string>();
+        static List<string> keys = new List<string>();
+        #region API鍑芥暟澹版槑
+
+        [DllImport("kernel32")]
+        private static extern long WritePrivateProfileString(string section, string key,
+            string val, string filePath);
+
+        //闇�瑕佽皟鐢℅etPrivateProfileString鐨勯噸杞�
+        [DllImport("kernel32", EntryPoint = "GetPrivateProfileString")]
+        private static extern long GetPrivateProfileString(string section, string key,
+            string def, StringBuilder retVal, int size, string filePath);
+
+        [DllImport("kernel32", EntryPoint = "GetPrivateProfileString")]
+        private static extern uint GetPrivateProfileStringA(string section, string key,
+            string def, Byte[] retVal, int size, string filePath);
+
+        #endregion
+
+        public static List<string> ReadSections(string iniFilename)
+        {
+            List<string> result = new List<string>();
+            Byte[] buf = new Byte[65536];
+            uint len = GetPrivateProfileStringA(null, null, null, buf, buf.Length, iniFilename);
+            int j = 0;
+            for (int i = 0; i < len; i++)
+                if (buf[i] == 0)
+                {
+                    result.Add(Encoding.Default.GetString(buf, j, i - j));
+                    j = i + 1;
+                }
+            return result;
+        }
+
+        public static List<string> ReadKeys(string SectionName, string iniFilename)
+        {
+            List<string> result = new List<string>();
+            Byte[] buf = new Byte[65536];
+            uint len = GetPrivateProfileStringA(SectionName, null, null, buf, buf.Length, iniFilename);
+            int j = 0;
+            for (int i = 0; i < len; i++)
+                if (buf[i] == 0)
+                {
+                    result.Add(Encoding.Default.GetString(buf, j, i - j));
+                    j = i + 1;
+                }
+            return result;
+        }
+
+        #region 璇籌ni鏂囦欢
+
+        public static string ReadIniData(string Section, string Key, string NoText, string iniFilePath)
+        {
+            if (File.Exists(iniFilePath))
+            {
+                StringBuilder temp = new StringBuilder(1024);
+                GetPrivateProfileString(Section, Key, NoText, temp, 1024, iniFilePath);
+                return temp.ToString();
+            }
+            else
+                return String.Empty;
+        }
+
+        #endregion
+
+        #region 鍐橧ni鏂囦欢
+
+
+        public static bool WriteIniData(string Section, string Key, string Value, string iniFilePath)
+        {
+            if (File.Exists(iniFilePath) == false)
+
+            {
+                FileStream FS = new FileStream(iniFilePath, FileMode.CreateNew);
+            }
+            long OpStation = WritePrivateProfileString(Section, Key, Value, iniFilePath);
+            if (OpStation == 0)
+                return false;
+            else
+                return true;
+        }
+        #endregion
+    }
+}
diff --git a/SimpleUtil/DIOController/ModBusTcpController.cs b/SimpleUtil/DIOController/ModBusTcpController.cs
new file mode 100644
index 0000000..fda4b29
--- /dev/null
+++ b/SimpleUtil/DIOController/ModBusTcpController.cs
@@ -0,0 +1,79 @@
+锘縰sing HslCommunication.ModBus;
+
+namespace DIOController
+{
+    public class ModBusTcpController : IDIOController
+    {
+        public string Ip { get; set; }
+        public int Port { get; set; }
+
+        private ModbusTcpNet client;
+
+        public bool Start(out string errMsg)
+        {
+            errMsg = string.Empty;
+            client = new ModbusTcpNet(Ip, Port);
+            var res = client.ConnectServer();
+            errMsg = res.Message;
+            return res.IsSuccess;
+        }
+
+        public bool ReadDIBool(string address, out bool res, out string msg)
+        {
+            var result = client?.ReadBool($"x=2;{address}");
+            msg = result?.Message;
+            res = result?.Content == true;
+            return result?.IsSuccess == true;
+        }
+
+        public bool ReadDIBool(string address, int length, out bool[] res, out string msg)
+        {
+            var result = client?.ReadBool($"x=2;{address}", (ushort)length);
+            msg = result?.Message;
+            res = result?.Content;
+            return result?.IsSuccess == true;
+        }
+
+        public bool ReadDOBool(string address, out bool res, out string msg)
+        {
+            var result = client?.ReadBool(address);
+            msg = result?.Message;
+            res = result?.Content == true;
+            return result?.IsSuccess == true;
+        }
+
+        public bool ReadDOBool(string address, int length, out bool[] res, out string msg)
+        {
+            var result = client?.ReadBool(address, (ushort)length);
+            msg = result?.Message;
+            res = result?.Content;
+            return result?.IsSuccess == true;
+        }
+
+        public bool WriteBool(string address, bool value, out string msg)
+        {
+            msg = string.Empty;
+            var res = client?.Write(address, value);
+            msg = res.Message;
+            return res?.IsSuccess == true;
+        }
+
+        public bool WriteBool(string address, bool[] values, out string msg)
+        {
+            msg = string.Empty;
+            var res = client?.Write(address, values);
+            msg = res.Message;
+            return res?.IsSuccess == true;
+        }
+
+        public bool Close()
+        {
+            return client?.ConnectClose()?.IsSuccess == true;
+
+        }
+        public void Dispose()
+        {
+            client?.Dispose();
+        }
+    }
+}
diff --git a/SimpleUtil/DIOController/PCI-Dask64.dll b/SimpleUtil/DIOController/PCI-Dask64.dll
new file mode 100644
index 0000000..232452a
--- /dev/null
+++ b/SimpleUtil/DIOController/PCI-Dask64.dll
Binary files differ
diff --git a/SimpleUtil/DIOController/PCIController.cs b/SimpleUtil/DIOController/PCIController.cs
new file mode 100644
index 0000000..9a9a042
--- /dev/null
+++ b/SimpleUtil/DIOController/PCIController.cs
@@ -0,0 +1,66 @@
+锘縰sing System;
+
+namespace DIOController
+{
+    public class PCIController : IDIOController
+    {
+        public string Name { get; set; }
+
+        private short id;
+
+        public bool Start(out string msg)
+        {
+            msg = string.Empty;
+            id = DASK.Register_Card(DaskHelper.CardType(Name), 0);
+            return id >= 0;
+        }
+
+        public bool ReadDIBool(string address, out bool res, out string msg)
+        {
+            msg = string.Empty;
+            DASK.DI_ReadLine((ushort)id, 0, ushort.Parse(address), out ushort value);
+            res = Convert.ToBoolean(value);
+            return true;
+        }
+
+        public bool ReadDOBool(string address, out bool res, out string msg)
+        {
+            msg = string.Empty;
+            DASK.DO_ReadLine((ushort)id, 0, ushort.Parse(address), out ushort value);
+            res = Convert.ToBoolean(value);
+            return true;
+        }
+
+        public bool WriteBool(string address, bool value, out string msg)
+        {
+            msg = string.Empty;
+            var res = DASK.DO_WriteLine((ushort)id, 0, ushort.Parse(address), Convert.ToUInt16(value));
+            return res == 0;
+        }
+
+        public bool Close()
+        {
+            return DASK.Release_Card((ushort)id) == 0;
+        }
+
+        public void Dispose()
+        {
+            this.Close();
+        }
+
+        public bool ReadDIBool(string address, int length, out bool[] res, out string msg)
+        {
+            throw new NotImplementedException();
+        }
+
+        public bool ReadDOBool(string address, int length, out bool[] res, out string msg)
+        {
+            throw new NotImplementedException();
+        }
+
+        public bool WriteBool(string address, bool[] value, out string msg)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}
diff --git a/SimpleUtil/DIOController/Properties/AssemblyInfo.cs b/SimpleUtil/DIOController/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..cd80fbc
--- /dev/null
+++ b/SimpleUtil/DIOController/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+锘縰sing System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 鏈夊叧绋嬪簭闆嗙殑涓�鑸俊鎭敱浠ヤ笅
+// 鎺у埗銆傛洿鏀硅繖浜涚壒鎬у�煎彲淇敼
+// 涓庣▼搴忛泦鍏宠仈鐨勪俊鎭��
+[assembly: AssemblyTitle("DIOController")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("DIOController")]
+[assembly: AssemblyCopyright("Copyright 漏  2025")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 灏� ComVisible 璁剧疆涓� false 浼氫娇姝ょ▼搴忛泦涓殑绫诲瀷
+//瀵� COM 缁勪欢涓嶅彲瑙併�傚鏋滈渶瑕佷粠 COM 璁块棶姝ょ▼搴忛泦涓殑绫诲瀷
+//璇峰皢姝ょ被鍨嬬殑 ComVisible 鐗规�ц缃负 true銆�
+[assembly: ComVisible(false)]
+
+// 濡傛灉姝ら」鐩悜 COM 鍏紑锛屽垯涓嬪垪 GUID 鐢ㄤ簬绫诲瀷搴撶殑 ID
+[assembly: Guid("34ffbafe-478f-4b6e-95e7-92a949011a9b")]
+
+// 绋嬪簭闆嗙殑鐗堟湰淇℃伅鐢变笅鍒楀洓涓�肩粍鎴�: 
+//
+//      涓荤増鏈�
+//      娆$増鏈�
+//      鐢熸垚鍙�
+//      淇鍙�
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/SimpleUtil/DIOController/template.ini b/SimpleUtil/DIOController/template.ini
new file mode 100644
index 0000000..d03b1cd
--- /dev/null
+++ b/SimpleUtil/DIOController/template.ini
@@ -0,0 +1,9 @@
+锘�
+[Config]
+;鍙�夐」 ModbusTcp锛孭CI_7432
+Type=ModbusTcp
+;Modbus鍙傛暟
+Ip=127.0.0.1
+Port=502
+;7432鍙傛暟
+Name=PCI_7432
\ No newline at end of file
diff --git a/SimpleUtil/HMI.Simple.Util/AlarmUtil.cs b/SimpleUtil/HMI.Simple.Util/AlarmUtil.cs
new file mode 100644
index 0000000..1a752ee
--- /dev/null
+++ b/SimpleUtil/HMI.Simple.Util/AlarmUtil.cs
@@ -0,0 +1,25 @@
+锘縰sing System;
+
+namespace HMI.Simple.Util
+{
+    public class AlarmUtil
+    {
+        public static bool CreateAlarm(string alarmContent, out string msg)
+        {
+            msg = string.Empty;
+            try
+            {
+                using (var helper = new MSMQHelper("HMI_Alarm"))
+                {
+                    helper.Send("Alarm", alarmContent);
+                    return true;
+                }
+            }
+            catch (Exception ex)
+            {
+                msg = ex.Message;
+                return false;
+            }
+        }
+    }
+}
diff --git a/SimpleUtil/HMI.Simple.Util/HMI.Simple.Util.csproj b/SimpleUtil/HMI.Simple.Util/HMI.Simple.Util.csproj
index eea004c..04d1ba5 100644
--- a/SimpleUtil/HMI.Simple.Util/HMI.Simple.Util.csproj
+++ b/SimpleUtil/HMI.Simple.Util/HMI.Simple.Util.csproj
@@ -30,6 +30,42 @@
     <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>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <LangVersion>7.3</LangVersion>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <LangVersion>7.3</LangVersion>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
   <ItemGroup>
     <Reference Include="NationalInstruments.TestStand.Interop.API, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL">
       <EmbedInteropTypes>True</EmbedInteropTypes>
@@ -39,6 +75,7 @@
     <Reference Include="System.Data.SQLite">
       <HintPath>..\..\..\HMI.Old\Plugin_OPCServer\Libs\System.Data.SQLite.dll</HintPath>
     </Reference>
+    <Reference Include="System.Messaging" />
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
     <Reference Include="Microsoft.CSharp" />
@@ -47,8 +84,11 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="AlarmUtil.cs" />
+    <Compile Include="MSMQHelper.cs" />
     <Compile Include="ParameterUtil.cs" />
     <Compile Include="Parameter.cs" />
+    <Compile Include="SerialDataHelper.cs" />
     <Compile Include="ProductModelHelper.cs" />
     <Compile Include="ProductUtil.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
diff --git a/SimpleUtil/HMI.Simple.Util/MSMQHelper.cs b/SimpleUtil/HMI.Simple.Util/MSMQHelper.cs
new file mode 100644
index 0000000..3232d7e
--- /dev/null
+++ b/SimpleUtil/HMI.Simple.Util/MSMQHelper.cs
@@ -0,0 +1,139 @@
+锘縰sing System;
+using System.Messaging;
+
+namespace HMI.Simple.Util
+{
+    public class MSMQHelper : IDisposable
+    {
+        /// <summary>
+        /// 娑堟伅闃熷垪鍚嶇О
+        /// </summary>
+        private string msmqName = string.Empty;
+
+        /// <summary>
+        /// 娑堟伅闃熷垪璺緞
+        /// </summary>
+        private string msmqPath = string.Empty;
+
+        /// <summary>
+        /// 瑕佹搷浣滅殑娑堟伅闃熷垪
+        /// </summary>
+        private MessageQueue msgQueue = null;
+
+        /// <summary>
+        /// 鏋勯�犲嚱鏁�
+        /// </summary>
+        /// <param name="Name">娑堟伅闃熷垪鍚嶇О</param>
+        public MSMQHelper(string Name)
+        {
+            try
+            {
+                this.msmqName = Name;
+                this.msmqPath = ".\\private$\\" + this.msmqName;
+                if (MessageQueue.Exists(this.msmqPath))
+                {
+                    // 濡傛灉褰撳墠娑堟伅闃熷垪宸茬粡瀛樺湪
+                    this.msgQueue = new MessageQueue(this.msmqPath);
+                }
+                else
+                {
+                    // 濡傛灉娑堟伅闃熷垪涓嶅瓨鍦紝鍒欏垱寤烘秷鎭鍨�
+                    this.msgQueue = MessageQueue.Create(this.msmqPath);
+                }
+                this.msgQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
+            }
+            catch (Exception ex)
+            {
+                throw new Exception(ex.Message);
+            }
+        }
+
+        /// <summary>
+        /// 鍙戦�佹秷鎭�
+        /// </summary>
+        /// <param name="MessageID">娑堟伅ID</param>
+        /// <param name="MsgString">瑕佸彂閫佺殑瀛楃涓�</param>
+        public void Send(string MessageID, string MsgString)
+        {
+            try
+            {
+                this.msgQueue.Send(MsgString, MessageID);
+            }
+            catch (Exception ex)
+            {
+                throw new Exception(ex.Message);
+            }
+        }
+
+        /// <summary>
+        /// 鎺ユ敹娑堟伅闃熷垪涓殑娑堟伅
+        /// </summary>
+        /// <param name="TimeOut">瓒呮椂鏃堕棿(ms)</param>
+        /// <param name="MessageID">娑堟伅ID</param>
+        /// <param name="MsgString">娑堟伅鍐呭</param>
+        public void Receive(long TimeOut, out string MessageID, out string MsgString)
+        {
+            try
+            {
+                MessageID = string.Empty;
+                MsgString = string.Empty;
+                TimeSpan Time = new TimeSpan(TimeOut);
+                Message MsgReceived = null;
+                try
+                {
+                    MsgReceived = this.msgQueue.Receive(Time);
+                }
+                catch
+                {
+                    // do nothing
+                }
+
+                if (MsgReceived != null)
+                {
+                    MessageID = MsgReceived.Label;
+                    MsgString = MsgReceived.Body.ToString();
+                }
+            }
+            catch (Exception ex)
+            {
+                throw new Exception("鎺ユ敹娑堟伅澶辫触:" + ex.Message);
+            }
+        }
+
+        /// <summary>
+        /// 娓呴櫎娑堟伅闃熷垪涓殑娑堟伅
+        /// </summary>
+        public void Clear()
+        {
+            try
+            {
+                this.msgQueue.Purge();
+            }
+            catch (Exception ex)
+            {
+                throw new Exception("娓呴櫎娑堟伅闃熷垪澶辫触:" + ex.Message);
+            }
+        }
+
+        /// <summary>
+        /// 鍏抽棴褰撳墠闃熷垪
+        /// </summary>
+        public void Close()
+        {
+            this.msgQueue.Close();
+        }
+
+        /// <summary>
+        /// 鍒犻櫎褰撳墠闃熷垪
+        /// </summary>
+        public void Delete()
+        {
+            MessageQueue.Delete(this.msmqPath);
+        }
+
+        public void Dispose()
+        {
+            this.Close();
+        }
+    }
+}
diff --git a/SimpleUtil/HMI.Simple.Util/Parameter.cs b/SimpleUtil/HMI.Simple.Util/Parameter.cs
index 97bc1da..71237da 100644
--- a/SimpleUtil/HMI.Simple.Util/Parameter.cs
+++ b/SimpleUtil/HMI.Simple.Util/Parameter.cs
@@ -1,6 +1,6 @@
 锘縩amespace HMI.Simple.Util
 {
-    internal class ParameterData
+    public class ParameterData
     {
         public string Id { get; set; }
         public string Name { get; set; }
diff --git a/SimpleUtil/HMI.Simple.Util/ParameterUtil.cs b/SimpleUtil/HMI.Simple.Util/ParameterUtil.cs
index 7b86228..25b24ae 100644
--- a/SimpleUtil/HMI.Simple.Util/ParameterUtil.cs
+++ b/SimpleUtil/HMI.Simple.Util/ParameterUtil.cs
@@ -65,7 +65,7 @@
             }
             else if (data.Type == "Int")
             {
-                context.StationGlobals.SetValInteger64($"{prefix}.{data.Name}", 1, int.Parse(data.Value));
+                context.StationGlobals.SetValNumber($"{prefix}.{data.Name}", 1, int.Parse(data.Value));
             }
             else if (data.Type == "Double")
             {
diff --git a/SimpleUtil/HMI.Simple.Util/ProductUtil.cs b/SimpleUtil/HMI.Simple.Util/ProductUtil.cs
index b4cf7db..aab00f6 100644
--- a/SimpleUtil/HMI.Simple.Util/ProductUtil.cs
+++ b/SimpleUtil/HMI.Simple.Util/ProductUtil.cs
@@ -34,7 +34,7 @@
             try
             {
                 string dir = RegUtil.GetLocaltion();
-                string path = Path.Combine(dir, "Config", "Product", $"Parameter_{model}.data");
+                string path = Path.Combine(dir, "Config", "Product","Parameter", $"Parameter_{model}.data");
                 return WriteConfigToContextByPath(path, instance, out errMsg);
             }
             catch (Exception ex)
diff --git a/SimpleUtil/HMI.Simple.Util/Properties/AssemblyInfo.cs b/SimpleUtil/HMI.Simple.Util/Properties/AssemblyInfo.cs
index cb017d7..72ab98f 100644
--- a/SimpleUtil/HMI.Simple.Util/Properties/AssemblyInfo.cs
+++ b/SimpleUtil/HMI.Simple.Util/Properties/AssemblyInfo.cs
@@ -30,4 +30,4 @@
 //      淇鍙�
 //
 [assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.2")]
diff --git a/SimpleUtil/HMI.Simple.Util/SerialDataHelper.cs b/SimpleUtil/HMI.Simple.Util/SerialDataHelper.cs
new file mode 100644
index 0000000..569445f
--- /dev/null
+++ b/SimpleUtil/HMI.Simple.Util/SerialDataHelper.cs
@@ -0,0 +1,117 @@
+锘縰sing System;
+using System.Data;
+using System.IO;
+
+namespace HMI.Simple.Util
+{
+    public class SerialDataHelper
+    {
+        public static bool GetFailCountBySNR(string snr, out int count, out string msg)
+        {
+            count = -1;
+            msg = string.Empty;
+            SqliteHelper sqliteHelper = null;
+            try
+            {
+                string dataLogPath = "";
+                var value = ParameterUtil.GetCommonParameterValue("TS_DataLogPath", out msg);
+                if (!string.IsNullOrEmpty(msg))
+                {
+                    string appFolder = RegUtil.GetLocaltion();
+                    dataLogPath = Path.Combine(appFolder, "Config", "DataBoard", "DataLog.db");
+                }
+                if (!File.Exists(dataLogPath))
+                {
+                    msg = "鏁版嵁搴撴枃浠朵笉瀛樺湪";
+                    return false;
+                }
+                sqliteHelper = new SqliteHelper(dataLogPath);
+
+                var sql = $@"SELECT COUNT(*) as num FROM testResult WHERE sn = '{snr}' AND result = 'Failed';";
+                DataTable dt = sqliteHelper.GetDataTable(sql);
+                if (dt.Rows.Count <= 0)
+                {
+                    count = 0;
+                    return true;
+                }
+                count = int.Parse(dt.Rows[0]["num"].ToString());
+                return true;
+            }
+            catch (Exception ex)
+            {
+                msg = ex.Message;
+                return false;
+            }
+            finally
+            {
+                sqliteHelper?.Dispose();
+            }
+        }
+
+        public static bool GetCountBySNRAndPosition(string snr, string position,
+            out int okCount,
+            out int ngCount,
+            out string status,
+            out string msg)
+        {
+            okCount = -1;
+            ngCount = -1;
+            status = string.Empty;
+            msg = string.Empty;
+            SqliteHelper sqliteHelper = null;
+            try
+            {
+                string dataLogPath = "";
+                var value = ParameterUtil.GetCommonParameterValue("TS_DataLogPath", out msg);
+                if (!string.IsNullOrEmpty(msg))
+                {
+                    string appFolder = RegUtil.GetLocaltion();
+                    dataLogPath = Path.Combine(appFolder, "Config", "DataBoard", "DataLog.db");
+                }
+                if (!File.Exists(dataLogPath))
+                {
+                    msg = "鏁版嵁搴撴枃浠朵笉瀛樺湪";
+                    return false;
+                }
+                sqliteHelper = new SqliteHelper(dataLogPath);
+
+                var sql = $@"SELECT COUNT(*) as num FROM testResult WHERE sn = '{snr}' AND position = '{position}' AND result = 'Failed';";
+                DataTable dt = sqliteHelper.GetDataTable(sql);
+                if (dt.Rows.Count <= 0)
+                {
+                    ngCount = 0;
+                    return true;
+                }
+                ngCount = int.Parse(dt.Rows[0]["num"].ToString());
+
+                sql = $@"SELECT COUNT(*) as num FROM testResult WHERE sn = '{snr}' AND position = '{position}' AND result = 'Passed';";
+                dt = sqliteHelper.GetDataTable(sql);
+                if (dt.Rows.Count <= 0)
+                {
+                    okCount = 0;
+                    return true;
+                }
+                okCount = int.Parse(dt.Rows[0]["num"].ToString());
+
+                sql = $@"SELECT status as status FROM testResult WHERE sn = '{snr}' ORDER BY time DESC LIMIT 0,1;";
+                dt = sqliteHelper.GetDataTable(sql);
+                if (dt.Rows.Count <= 0)
+                {
+                    status = string.Empty;
+                    return true;
+                }
+                status = dt.Rows[0]["status"] == DBNull.Value ? string.Empty : dt.Rows[0]["status"].ToString();
+                return true;
+            }
+            catch (Exception ex)
+            {
+                msg = ex.Message;
+                return false;
+            }
+            finally
+            {
+                sqliteHelper?.Dispose();
+            }
+        }
+    }
+}
diff --git a/WPFProject/WPFProject.csproj b/WPFProject/WPFProject.csproj
index 4558ef5..f219855 100644
--- a/WPFProject/WPFProject.csproj
+++ b/WPFProject/WPFProject.csproj
@@ -97,6 +97,26 @@
   <PropertyGroup>
     <ApplicationManifest>Properties\app.manifest</ApplicationManifest>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <LangVersion>latest</LangVersion>
+    <ErrorReport>prompt</ErrorReport>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <LangVersion>latest</LangVersion>
+    <ErrorReport>prompt</ErrorReport>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
   <ItemGroup>
     <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>
diff --git a/WPFProject/WPFProject.sln b/WPFProject/WPFProject.sln
index 366f8fa..0c98dc2 100644
--- a/WPFProject/WPFProject.sln
+++ b/WPFProject/WPFProject.sln
@@ -81,318 +81,500 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.ModelManage", "..\Plugin.ModelManage\Plugin.ModelManage.csproj", "{76CE4D21-702C-416F-95B4-F4F4C5B2D162}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DIOController", "..\SimpleUtil\DIOController\DIOController.csproj", "{34FFBAFE-478F-4B6E-95E7-92A949011A9B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleTest", "..\ConsoleTest\ConsoleTest.csproj", "{2BDDB984-199B-4913-96BB-39C252E101F2}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
 		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
 		Release|Any CPU = Release|Any CPU
 		Release|x64 = Release|x64
+		Release|x86 = Release|x86
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 		{D47D2314-5DD5-4899-ADF9-15ED057289D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{D47D2314-5DD5-4899-ADF9-15ED057289D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{D47D2314-5DD5-4899-ADF9-15ED057289D3}.Debug|x64.ActiveCfg = Debug|x64
 		{D47D2314-5DD5-4899-ADF9-15ED057289D3}.Debug|x64.Build.0 = Debug|x64
+		{D47D2314-5DD5-4899-ADF9-15ED057289D3}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{D47D2314-5DD5-4899-ADF9-15ED057289D3}.Debug|x86.Build.0 = Debug|Any CPU
 		{D47D2314-5DD5-4899-ADF9-15ED057289D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{D47D2314-5DD5-4899-ADF9-15ED057289D3}.Release|Any CPU.Build.0 = Release|Any CPU
 		{D47D2314-5DD5-4899-ADF9-15ED057289D3}.Release|x64.ActiveCfg = Release|x64
 		{D47D2314-5DD5-4899-ADF9-15ED057289D3}.Release|x64.Build.0 = Release|x64
+		{D47D2314-5DD5-4899-ADF9-15ED057289D3}.Release|x86.ActiveCfg = Release|x86
+		{D47D2314-5DD5-4899-ADF9-15ED057289D3}.Release|x86.Build.0 = Release|x86
 		{3E3BF44A-0B69-45C5-9512-528CB48A7106}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{3E3BF44A-0B69-45C5-9512-528CB48A7106}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{3E3BF44A-0B69-45C5-9512-528CB48A7106}.Debug|x64.ActiveCfg = Debug|x64
 		{3E3BF44A-0B69-45C5-9512-528CB48A7106}.Debug|x64.Build.0 = Debug|x64
+		{3E3BF44A-0B69-45C5-9512-528CB48A7106}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{3E3BF44A-0B69-45C5-9512-528CB48A7106}.Debug|x86.Build.0 = Debug|Any CPU
 		{3E3BF44A-0B69-45C5-9512-528CB48A7106}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{3E3BF44A-0B69-45C5-9512-528CB48A7106}.Release|Any CPU.Build.0 = Release|Any CPU
 		{3E3BF44A-0B69-45C5-9512-528CB48A7106}.Release|x64.ActiveCfg = Release|x64
 		{3E3BF44A-0B69-45C5-9512-528CB48A7106}.Release|x64.Build.0 = Release|x64
+		{3E3BF44A-0B69-45C5-9512-528CB48A7106}.Release|x86.ActiveCfg = Release|x86
+		{3E3BF44A-0B69-45C5-9512-528CB48A7106}.Release|x86.Build.0 = Release|x86
 		{6E1CC97A-B3CB-4E9F-94E0-F264DE0D8298}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{6E1CC97A-B3CB-4E9F-94E0-F264DE0D8298}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{6E1CC97A-B3CB-4E9F-94E0-F264DE0D8298}.Debug|x64.ActiveCfg = Debug|x64
 		{6E1CC97A-B3CB-4E9F-94E0-F264DE0D8298}.Debug|x64.Build.0 = Debug|x64
+		{6E1CC97A-B3CB-4E9F-94E0-F264DE0D8298}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{6E1CC97A-B3CB-4E9F-94E0-F264DE0D8298}.Debug|x86.Build.0 = Debug|Any CPU
 		{6E1CC97A-B3CB-4E9F-94E0-F264DE0D8298}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{6E1CC97A-B3CB-4E9F-94E0-F264DE0D8298}.Release|Any CPU.Build.0 = Release|Any CPU
 		{6E1CC97A-B3CB-4E9F-94E0-F264DE0D8298}.Release|x64.ActiveCfg = Release|x64
 		{6E1CC97A-B3CB-4E9F-94E0-F264DE0D8298}.Release|x64.Build.0 = Release|x64
+		{6E1CC97A-B3CB-4E9F-94E0-F264DE0D8298}.Release|x86.ActiveCfg = Release|Any CPU
+		{6E1CC97A-B3CB-4E9F-94E0-F264DE0D8298}.Release|x86.Build.0 = Release|Any CPU
 		{8E5E8A68-0B9D-4A6A-B325-730C64603FDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{8E5E8A68-0B9D-4A6A-B325-730C64603FDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{8E5E8A68-0B9D-4A6A-B325-730C64603FDF}.Debug|x64.ActiveCfg = Debug|x64
 		{8E5E8A68-0B9D-4A6A-B325-730C64603FDF}.Debug|x64.Build.0 = Debug|x64
+		{8E5E8A68-0B9D-4A6A-B325-730C64603FDF}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{8E5E8A68-0B9D-4A6A-B325-730C64603FDF}.Debug|x86.Build.0 = Debug|Any CPU
 		{8E5E8A68-0B9D-4A6A-B325-730C64603FDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{8E5E8A68-0B9D-4A6A-B325-730C64603FDF}.Release|Any CPU.Build.0 = Release|Any CPU
 		{8E5E8A68-0B9D-4A6A-B325-730C64603FDF}.Release|x64.ActiveCfg = Release|x64
 		{8E5E8A68-0B9D-4A6A-B325-730C64603FDF}.Release|x64.Build.0 = Release|x64
+		{8E5E8A68-0B9D-4A6A-B325-730C64603FDF}.Release|x86.ActiveCfg = Release|Any CPU
+		{8E5E8A68-0B9D-4A6A-B325-730C64603FDF}.Release|x86.Build.0 = Release|Any CPU
 		{F17DE6B5-AF1D-48C6-94A0-6B763A6546A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{F17DE6B5-AF1D-48C6-94A0-6B763A6546A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{F17DE6B5-AF1D-48C6-94A0-6B763A6546A6}.Debug|x64.ActiveCfg = Debug|x64
 		{F17DE6B5-AF1D-48C6-94A0-6B763A6546A6}.Debug|x64.Build.0 = Debug|x64
+		{F17DE6B5-AF1D-48C6-94A0-6B763A6546A6}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{F17DE6B5-AF1D-48C6-94A0-6B763A6546A6}.Debug|x86.Build.0 = Debug|Any CPU
 		{F17DE6B5-AF1D-48C6-94A0-6B763A6546A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{F17DE6B5-AF1D-48C6-94A0-6B763A6546A6}.Release|Any CPU.Build.0 = Release|Any CPU
 		{F17DE6B5-AF1D-48C6-94A0-6B763A6546A6}.Release|x64.ActiveCfg = Release|Any CPU
 		{F17DE6B5-AF1D-48C6-94A0-6B763A6546A6}.Release|x64.Build.0 = Release|Any CPU
+		{F17DE6B5-AF1D-48C6-94A0-6B763A6546A6}.Release|x86.ActiveCfg = Release|Any CPU
+		{F17DE6B5-AF1D-48C6-94A0-6B763A6546A6}.Release|x86.Build.0 = Release|Any CPU
 		{DE4205C6-5923-46FD-A4B9-65169BF61C75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{DE4205C6-5923-46FD-A4B9-65169BF61C75}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{DE4205C6-5923-46FD-A4B9-65169BF61C75}.Debug|x64.ActiveCfg = Debug|x64
 		{DE4205C6-5923-46FD-A4B9-65169BF61C75}.Debug|x64.Build.0 = Debug|x64
+		{DE4205C6-5923-46FD-A4B9-65169BF61C75}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{DE4205C6-5923-46FD-A4B9-65169BF61C75}.Debug|x86.Build.0 = Debug|Any CPU
 		{DE4205C6-5923-46FD-A4B9-65169BF61C75}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{DE4205C6-5923-46FD-A4B9-65169BF61C75}.Release|Any CPU.Build.0 = Release|Any CPU
 		{DE4205C6-5923-46FD-A4B9-65169BF61C75}.Release|x64.ActiveCfg = Release|Any CPU
 		{DE4205C6-5923-46FD-A4B9-65169BF61C75}.Release|x64.Build.0 = Release|Any CPU
+		{DE4205C6-5923-46FD-A4B9-65169BF61C75}.Release|x86.ActiveCfg = Release|Any CPU
+		{DE4205C6-5923-46FD-A4B9-65169BF61C75}.Release|x86.Build.0 = Release|Any CPU
 		{7C299AED-88CC-437E-A68B-1550AA72E6B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{7C299AED-88CC-437E-A68B-1550AA72E6B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{7C299AED-88CC-437E-A68B-1550AA72E6B0}.Debug|x64.ActiveCfg = Debug|x64
 		{7C299AED-88CC-437E-A68B-1550AA72E6B0}.Debug|x64.Build.0 = Debug|x64
+		{7C299AED-88CC-437E-A68B-1550AA72E6B0}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{7C299AED-88CC-437E-A68B-1550AA72E6B0}.Debug|x86.Build.0 = Debug|Any CPU
 		{7C299AED-88CC-437E-A68B-1550AA72E6B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{7C299AED-88CC-437E-A68B-1550AA72E6B0}.Release|Any CPU.Build.0 = Release|Any CPU
 		{7C299AED-88CC-437E-A68B-1550AA72E6B0}.Release|x64.ActiveCfg = Release|Any CPU
 		{7C299AED-88CC-437E-A68B-1550AA72E6B0}.Release|x64.Build.0 = Release|Any CPU
+		{7C299AED-88CC-437E-A68B-1550AA72E6B0}.Release|x86.ActiveCfg = Release|Any CPU
+		{7C299AED-88CC-437E-A68B-1550AA72E6B0}.Release|x86.Build.0 = Release|Any CPU
 		{325A7F52-FE51-44F0-B3AC-5F42F5356605}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{325A7F52-FE51-44F0-B3AC-5F42F5356605}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{325A7F52-FE51-44F0-B3AC-5F42F5356605}.Debug|x64.ActiveCfg = Debug|x64
 		{325A7F52-FE51-44F0-B3AC-5F42F5356605}.Debug|x64.Build.0 = Debug|x64
+		{325A7F52-FE51-44F0-B3AC-5F42F5356605}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{325A7F52-FE51-44F0-B3AC-5F42F5356605}.Debug|x86.Build.0 = Debug|Any CPU
 		{325A7F52-FE51-44F0-B3AC-5F42F5356605}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{325A7F52-FE51-44F0-B3AC-5F42F5356605}.Release|Any CPU.Build.0 = Release|Any CPU
 		{325A7F52-FE51-44F0-B3AC-5F42F5356605}.Release|x64.ActiveCfg = Release|Any CPU
 		{325A7F52-FE51-44F0-B3AC-5F42F5356605}.Release|x64.Build.0 = Release|Any CPU
+		{325A7F52-FE51-44F0-B3AC-5F42F5356605}.Release|x86.ActiveCfg = Release|Any CPU
+		{325A7F52-FE51-44F0-B3AC-5F42F5356605}.Release|x86.Build.0 = Release|Any CPU
 		{945C2577-4558-45E3-891A-096CB3047304}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{945C2577-4558-45E3-891A-096CB3047304}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{945C2577-4558-45E3-891A-096CB3047304}.Debug|x64.ActiveCfg = Debug|x64
 		{945C2577-4558-45E3-891A-096CB3047304}.Debug|x64.Build.0 = Debug|x64
+		{945C2577-4558-45E3-891A-096CB3047304}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{945C2577-4558-45E3-891A-096CB3047304}.Debug|x86.Build.0 = Debug|Any CPU
 		{945C2577-4558-45E3-891A-096CB3047304}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{945C2577-4558-45E3-891A-096CB3047304}.Release|Any CPU.Build.0 = Release|Any CPU
 		{945C2577-4558-45E3-891A-096CB3047304}.Release|x64.ActiveCfg = Release|Any CPU
 		{945C2577-4558-45E3-891A-096CB3047304}.Release|x64.Build.0 = Release|Any CPU
+		{945C2577-4558-45E3-891A-096CB3047304}.Release|x86.ActiveCfg = Release|Any CPU
+		{945C2577-4558-45E3-891A-096CB3047304}.Release|x86.Build.0 = Release|Any CPU
 		{3DD748AC-9708-49AD-B846-659214035588}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{3DD748AC-9708-49AD-B846-659214035588}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{3DD748AC-9708-49AD-B846-659214035588}.Debug|x64.ActiveCfg = Debug|x64
 		{3DD748AC-9708-49AD-B846-659214035588}.Debug|x64.Build.0 = Debug|x64
+		{3DD748AC-9708-49AD-B846-659214035588}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{3DD748AC-9708-49AD-B846-659214035588}.Debug|x86.Build.0 = Debug|Any CPU
 		{3DD748AC-9708-49AD-B846-659214035588}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{3DD748AC-9708-49AD-B846-659214035588}.Release|Any CPU.Build.0 = Release|Any CPU
 		{3DD748AC-9708-49AD-B846-659214035588}.Release|x64.ActiveCfg = Release|Any CPU
 		{3DD748AC-9708-49AD-B846-659214035588}.Release|x64.Build.0 = Release|Any CPU
+		{3DD748AC-9708-49AD-B846-659214035588}.Release|x86.ActiveCfg = Release|Any CPU
+		{3DD748AC-9708-49AD-B846-659214035588}.Release|x86.Build.0 = Release|Any CPU
 		{2A6F9720-A890-4036-9D73-41A0DAE28341}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{2A6F9720-A890-4036-9D73-41A0DAE28341}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{2A6F9720-A890-4036-9D73-41A0DAE28341}.Debug|x64.ActiveCfg = Debug|x64
 		{2A6F9720-A890-4036-9D73-41A0DAE28341}.Debug|x64.Build.0 = Debug|x64
+		{2A6F9720-A890-4036-9D73-41A0DAE28341}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{2A6F9720-A890-4036-9D73-41A0DAE28341}.Debug|x86.Build.0 = Debug|Any CPU
 		{2A6F9720-A890-4036-9D73-41A0DAE28341}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{2A6F9720-A890-4036-9D73-41A0DAE28341}.Release|Any CPU.Build.0 = Release|Any CPU
 		{2A6F9720-A890-4036-9D73-41A0DAE28341}.Release|x64.ActiveCfg = Release|Any CPU
 		{2A6F9720-A890-4036-9D73-41A0DAE28341}.Release|x64.Build.0 = Release|Any CPU
+		{2A6F9720-A890-4036-9D73-41A0DAE28341}.Release|x86.ActiveCfg = Release|Any CPU
+		{2A6F9720-A890-4036-9D73-41A0DAE28341}.Release|x86.Build.0 = Release|Any CPU
 		{A580DE4A-34E7-4EFE-AD2C-0871396000E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{A580DE4A-34E7-4EFE-AD2C-0871396000E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{A580DE4A-34E7-4EFE-AD2C-0871396000E9}.Debug|x64.ActiveCfg = Debug|x64
 		{A580DE4A-34E7-4EFE-AD2C-0871396000E9}.Debug|x64.Build.0 = Debug|x64
+		{A580DE4A-34E7-4EFE-AD2C-0871396000E9}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{A580DE4A-34E7-4EFE-AD2C-0871396000E9}.Debug|x86.Build.0 = Debug|Any CPU
 		{A580DE4A-34E7-4EFE-AD2C-0871396000E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{A580DE4A-34E7-4EFE-AD2C-0871396000E9}.Release|Any CPU.Build.0 = Release|Any CPU
 		{A580DE4A-34E7-4EFE-AD2C-0871396000E9}.Release|x64.ActiveCfg = Release|Any CPU
 		{A580DE4A-34E7-4EFE-AD2C-0871396000E9}.Release|x64.Build.0 = Release|Any CPU
+		{A580DE4A-34E7-4EFE-AD2C-0871396000E9}.Release|x86.ActiveCfg = Release|Any CPU
+		{A580DE4A-34E7-4EFE-AD2C-0871396000E9}.Release|x86.Build.0 = Release|Any CPU
 		{F7663C79-7047-42F3-B129-73A2575EE7C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{F7663C79-7047-42F3-B129-73A2575EE7C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{F7663C79-7047-42F3-B129-73A2575EE7C6}.Debug|x64.ActiveCfg = Debug|x64
 		{F7663C79-7047-42F3-B129-73A2575EE7C6}.Debug|x64.Build.0 = Debug|x64
+		{F7663C79-7047-42F3-B129-73A2575EE7C6}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{F7663C79-7047-42F3-B129-73A2575EE7C6}.Debug|x86.Build.0 = Debug|Any CPU
 		{F7663C79-7047-42F3-B129-73A2575EE7C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{F7663C79-7047-42F3-B129-73A2575EE7C6}.Release|Any CPU.Build.0 = Release|Any CPU
 		{F7663C79-7047-42F3-B129-73A2575EE7C6}.Release|x64.ActiveCfg = Release|Any CPU
 		{F7663C79-7047-42F3-B129-73A2575EE7C6}.Release|x64.Build.0 = Release|Any CPU
+		{F7663C79-7047-42F3-B129-73A2575EE7C6}.Release|x86.ActiveCfg = Release|Any CPU
+		{F7663C79-7047-42F3-B129-73A2575EE7C6}.Release|x86.Build.0 = Release|Any CPU
 		{736CD77D-B81E-4866-BB00-84B0B57110F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{736CD77D-B81E-4866-BB00-84B0B57110F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{736CD77D-B81E-4866-BB00-84B0B57110F0}.Debug|x64.ActiveCfg = Debug|x64
 		{736CD77D-B81E-4866-BB00-84B0B57110F0}.Debug|x64.Build.0 = Debug|x64
+		{736CD77D-B81E-4866-BB00-84B0B57110F0}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{736CD77D-B81E-4866-BB00-84B0B57110F0}.Debug|x86.Build.0 = Debug|Any CPU
 		{736CD77D-B81E-4866-BB00-84B0B57110F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{736CD77D-B81E-4866-BB00-84B0B57110F0}.Release|Any CPU.Build.0 = Release|Any CPU
 		{736CD77D-B81E-4866-BB00-84B0B57110F0}.Release|x64.ActiveCfg = Release|Any CPU
 		{736CD77D-B81E-4866-BB00-84B0B57110F0}.Release|x64.Build.0 = Release|Any CPU
+		{736CD77D-B81E-4866-BB00-84B0B57110F0}.Release|x86.ActiveCfg = Release|Any CPU
+		{736CD77D-B81E-4866-BB00-84B0B57110F0}.Release|x86.Build.0 = Release|Any CPU
 		{20C23602-B029-4E21-8C11-B9E5F2223237}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{20C23602-B029-4E21-8C11-B9E5F2223237}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{20C23602-B029-4E21-8C11-B9E5F2223237}.Debug|x64.ActiveCfg = Debug|x64
 		{20C23602-B029-4E21-8C11-B9E5F2223237}.Debug|x64.Build.0 = Debug|x64
+		{20C23602-B029-4E21-8C11-B9E5F2223237}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{20C23602-B029-4E21-8C11-B9E5F2223237}.Debug|x86.Build.0 = Debug|Any CPU
 		{20C23602-B029-4E21-8C11-B9E5F2223237}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{20C23602-B029-4E21-8C11-B9E5F2223237}.Release|Any CPU.Build.0 = Release|Any CPU
 		{20C23602-B029-4E21-8C11-B9E5F2223237}.Release|x64.ActiveCfg = Release|Any CPU
 		{20C23602-B029-4E21-8C11-B9E5F2223237}.Release|x64.Build.0 = Release|Any CPU
+		{20C23602-B029-4E21-8C11-B9E5F2223237}.Release|x86.ActiveCfg = Release|Any CPU
+		{20C23602-B029-4E21-8C11-B9E5F2223237}.Release|x86.Build.0 = Release|Any CPU
 		{7375B74C-B6BF-4814-9838-E1CAACAD1897}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{7375B74C-B6BF-4814-9838-E1CAACAD1897}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{7375B74C-B6BF-4814-9838-E1CAACAD1897}.Debug|x64.ActiveCfg = Debug|x64
 		{7375B74C-B6BF-4814-9838-E1CAACAD1897}.Debug|x64.Build.0 = Debug|x64
+		{7375B74C-B6BF-4814-9838-E1CAACAD1897}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{7375B74C-B6BF-4814-9838-E1CAACAD1897}.Debug|x86.Build.0 = Debug|Any CPU
 		{7375B74C-B6BF-4814-9838-E1CAACAD1897}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{7375B74C-B6BF-4814-9838-E1CAACAD1897}.Release|Any CPU.Build.0 = Release|Any CPU
 		{7375B74C-B6BF-4814-9838-E1CAACAD1897}.Release|x64.ActiveCfg = Release|x64
 		{7375B74C-B6BF-4814-9838-E1CAACAD1897}.Release|x64.Build.0 = Release|x64
+		{7375B74C-B6BF-4814-9838-E1CAACAD1897}.Release|x86.ActiveCfg = Release|x86
+		{7375B74C-B6BF-4814-9838-E1CAACAD1897}.Release|x86.Build.0 = Release|x86
 		{202D9A7B-96B3-4AD4-9977-FC4263207A02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{202D9A7B-96B3-4AD4-9977-FC4263207A02}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{202D9A7B-96B3-4AD4-9977-FC4263207A02}.Debug|x64.ActiveCfg = Debug|x64
 		{202D9A7B-96B3-4AD4-9977-FC4263207A02}.Debug|x64.Build.0 = Debug|x64
+		{202D9A7B-96B3-4AD4-9977-FC4263207A02}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{202D9A7B-96B3-4AD4-9977-FC4263207A02}.Debug|x86.Build.0 = Debug|Any CPU
 		{202D9A7B-96B3-4AD4-9977-FC4263207A02}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{202D9A7B-96B3-4AD4-9977-FC4263207A02}.Release|Any CPU.Build.0 = Release|Any CPU
-		{202D9A7B-96B3-4AD4-9977-FC4263207A02}.Release|x64.ActiveCfg = Release|Any CPU
-		{202D9A7B-96B3-4AD4-9977-FC4263207A02}.Release|x64.Build.0 = Release|Any CPU
+		{202D9A7B-96B3-4AD4-9977-FC4263207A02}.Release|x64.ActiveCfg = Release|x64
+		{202D9A7B-96B3-4AD4-9977-FC4263207A02}.Release|x64.Build.0 = Release|x64
+		{202D9A7B-96B3-4AD4-9977-FC4263207A02}.Release|x86.ActiveCfg = Release|x86
+		{202D9A7B-96B3-4AD4-9977-FC4263207A02}.Release|x86.Build.0 = Release|x86
 		{AFEA100A-9223-448D-AB10-3015D93DD98C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{AFEA100A-9223-448D-AB10-3015D93DD98C}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{AFEA100A-9223-448D-AB10-3015D93DD98C}.Debug|x64.ActiveCfg = Debug|x64
 		{AFEA100A-9223-448D-AB10-3015D93DD98C}.Debug|x64.Build.0 = Debug|x64
+		{AFEA100A-9223-448D-AB10-3015D93DD98C}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{AFEA100A-9223-448D-AB10-3015D93DD98C}.Debug|x86.Build.0 = Debug|Any CPU
 		{AFEA100A-9223-448D-AB10-3015D93DD98C}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{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
+		{AFEA100A-9223-448D-AB10-3015D93DD98C}.Release|x86.ActiveCfg = Release|Any CPU
+		{AFEA100A-9223-448D-AB10-3015D93DD98C}.Release|x86.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}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{1853E00F-6865-4BC6-974B-6A5E1C00BAFE}.Debug|x86.Build.0 = Debug|Any CPU
 		{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
+		{1853E00F-6865-4BC6-974B-6A5E1C00BAFE}.Release|x86.ActiveCfg = Release|Any CPU
+		{1853E00F-6865-4BC6-974B-6A5E1C00BAFE}.Release|x86.Build.0 = Release|Any CPU
 		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Debug|x64.ActiveCfg = Debug|x64
 		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Debug|x64.Build.0 = Debug|x64
+		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Debug|x86.Build.0 = Debug|Any CPU
 		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Release|Any CPU.Build.0 = Release|Any CPU
 		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Release|x64.ActiveCfg = Release|Any CPU
 		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Release|x64.Build.0 = Release|Any CPU
+		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Release|x86.ActiveCfg = Release|Any CPU
+		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Release|x86.Build.0 = Release|Any CPU
 		{D0806FA6-3F6D-4304-81B8-EAD9DA7CB5B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{D0806FA6-3F6D-4304-81B8-EAD9DA7CB5B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{D0806FA6-3F6D-4304-81B8-EAD9DA7CB5B2}.Debug|x64.ActiveCfg = Debug|x64
 		{D0806FA6-3F6D-4304-81B8-EAD9DA7CB5B2}.Debug|x64.Build.0 = Debug|x64
+		{D0806FA6-3F6D-4304-81B8-EAD9DA7CB5B2}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{D0806FA6-3F6D-4304-81B8-EAD9DA7CB5B2}.Debug|x86.Build.0 = Debug|Any CPU
 		{D0806FA6-3F6D-4304-81B8-EAD9DA7CB5B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{D0806FA6-3F6D-4304-81B8-EAD9DA7CB5B2}.Release|Any CPU.Build.0 = Release|Any CPU
 		{D0806FA6-3F6D-4304-81B8-EAD9DA7CB5B2}.Release|x64.ActiveCfg = Release|Any CPU
 		{D0806FA6-3F6D-4304-81B8-EAD9DA7CB5B2}.Release|x64.Build.0 = Release|Any CPU
+		{D0806FA6-3F6D-4304-81B8-EAD9DA7CB5B2}.Release|x86.ActiveCfg = Release|Any CPU
+		{D0806FA6-3F6D-4304-81B8-EAD9DA7CB5B2}.Release|x86.Build.0 = Release|Any CPU
 		{E5740BB5-9FC6-4A20-B7C2-CC90C281ED05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{E5740BB5-9FC6-4A20-B7C2-CC90C281ED05}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{E5740BB5-9FC6-4A20-B7C2-CC90C281ED05}.Debug|x64.ActiveCfg = Debug|x64
 		{E5740BB5-9FC6-4A20-B7C2-CC90C281ED05}.Debug|x64.Build.0 = Debug|x64
+		{E5740BB5-9FC6-4A20-B7C2-CC90C281ED05}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{E5740BB5-9FC6-4A20-B7C2-CC90C281ED05}.Debug|x86.Build.0 = Debug|Any CPU
 		{E5740BB5-9FC6-4A20-B7C2-CC90C281ED05}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{E5740BB5-9FC6-4A20-B7C2-CC90C281ED05}.Release|Any CPU.Build.0 = Release|Any CPU
 		{E5740BB5-9FC6-4A20-B7C2-CC90C281ED05}.Release|x64.ActiveCfg = Release|Any CPU
 		{E5740BB5-9FC6-4A20-B7C2-CC90C281ED05}.Release|x64.Build.0 = Release|Any CPU
+		{E5740BB5-9FC6-4A20-B7C2-CC90C281ED05}.Release|x86.ActiveCfg = Release|Any CPU
+		{E5740BB5-9FC6-4A20-B7C2-CC90C281ED05}.Release|x86.Build.0 = Release|Any CPU
 		{30201EC1-9A82-48DB-94B9-BD5C1190228B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{30201EC1-9A82-48DB-94B9-BD5C1190228B}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{30201EC1-9A82-48DB-94B9-BD5C1190228B}.Debug|x64.ActiveCfg = Debug|x64
 		{30201EC1-9A82-48DB-94B9-BD5C1190228B}.Debug|x64.Build.0 = Debug|x64
+		{30201EC1-9A82-48DB-94B9-BD5C1190228B}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{30201EC1-9A82-48DB-94B9-BD5C1190228B}.Debug|x86.Build.0 = Debug|Any CPU
 		{30201EC1-9A82-48DB-94B9-BD5C1190228B}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{30201EC1-9A82-48DB-94B9-BD5C1190228B}.Release|Any CPU.Build.0 = Release|Any CPU
 		{30201EC1-9A82-48DB-94B9-BD5C1190228B}.Release|x64.ActiveCfg = Release|Any CPU
 		{30201EC1-9A82-48DB-94B9-BD5C1190228B}.Release|x64.Build.0 = Release|Any CPU
+		{30201EC1-9A82-48DB-94B9-BD5C1190228B}.Release|x86.ActiveCfg = Release|Any CPU
+		{30201EC1-9A82-48DB-94B9-BD5C1190228B}.Release|x86.Build.0 = Release|Any CPU
 		{BE42AB26-3270-43E1-84B8-6929D862FF8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{BE42AB26-3270-43E1-84B8-6929D862FF8D}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{BE42AB26-3270-43E1-84B8-6929D862FF8D}.Debug|x64.ActiveCfg = Debug|x64
 		{BE42AB26-3270-43E1-84B8-6929D862FF8D}.Debug|x64.Build.0 = Debug|x64
+		{BE42AB26-3270-43E1-84B8-6929D862FF8D}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{BE42AB26-3270-43E1-84B8-6929D862FF8D}.Debug|x86.Build.0 = Debug|Any CPU
 		{BE42AB26-3270-43E1-84B8-6929D862FF8D}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{BE42AB26-3270-43E1-84B8-6929D862FF8D}.Release|Any CPU.Build.0 = Release|Any CPU
 		{BE42AB26-3270-43E1-84B8-6929D862FF8D}.Release|x64.ActiveCfg = Release|Any CPU
 		{BE42AB26-3270-43E1-84B8-6929D862FF8D}.Release|x64.Build.0 = Release|Any CPU
+		{BE42AB26-3270-43E1-84B8-6929D862FF8D}.Release|x86.ActiveCfg = Release|Any CPU
+		{BE42AB26-3270-43E1-84B8-6929D862FF8D}.Release|x86.Build.0 = Release|Any CPU
 		{CF5BEBE9-2803-49C3-B773-73D082E0984A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{CF5BEBE9-2803-49C3-B773-73D082E0984A}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{CF5BEBE9-2803-49C3-B773-73D082E0984A}.Debug|x64.ActiveCfg = Debug|Any CPU
 		{CF5BEBE9-2803-49C3-B773-73D082E0984A}.Debug|x64.Build.0 = Debug|Any CPU
+		{CF5BEBE9-2803-49C3-B773-73D082E0984A}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{CF5BEBE9-2803-49C3-B773-73D082E0984A}.Debug|x86.Build.0 = Debug|Any CPU
 		{CF5BEBE9-2803-49C3-B773-73D082E0984A}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{CF5BEBE9-2803-49C3-B773-73D082E0984A}.Release|Any CPU.Build.0 = Release|Any CPU
-		{CF5BEBE9-2803-49C3-B773-73D082E0984A}.Release|x64.ActiveCfg = Release|Any CPU
-		{CF5BEBE9-2803-49C3-B773-73D082E0984A}.Release|x64.Build.0 = Release|Any CPU
+		{CF5BEBE9-2803-49C3-B773-73D082E0984A}.Release|x64.ActiveCfg = Release|x64
+		{CF5BEBE9-2803-49C3-B773-73D082E0984A}.Release|x64.Build.0 = Release|x64
+		{CF5BEBE9-2803-49C3-B773-73D082E0984A}.Release|x86.ActiveCfg = Release|x86
+		{CF5BEBE9-2803-49C3-B773-73D082E0984A}.Release|x86.Build.0 = Release|x86
 		{6735FDB8-B471-41C3-93CB-E8ADBD0989F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{6735FDB8-B471-41C3-93CB-E8ADBD0989F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{6735FDB8-B471-41C3-93CB-E8ADBD0989F0}.Debug|x64.ActiveCfg = Debug|x64
 		{6735FDB8-B471-41C3-93CB-E8ADBD0989F0}.Debug|x64.Build.0 = Debug|x64
+		{6735FDB8-B471-41C3-93CB-E8ADBD0989F0}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{6735FDB8-B471-41C3-93CB-E8ADBD0989F0}.Debug|x86.Build.0 = Debug|Any CPU
 		{6735FDB8-B471-41C3-93CB-E8ADBD0989F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{6735FDB8-B471-41C3-93CB-E8ADBD0989F0}.Release|Any CPU.Build.0 = Release|Any CPU
 		{6735FDB8-B471-41C3-93CB-E8ADBD0989F0}.Release|x64.ActiveCfg = Release|Any CPU
 		{6735FDB8-B471-41C3-93CB-E8ADBD0989F0}.Release|x64.Build.0 = Release|Any CPU
+		{6735FDB8-B471-41C3-93CB-E8ADBD0989F0}.Release|x86.ActiveCfg = Release|Any CPU
+		{6735FDB8-B471-41C3-93CB-E8ADBD0989F0}.Release|x86.Build.0 = Release|Any CPU
 		{6D0AAB08-0F3E-48CE-B755-9D29BC8F1225}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{6D0AAB08-0F3E-48CE-B755-9D29BC8F1225}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{6D0AAB08-0F3E-48CE-B755-9D29BC8F1225}.Debug|x64.ActiveCfg = Debug|x64
 		{6D0AAB08-0F3E-48CE-B755-9D29BC8F1225}.Debug|x64.Build.0 = Debug|x64
+		{6D0AAB08-0F3E-48CE-B755-9D29BC8F1225}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{6D0AAB08-0F3E-48CE-B755-9D29BC8F1225}.Debug|x86.Build.0 = Debug|Any CPU
 		{6D0AAB08-0F3E-48CE-B755-9D29BC8F1225}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{6D0AAB08-0F3E-48CE-B755-9D29BC8F1225}.Release|Any CPU.Build.0 = Release|Any CPU
 		{6D0AAB08-0F3E-48CE-B755-9D29BC8F1225}.Release|x64.ActiveCfg = Release|Any CPU
 		{6D0AAB08-0F3E-48CE-B755-9D29BC8F1225}.Release|x64.Build.0 = Release|Any CPU
+		{6D0AAB08-0F3E-48CE-B755-9D29BC8F1225}.Release|x86.ActiveCfg = Release|Any CPU
+		{6D0AAB08-0F3E-48CE-B755-9D29BC8F1225}.Release|x86.Build.0 = Release|Any CPU
 		{D59E25D1-9B27-46A1-8438-92661DD23FAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{D59E25D1-9B27-46A1-8438-92661DD23FAE}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{D59E25D1-9B27-46A1-8438-92661DD23FAE}.Debug|x64.ActiveCfg = Debug|x64
 		{D59E25D1-9B27-46A1-8438-92661DD23FAE}.Debug|x64.Build.0 = Debug|x64
+		{D59E25D1-9B27-46A1-8438-92661DD23FAE}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{D59E25D1-9B27-46A1-8438-92661DD23FAE}.Debug|x86.Build.0 = Debug|Any CPU
 		{D59E25D1-9B27-46A1-8438-92661DD23FAE}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{D59E25D1-9B27-46A1-8438-92661DD23FAE}.Release|Any CPU.Build.0 = Release|Any CPU
 		{D59E25D1-9B27-46A1-8438-92661DD23FAE}.Release|x64.ActiveCfg = Release|Any CPU
 		{D59E25D1-9B27-46A1-8438-92661DD23FAE}.Release|x64.Build.0 = Release|Any CPU
+		{D59E25D1-9B27-46A1-8438-92661DD23FAE}.Release|x86.ActiveCfg = Release|Any CPU
+		{D59E25D1-9B27-46A1-8438-92661DD23FAE}.Release|x86.Build.0 = Release|Any CPU
 		{968FE602-22D6-42BD-981C-601AD518A896}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{968FE602-22D6-42BD-981C-601AD518A896}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{968FE602-22D6-42BD-981C-601AD518A896}.Debug|x64.ActiveCfg = Debug|x64
 		{968FE602-22D6-42BD-981C-601AD518A896}.Debug|x64.Build.0 = Debug|x64
+		{968FE602-22D6-42BD-981C-601AD518A896}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{968FE602-22D6-42BD-981C-601AD518A896}.Debug|x86.Build.0 = Debug|Any CPU
 		{968FE602-22D6-42BD-981C-601AD518A896}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{968FE602-22D6-42BD-981C-601AD518A896}.Release|Any CPU.Build.0 = Release|Any CPU
 		{968FE602-22D6-42BD-981C-601AD518A896}.Release|x64.ActiveCfg = Release|Any CPU
 		{968FE602-22D6-42BD-981C-601AD518A896}.Release|x64.Build.0 = Release|Any CPU
+		{968FE602-22D6-42BD-981C-601AD518A896}.Release|x86.ActiveCfg = Release|Any CPU
+		{968FE602-22D6-42BD-981C-601AD518A896}.Release|x86.Build.0 = Release|Any CPU
 		{717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Debug|x64.ActiveCfg = Debug|x64
 		{717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Debug|x64.Build.0 = Debug|x64
+		{717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Debug|x86.Build.0 = Debug|Any CPU
 		{717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Release|Any CPU.Build.0 = Release|Any CPU
 		{717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Release|x64.ActiveCfg = Release|x64
 		{717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Release|x64.Build.0 = Release|x64
+		{717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Release|x86.ActiveCfg = Release|x86
+		{717FD815-FF95-4F30-B4D9-9CEA978CA40E}.Release|x86.Build.0 = Release|x86
 		{EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Debug|x64.ActiveCfg = Debug|x64
 		{EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Debug|x64.Build.0 = Debug|x64
+		{EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Debug|x86.Build.0 = Debug|Any CPU
 		{EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Release|Any CPU.Build.0 = Release|Any CPU
 		{EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Release|x64.ActiveCfg = Release|Any CPU
 		{EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Release|x64.Build.0 = Release|Any CPU
+		{EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Release|x86.ActiveCfg = Release|Any CPU
+		{EF5972B1-DD20-404D-B2B3-37E70E2A478A}.Release|x86.Build.0 = Release|Any CPU
 		{376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Debug|x64.ActiveCfg = Debug|Any CPU
 		{376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Debug|x64.Build.0 = Debug|Any CPU
+		{376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Debug|x86.Build.0 = Debug|Any CPU
 		{376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Release|Any CPU.Build.0 = Release|Any CPU
 		{376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Release|x64.ActiveCfg = Release|Any CPU
 		{376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Release|x64.Build.0 = Release|Any CPU
+		{376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Release|x86.ActiveCfg = Release|Any CPU
+		{376CA791-49D8-B4D7-6F98-6E86BD46CAEF}.Release|x86.Build.0 = Release|Any CPU
 		{E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Debug|x64.ActiveCfg = Debug|x64
 		{E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Debug|x64.Build.0 = Debug|x64
+		{E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Debug|x86.Build.0 = Debug|Any CPU
 		{E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Release|Any CPU.Build.0 = Release|Any CPU
 		{E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Release|x64.ActiveCfg = Release|Any CPU
 		{E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Release|x64.Build.0 = Release|Any CPU
+		{E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Release|x86.ActiveCfg = Release|Any CPU
+		{E1F90CBD-A0D4-48DA-AB25-7F490935AA4A}.Release|x86.Build.0 = Release|Any CPU
 		{F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Debug|x64.ActiveCfg = Debug|Any CPU
 		{F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Debug|x64.Build.0 = Debug|Any CPU
+		{F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Debug|x86.Build.0 = Debug|Any CPU
 		{F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Release|Any CPU.Build.0 = Release|Any CPU
 		{F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Release|x64.ActiveCfg = Release|Any CPU
 		{F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Release|x64.Build.0 = Release|Any CPU
+		{F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Release|x86.ActiveCfg = Release|Any CPU
+		{F8B8B6B6-821B-4FF6-B556-9CAB840EA57A}.Release|x86.Build.0 = Release|Any CPU
 		{61DF853D-829A-4426-BEF8-0135586005B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{61DF853D-829A-4426-BEF8-0135586005B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{61DF853D-829A-4426-BEF8-0135586005B6}.Debug|x64.ActiveCfg = Debug|x64
 		{61DF853D-829A-4426-BEF8-0135586005B6}.Debug|x64.Build.0 = Debug|x64
+		{61DF853D-829A-4426-BEF8-0135586005B6}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{61DF853D-829A-4426-BEF8-0135586005B6}.Debug|x86.Build.0 = Debug|Any CPU
 		{61DF853D-829A-4426-BEF8-0135586005B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{61DF853D-829A-4426-BEF8-0135586005B6}.Release|Any CPU.Build.0 = Release|Any CPU
 		{61DF853D-829A-4426-BEF8-0135586005B6}.Release|x64.ActiveCfg = Release|Any CPU
 		{61DF853D-829A-4426-BEF8-0135586005B6}.Release|x64.Build.0 = Release|Any CPU
+		{61DF853D-829A-4426-BEF8-0135586005B6}.Release|x86.ActiveCfg = Release|Any CPU
+		{61DF853D-829A-4426-BEF8-0135586005B6}.Release|x86.Build.0 = Release|Any CPU
 		{AA30059E-7269-415C-9DF2-55C310DD5548}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{AA30059E-7269-415C-9DF2-55C310DD5548}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{AA30059E-7269-415C-9DF2-55C310DD5548}.Debug|x64.ActiveCfg = Debug|Any CPU
 		{AA30059E-7269-415C-9DF2-55C310DD5548}.Debug|x64.Build.0 = Debug|Any CPU
+		{AA30059E-7269-415C-9DF2-55C310DD5548}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{AA30059E-7269-415C-9DF2-55C310DD5548}.Debug|x86.Build.0 = Debug|Any CPU
 		{AA30059E-7269-415C-9DF2-55C310DD5548}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{AA30059E-7269-415C-9DF2-55C310DD5548}.Release|Any CPU.Build.0 = Release|Any CPU
 		{AA30059E-7269-415C-9DF2-55C310DD5548}.Release|x64.ActiveCfg = Release|Any CPU
 		{AA30059E-7269-415C-9DF2-55C310DD5548}.Release|x64.Build.0 = Release|Any CPU
+		{AA30059E-7269-415C-9DF2-55C310DD5548}.Release|x86.ActiveCfg = Release|Any CPU
+		{AA30059E-7269-415C-9DF2-55C310DD5548}.Release|x86.Build.0 = Release|Any CPU
 		{3068124E-F12B-473E-99A0-2DA5A0385D05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{3068124E-F12B-473E-99A0-2DA5A0385D05}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{3068124E-F12B-473E-99A0-2DA5A0385D05}.Debug|x64.ActiveCfg = Debug|Any CPU
 		{3068124E-F12B-473E-99A0-2DA5A0385D05}.Debug|x64.Build.0 = Debug|Any CPU
+		{3068124E-F12B-473E-99A0-2DA5A0385D05}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{3068124E-F12B-473E-99A0-2DA5A0385D05}.Debug|x86.Build.0 = Debug|Any CPU
 		{3068124E-F12B-473E-99A0-2DA5A0385D05}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{3068124E-F12B-473E-99A0-2DA5A0385D05}.Release|Any CPU.Build.0 = Release|Any CPU
 		{3068124E-F12B-473E-99A0-2DA5A0385D05}.Release|x64.ActiveCfg = Release|Any CPU
 		{3068124E-F12B-473E-99A0-2DA5A0385D05}.Release|x64.Build.0 = Release|Any CPU
+		{3068124E-F12B-473E-99A0-2DA5A0385D05}.Release|x86.ActiveCfg = Release|Any CPU
+		{3068124E-F12B-473E-99A0-2DA5A0385D05}.Release|x86.Build.0 = Release|Any CPU
 		{76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Debug|x64.ActiveCfg = Debug|Any CPU
 		{76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Debug|x64.Build.0 = Debug|Any CPU
+		{76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Debug|x86.Build.0 = Debug|Any CPU
 		{76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Release|Any CPU.Build.0 = Release|Any CPU
 		{76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Release|x64.ActiveCfg = Release|Any CPU
 		{76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Release|x64.Build.0 = Release|Any CPU
+		{76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Release|x86.ActiveCfg = Release|Any CPU
+		{76CE4D21-702C-416F-95B4-F4F4C5B2D162}.Release|x86.Build.0 = Release|Any CPU
+		{34FFBAFE-478F-4B6E-95E7-92A949011A9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{34FFBAFE-478F-4B6E-95E7-92A949011A9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{34FFBAFE-478F-4B6E-95E7-92A949011A9B}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{34FFBAFE-478F-4B6E-95E7-92A949011A9B}.Debug|x64.Build.0 = Debug|Any CPU
+		{34FFBAFE-478F-4B6E-95E7-92A949011A9B}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{34FFBAFE-478F-4B6E-95E7-92A949011A9B}.Debug|x86.Build.0 = Debug|Any CPU
+		{34FFBAFE-478F-4B6E-95E7-92A949011A9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{34FFBAFE-478F-4B6E-95E7-92A949011A9B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{34FFBAFE-478F-4B6E-95E7-92A949011A9B}.Release|x64.ActiveCfg = Release|Any CPU
+		{34FFBAFE-478F-4B6E-95E7-92A949011A9B}.Release|x64.Build.0 = Release|Any CPU
+		{34FFBAFE-478F-4B6E-95E7-92A949011A9B}.Release|x86.ActiveCfg = Release|Any CPU
+		{34FFBAFE-478F-4B6E-95E7-92A949011A9B}.Release|x86.Build.0 = Release|Any CPU
+		{2BDDB984-199B-4913-96BB-39C252E101F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2BDDB984-199B-4913-96BB-39C252E101F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2BDDB984-199B-4913-96BB-39C252E101F2}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{2BDDB984-199B-4913-96BB-39C252E101F2}.Debug|x64.Build.0 = Debug|Any CPU
+		{2BDDB984-199B-4913-96BB-39C252E101F2}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{2BDDB984-199B-4913-96BB-39C252E101F2}.Debug|x86.Build.0 = Debug|Any CPU
+		{2BDDB984-199B-4913-96BB-39C252E101F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2BDDB984-199B-4913-96BB-39C252E101F2}.Release|Any CPU.Build.0 = Release|Any CPU
+		{2BDDB984-199B-4913-96BB-39C252E101F2}.Release|x64.ActiveCfg = Release|Any CPU
+		{2BDDB984-199B-4913-96BB-39C252E101F2}.Release|x64.Build.0 = Release|Any CPU
+		{2BDDB984-199B-4913-96BB-39C252E101F2}.Release|x86.ActiveCfg = Release|Any CPU
+		{2BDDB984-199B-4913-96BB-39C252E101F2}.Release|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -403,6 +585,7 @@
 		{6D0AAB08-0F3E-48CE-B755-9D29BC8F1225} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
 		{D59E25D1-9B27-46A1-8438-92661DD23FAE} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
 		{F8B8B6B6-821B-4FF6-B556-9CAB840EA57A} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
+		{34FFBAFE-478F-4B6E-95E7-92A949011A9B} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {784CEA1D-A890-4625-B0C1-72294A6B4803}

--
Gitblit v1.9.1