alielie
2025-10-10 15bbd62b0b24b72c717ae91ab45348a2083ad04e
优化bug;
50个文件已修改
25个文件已添加
3946 ■■■■■ 已修改文件
ConsoleTest/App.config 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleTest/ConsoleTest.csproj 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleTest/Program.cs 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleTest/Properties/AssemblyInfo.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.AlermInfoManage/AlarmInfoManage.xaml.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.Core/Entity/ParameterData.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.Core/HMI.Core.csproj 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.DataViewer/DataViewer.xaml.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.LogViewer/LogViewer.xaml 270 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.LogViewer/LogViewer.xaml.cs 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.LogViewer/Properties/AssemblyInfo.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/Model/XmlModel.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/ParameterManage.xaml 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/ParameterManage.xaml.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/ParameterModal.xaml 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/ParameterModal.xaml.cs 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/ParameterSetting.xaml 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/ParameterSetting.xaml.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/ProductModal.xaml 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/ProductModal.xaml.cs 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/Properties/AssemblyInfo.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/SettingModal.xaml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/SettingModal.xaml.cs 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.UI/Converter/IndentConverter.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.UI/DpUtil/FormGroupHelper.cs 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.DataBoard/DataBoard.xaml.cs 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.DataBoard/Libs/Static/test.html 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.DataBoard/Plugin.DataBoard.csproj 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.DataBoard/Properties/AssemblyInfo.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.DataBoard/SerialData.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.DataBoard/SimpleData.cs 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.SeqEditor/AssemblyInfo.cs 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.SeqEditor/Constant/StepTypeStr.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.SeqEditor/Entity/EditablePO/ViCallEPO.cs 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.SeqEditor/Entity/SeqUI.cs 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.SeqEditor/Entity/StepUI.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.SeqEditor/Plugin.SeqEditor.csproj 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.SeqEditor/RowNumberConverter.cs 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.SeqEditor/SeqEditor.xaml 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.SeqEditor/SeqEditor.xaml.cs 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.SeqEditor/SettingPanel/CallSeqPanel.xaml 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.SeqEditor/SettingPanel/CallSeqPanel.xaml.cs 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.SeqEditor/SettingPanel/ViPanel.xaml 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.SeqEditor/SettingPanel/ViPanel.xaml.cs 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.SeqEditor/Util/Step2EPO.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.SeqEditor/ViewModel/SeqEditorViewModel.cs 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TestResult/Plugin.TestResult.csproj 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TestResult/ViewControl.xaml.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TsExecution/Plugin.TsExecution.csproj 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TsExecution/Properties/AssemblyInfo.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TsExecution/SingleControl.xaml 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TsExecution/SingleControl.xaml.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TsExecution/TsExecution.xaml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TsExecution/TsExecution.xaml.cs 263 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/DIOController/DIOController.csproj 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/DIOController/DIOControllerCreator.cs 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/DIOController/Dask.cs 803 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/DIOController/DaskHelper.cs 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/DIOController/IDIOController.cs 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/DIOController/IniFileHelper.cs 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/DIOController/ModBusTcpController.cs 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/DIOController/PCI-Dask64.dll 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/DIOController/PCIController.cs 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/DIOController/Properties/AssemblyInfo.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/DIOController/template.ini 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/HMI.Simple.Util/AlarmUtil.cs 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/HMI.Simple.Util/HMI.Simple.Util.csproj 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/HMI.Simple.Util/MSMQHelper.cs 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/HMI.Simple.Util/Parameter.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/HMI.Simple.Util/ParameterUtil.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/HMI.Simple.Util/ProductUtil.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/HMI.Simple.Util/Properties/AssemblyInfo.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SimpleUtil/HMI.Simple.Util/SerialDataHelper.cs 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/WPFProject.csproj 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/WPFProject.sln 191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleTest/App.config
New file
@@ -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>
ConsoleTest/ConsoleTest.csproj
New file
@@ -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>
ConsoleTest/Program.cs
New file
@@ -0,0 +1,57 @@
using 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;
        }
    }
}
ConsoleTest/Properties/AssemblyInfo.cs
New file
@@ -0,0 +1,33 @@
using 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")]
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);
                if (AlarmShowHelper.ShowAlarm(alarm.AlarmInfo))
                {
                sqliteHelper.ExecuteSql(sqladd2);
                //Dispatcher.BeginInvoke(new Action(() =>
                //{
                //    Datasource.Add(alarm);
                //}));
                }
            }
            this.currentAlarmCachePc.Clear();
        }
HMI.Core/Entity/ParameterData.cs
@@ -1,4 +1,6 @@
namespace HMI.Core.Entity
using 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
            {
            }
        }
    }
}
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>
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;
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>
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);
                using (SqliteHelper sql = new SqliteHelper(file))
                {
                dt.Merge(sql.GetDataTable(str));
                sql.Close();
            }
            }
            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,18 +248,22 @@
        /// </summary>
        private void Refresh100items()
        {
            autoRfhTimer.Enabled = false;
            Task.Run(() =>
            {
            try
            {
                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);
                    using (SqliteHelper sql = new SqliteHelper(todayLogFile))
                    {
                var dt = sql.GetDataTable(str);
                this.Dispatcher.BeginInvoke((Action)delegate ()
                {
                    table.ItemsSource = dt.DefaultView;
                });
                    }
            }
            catch (Exception ex)
            {
@@ -243,8 +272,12 @@
            }
            finally
            {
                    this.Dispatcher.BeginInvoke((Action)delegate ()
                    {
                autoRfhTimer.Enabled = AutoRfh;
                    });
            }
            });
        }
    }
}
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")]
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
    }
}
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>
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();
            }
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}" 
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;
            }
        }
    }
}
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>
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)
                    {
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>
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();
        }
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")]
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}" 
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;
            }
        }
    }
}
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)
HMI.UI/DpUtil/FormGroupHelper.cs
@@ -1,5 +1,6 @@
using 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 value;
                    if (values != null && values.ContainsKey(fgName))
                    {
                        value = values[fgName];
                    }
                    else
                    {
                    object content = fg.Content;
                    object value = GetValidateValue(content);
                        value = GetValidateValue(content);
                    }
                    if (GetIsRequired(fg) && (value == null || string.IsNullOrEmpty(value.ToString())))
                    {
                        fg.ValidateResult = ValidateResult.Error;
Plugin.DataBoard/DataBoard.xaml.cs
@@ -1,5 +1,6 @@
using 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,6 +139,8 @@
        private void RefreshChart0(DateTime start, DateTime end)
        {
            try
            {
            dtp00.SelectedDateTime = start;
            dtp01.SelectedDateTime = end;
            List<SerialData> datas = SelectSerialDataByTime(start, end);
@@ -136,28 +159,44 @@
            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)
        {
            try
            {
            dtp10.SelectedDateTime = start;
            dtp11.SelectedDateTime = end;
            List<SerialData> datas = SelectSerialDataByTime(start, end);
                List<SerialData> datas = SelectResultDataByTime(start, end);
            datas = datas.OrderByDescending(e => e.time).ToList();
            Dictionary<string, int> pieData = new Dictionary<string, int> {
                Dictionary<string, int?> pieData = new Dictionary<string, int?> {
                { "Passed",0},
                { "Failed",0},
                { "Action",0},
                { "Wait",0},
                //{ "Action",0},
                //{ "Wait",0},
            };
                //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)
            {
                if (snCache.Contains(data.sn)) continue;
                snCache.Add(data.sn);
                if (pieData.ContainsKey(data.status))
                    if (pieData.ContainsKey(data.result))
                {
                    pieData[data.status]++;
                        pieData[data.result]++;
                }
            }
            string res = "[";
@@ -168,12 +207,86 @@
            res += "]";
            webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart1({res})");
        }
            catch (Exception ex)
            {
                log.Error("RefreshChart1 Error.", ex);
                ToastHelper.Error("表2刷新失败!");
            }
        }
        //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)
        {
            try
            {
            dtp20.SelectedDateTime = start;
            dtp21.SelectedDateTime = end;
            List<SerialData> datas = SelectSerialDataByTime(start, end);
                List<SerialData> datas = SelectResultDataByTime(start, end);
            var groups =
                datas.GroupBy(d => d.time.ToString("yyyy-MM-dd"));
@@ -185,30 +298,27 @@
                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();
                    groupDatas = groupDatas.OrderByDescending(e => e.time).ToList();
                foreach (var data in groupDatas)
                {
                    if (snStatusCache.ContainsKey(data.sn))
                        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
                    {
                            snStatusCache.Add(data.sn, data.result);
                        all++;
                        if (data.status == "Passed")
                            if (data.result == "Passed")
                        {
                            passed++;
                            oneTimePass++;
                        }
                        snStatusCache.Add(data.sn, data.status);
                        }
                        else
                        {
                            if (snStatusCache[data.sn] == "Passed")
                            {
                                if (oneTimePass > 0) oneTimePass--;
                                snStatusCache[data.sn] = "NoOnePass";
                            }
                    }
                }
                res.Add(group.Key, new PassRateData
@@ -234,41 +344,68 @@
            var names = $"['{this.lang("bd.onePassRate")}','{this.lang("bd.passRate")}']";
            webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart2({fields},{names},{vals0},{vals1})");
        }
            catch (Exception ex)
            {
                log.Error("RefreshChart2 Error.", ex);
                ToastHelper.Error("表3刷新失败!");
            }
        }
        private void RefreshChart3(DateTime start, DateTime end)
        {
            try
        {
            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>();
                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)
            {
                //if (snCache.Contains(data.sn)) continue;
                if (data.status != "Failed") continue;
                snCache.Add(data.sn);
                if (pieData.ContainsKey(data.step))
                {
                    pieData[data.step]++;
                        pieData[data.step].Value++;
                }
                else
                {
                    pieData[data.step] = 1;
                }
            }
            string names = string.Empty, vals = string.Empty;
            foreach (var key in pieData.Keys)
                        pieData[data.step] = new SimpleData
            {
                names += $"'{key}',";
                vals += $"{pieData[key]},";
                            Name = data.step,
                            Value = 1
                        };
                        datasource.Add(pieData[data.step]);
                    }
                }
                datasource = datasource.OrderByDescending(e => e.Value).ToList();
                if (datasource.Count > 10)
                {
                    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}])");
        }
            catch (Exception ex)
            {
                log.Error("RefreshChart3 Error.", ex);
                ToastHelper.Error("表4刷新失败!");
            }
        }
        private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
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);
        }
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>
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")]
Plugin.DataBoard/SerialData.cs
@@ -1,16 +1,14 @@
using 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; }
    }
Plugin.DataBoard/SimpleData.cs
New file
@@ -0,0 +1,8 @@
namespace Plugin.DataBoard
{
    public class SimpleData
    {
        public string Name { get; set; }
        public int Value { get; set; }
    }
}
Plugin.SeqEditor/AssemblyInfo.cs
@@ -1,3 +1,4 @@
using System.Reflection;
using System.Windows;
[assembly:ThemeInfo(
Plugin.SeqEditor/Constant/StepTypeStr.cs
@@ -21,4 +21,9 @@
    }
    public abstract class AdapterName
    {
        public const string VICall = "G Flexible VI Adapter";
    }
}
Plugin.SeqEditor/Entity/EditablePO/ViCallEPO.cs
New file
@@ -0,0 +1,36 @@
using 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)
                {
                }
            }
        }
    }
}
Plugin.SeqEditor/Entity/SeqUI.cs
@@ -15,6 +15,7 @@
        }
        public Sequence sequence { get; private set; }
        public SeqUI(Sequence sequence)
        {
            this.sequence = sequence;
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;
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" />
Plugin.SeqEditor/RowNumberConverter.cs
New file
@@ -0,0 +1,36 @@
using 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;
        }
    }
}
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">
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;
@@ -84,5 +87,57 @@
        //    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 ? "一键收起" : "一键展开";
    }
}
Plugin.SeqEditor/SettingPanel/CallSeqPanel.xaml
New file
@@ -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>
Plugin.SeqEditor/SettingPanel/CallSeqPanel.xaml.cs
New file
@@ -0,0 +1,39 @@
using 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;
        }
    }
}
Plugin.SeqEditor/SettingPanel/ViPanel.xaml
New file
@@ -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>
Plugin.SeqEditor/SettingPanel/ViPanel.xaml.cs
New file
@@ -0,0 +1,20 @@
using 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;
        }
    }
}
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);
            }
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);
                // 不加延时会弹窗md
                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)
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>
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;
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>
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")]
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>
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);
                }));
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}"/>
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("DefaultEnableMes");
                if (value != null)
                {
                    flag = bool.Parse(value.Value);
                }
            }
            catch
            {
                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");
                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");
                if (value == null)
                {
                    CbEnableSimpleMode.Visibility = Visibility.Collapsed;
                }
                else
                {
                EnableSimpleMode = bool.Parse(value.Value);
                }
            }
            catch
            {
@@ -632,7 +780,14 @@
            try
            {
                value = ParameterManager.GetCommonParameterByName("UI_ShowInfoDock");
                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();
            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,8 +1406,15 @@
            {
                lock (this)
                {
                    //execution.Abort();
                    int count = 10;
                    while (count > 0)
                    {
                        try
                        {
                    if (this.testSeq == null)
                        return true;
                    if (this.engine.ReleaseSequenceFileEx(this.testSeq, 4))
                    {
                        this.testSeq = null;
@@ -1249,7 +1424,17 @@
                        this.modeSeq = null;
                    }
                    this.engine.UnloadAllModules();
                    return true;
                            return this.testSeq == null && this.modeSeq == null;
                        }
                        catch (Exception ex)
                        {
                            log.Warn($"ReleaseSequenceFile In {count} Times Fail.", ex);
                            count--;
                            System.Threading.Thread.Sleep(1000);
                        }
                    }
                    log.Warn($"ReleaseSequenceFile Failed.");
                    return false;
                }
            }
            catch (Exception ex)
SimpleUtil/DIOController/DIOController.csproj
New file
@@ -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带源码demo\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>
SimpleUtil/DIOController/DIOControllerCreator.cs
New file
@@ -0,0 +1,31 @@
using 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("无效的控制器类型");
            }
        }
    }
}
SimpleUtil/DIOController/Dask.cs
New file
@@ -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);
    }
}
SimpleUtil/DIOController/DaskHelper.cs
New file
@@ -0,0 +1,132 @@
namespace 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;
        }
    }
}
SimpleUtil/DIOController/IDIOController.cs
New file
@@ -0,0 +1,20 @@
using 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();
    }
}
SimpleUtil/DIOController/IniFileHelper.cs
New file
@@ -0,0 +1,94 @@
using 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);
        //需要调用GetPrivateProfileString的重载
        [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 读Ini文件
        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 写Ini文件
        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
    }
}
SimpleUtil/DIOController/ModBusTcpController.cs
New file
@@ -0,0 +1,79 @@
using 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();
        }
    }
}
SimpleUtil/DIOController/PCI-Dask64.dll
Binary files differ
SimpleUtil/DIOController/PCIController.cs
New file
@@ -0,0 +1,66 @@
using 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();
        }
    }
}
SimpleUtil/DIOController/Properties/AssemblyInfo.cs
New file
@@ -0,0 +1,33 @@
using 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")]
SimpleUtil/DIOController/template.ini
New file
@@ -0,0 +1,9 @@

[Config]
;可选项 ModbusTcp,PCI_7432
Type=ModbusTcp
;Modbus参数
Ip=127.0.0.1
Port=502
;7432参数
Name=PCI_7432
SimpleUtil/HMI.Simple.Util/AlarmUtil.cs
New file
@@ -0,0 +1,25 @@
using 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;
            }
        }
    }
}
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" />
SimpleUtil/HMI.Simple.Util/MSMQHelper.cs
New file
@@ -0,0 +1,139 @@
using 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();
        }
    }
}
SimpleUtil/HMI.Simple.Util/Parameter.cs
@@ -1,6 +1,6 @@
namespace HMI.Simple.Util
{
    internal class ParameterData
    public class ParameterData
    {
        public string Id { get; set; }
        public string Name { get; set; }
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")
            {
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)
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")]
SimpleUtil/HMI.Simple.Util/SerialDataHelper.cs
New file
@@ -0,0 +1,117 @@
using 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();
            }
        }
    }
}
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>
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}