初始化提交
仓库转移到Gitea,初始化提交,可能丢失以前的git版本日志
This commit is contained in:
167
AUTS_DataService/AUTS_DataService.vbproj
Normal file
167
AUTS_DataService/AUTS_DataService.vbproj
Normal file
@@ -0,0 +1,167 @@
|
||||
<?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>{163446E7-7512-4ECE-819D-AF1A139E3DFB}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<StartupObject>AUTS_DataService.Service1</StartupObject>
|
||||
<RootNamespace>AUTS_DataService</RootNamespace>
|
||||
<AssemblyName>AUTS_DataService</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<MyType>Console</MyType>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<DefineDebug>true</DefineDebug>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DocumentationFile>AUTS_DataService.xml</DocumentationFile>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DefineDebug>false</DefineDebug>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DocumentationFile>AUTS_DataService.xml</DocumentationFile>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionExplicit>On</OptionExplicit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionCompare>Binary</OptionCompare>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionStrict>On</OptionStrict>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionInfer>Off</OptionInfer>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="FluentFTP">
|
||||
<HintPath>..\packages\FluentFTP.33.0.3\lib\net45\FluentFTP.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Data, Version=8.0.26.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\UTS_Core\bin\Debug\MySql.Data.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\UTS_Core\bin\Debug\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration.Install" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Import Include="Microsoft.VisualBasic" />
|
||||
<Import Include="System" />
|
||||
<Import Include="System.Collections" />
|
||||
<Import Include="System.Collections.Generic" />
|
||||
<Import Include="System.Data" />
|
||||
<Import Include="System.Diagnostics" />
|
||||
<Import Include="System.Linq" />
|
||||
<Import Include="System.Xml.Linq" />
|
||||
<Import Include="System.Threading.Tasks" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ServiceError.vb" />
|
||||
<Compile Include="UtsGroup\ServiceGroup.vb" />
|
||||
<Compile Include="ServiceLog.vb" />
|
||||
<Compile Include="ServiceConfig.vb" />
|
||||
<Compile Include="ServiceTask\ServiceTasks.vb" />
|
||||
<Compile Include="UtsApp\UtsApp.vb" />
|
||||
<Compile Include="UtsApp\UtsAppManager.vb" />
|
||||
<Compile Include="UtsGroup\ServiceGroupManager.vb" />
|
||||
<Compile Include="UtsWeb\CheckSum.vb" />
|
||||
<Compile Include="ServiceTask\DbSynchronizer.vb" />
|
||||
<Compile Include="ServiceTask\DbSyncServiceTask.vb" />
|
||||
<Compile Include="UtsWeb\IDataPacket.vb" />
|
||||
<Compile Include="ServiceTask\JsonFileListen.vb" />
|
||||
<Compile Include="ServiceTask\ListenJsonFileServiceTask.vb" />
|
||||
<Compile Include="My Project\Application.Designer.vb">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Application.myapp</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<Compile Include="ProjectInstaller.Designer.vb">
|
||||
<DependentUpon>ProjectInstaller.vb</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ProjectInstaller.vb">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Service1.vb">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Service1.Designer.vb">
|
||||
<DependentUpon>Service1.vb</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="My Project\AssemblyInfo.vb" />
|
||||
<Compile Include="My Project\Resources.Designer.vb">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="My Project\Settings.Designer.vb">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<Compile Include="ServiceSettings.vb" />
|
||||
<Compile Include="UtsWeb\UtsWebPacket.vb" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="My Project\Resources.resx">
|
||||
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
|
||||
<CustomToolNamespace>My.Resources</CustomToolNamespace>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="ProjectInstaller.resx">
|
||||
<DependentUpon>ProjectInstaller.vb</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="My Project\Application.myapp">
|
||||
<Generator>MyApplicationCodeGenerator</Generator>
|
||||
<LastGenOutput>Application.Designer.vb</LastGenOutput>
|
||||
</None>
|
||||
<None Include="My Project\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<CustomToolNamespace>My</CustomToolNamespace>
|
||||
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
|
||||
</None>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\UTS_Core\UTS_Core.vbproj">
|
||||
<Project>{33C6456C-F00D-41AC-A6FB-DB0601495C6A}</Project>
|
||||
<Name>UTS_Core</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||
</Project>
|
||||
42
AUTS_DataService/App.config
Normal file
42
AUTS_DataService/App.config
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<section name="AUTS_DataService.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
|
||||
</startup>
|
||||
<userSettings>
|
||||
<AUTS_DataService.My.MySettings>
|
||||
<setting name="dbLogType" serializeAs="String">
|
||||
<value>30</value>
|
||||
</setting>
|
||||
</AUTS_DataService.My.MySettings>
|
||||
</userSettings>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Google.Protobuf" publicKeyToken="a7d26565bac4d604" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.30.1.0" newVersion="3.30.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="BouncyCastle.Crypto" publicKeyToken="0e99375e54769942" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.8.5.0" newVersion="1.8.5.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.4.0" newVersion="4.0.4.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
13
AUTS_DataService/My Project/Application.Designer.vb
generated
Normal file
13
AUTS_DataService/My Project/Application.Designer.vb
generated
Normal file
@@ -0,0 +1,13 @@
|
||||
'------------------------------------------------------------------------------
|
||||
' <auto-generated>
|
||||
' 此代码由工具生成。
|
||||
' 运行时版本:4.0.30319.42000
|
||||
'
|
||||
' 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
' 重新生成代码,这些更改将会丢失。
|
||||
' </auto-generated>
|
||||
'------------------------------------------------------------------------------
|
||||
|
||||
Option Strict On
|
||||
Option Explicit On
|
||||
|
||||
10
AUTS_DataService/My Project/Application.myapp
Normal file
10
AUTS_DataService/My Project/Application.myapp
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<MySubMain>false</MySubMain>
|
||||
<SingleInstance>false</SingleInstance>
|
||||
<ShutdownMode>0</ShutdownMode>
|
||||
<EnableVisualStyles>true</EnableVisualStyles>
|
||||
<AuthenticationMode>0</AuthenticationMode>
|
||||
<ApplicationType>3</ApplicationType>
|
||||
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
|
||||
</MyApplicationData>
|
||||
35
AUTS_DataService/My Project/AssemblyInfo.vb
Normal file
35
AUTS_DataService/My Project/AssemblyInfo.vb
Normal file
@@ -0,0 +1,35 @@
|
||||
Imports System
|
||||
Imports System.Reflection
|
||||
Imports System.Runtime.InteropServices
|
||||
|
||||
' 有关程序集的一般信息由以下
|
||||
' 控制。更改这些特性值可修改
|
||||
' 与程序集关联的信息。
|
||||
|
||||
'查看程序集特性的值
|
||||
|
||||
<Assembly: AssemblyTitle("AUTS_DataService")>
|
||||
<Assembly: AssemblyDescription("")>
|
||||
<Assembly: AssemblyCompany("Microsoft")>
|
||||
<Assembly: AssemblyProduct("AUTS_DataService")>
|
||||
<Assembly: AssemblyCopyright("Copyright © Microsoft 2020")>
|
||||
<Assembly: AssemblyTrademark("")>
|
||||
|
||||
<Assembly: ComVisible(False)>
|
||||
|
||||
'如果此项目向 COM 公开,则下列 GUID 用于 typelib 的 ID
|
||||
<Assembly: Guid("ce81e273-2959-4d63-90b0-54545ed20a06")>
|
||||
|
||||
' 程序集的版本信息由下列四个值组成:
|
||||
'
|
||||
' 主版本
|
||||
' 次版本
|
||||
' 生成号
|
||||
' 修订号
|
||||
'
|
||||
'可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
|
||||
'通过使用 "*",如下所示:
|
||||
' <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
<Assembly: AssemblyVersion("2.6.0.1")>
|
||||
<Assembly: AssemblyFileVersion("2.6.0.1")>
|
||||
63
AUTS_DataService/My Project/Resources.Designer.vb
generated
Normal file
63
AUTS_DataService/My Project/Resources.Designer.vb
generated
Normal file
@@ -0,0 +1,63 @@
|
||||
'------------------------------------------------------------------------------
|
||||
' <auto-generated>
|
||||
' 此代码由工具生成。
|
||||
' 运行时版本:4.0.30319.42000
|
||||
'
|
||||
' 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
' 重新生成代码,这些更改将会丢失。
|
||||
' </auto-generated>
|
||||
'------------------------------------------------------------------------------
|
||||
|
||||
Option Strict On
|
||||
Option Explicit On
|
||||
|
||||
Imports System
|
||||
|
||||
Namespace My.Resources
|
||||
|
||||
'此类是由 StronglyTypedResourceBuilder
|
||||
'类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||
'若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||
'(以 /str 作为命令选项),或重新生成 VS 项目。
|
||||
'''<summary>
|
||||
''' 一个强类型的资源类,用于查找本地化的字符串等。
|
||||
'''</summary>
|
||||
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0"), _
|
||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
|
||||
Friend Module Resources
|
||||
|
||||
Private resourceMan As Global.System.Resources.ResourceManager
|
||||
|
||||
Private resourceCulture As Global.System.Globalization.CultureInfo
|
||||
|
||||
'''<summary>
|
||||
''' 返回此类使用的缓存的 ResourceManager 实例。
|
||||
'''</summary>
|
||||
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
|
||||
Get
|
||||
If Object.ReferenceEquals(resourceMan, Nothing) Then
|
||||
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("AUTS_DataService.Resources", GetType(Resources).Assembly)
|
||||
resourceMan = temp
|
||||
End If
|
||||
Return resourceMan
|
||||
End Get
|
||||
End Property
|
||||
|
||||
'''<summary>
|
||||
''' 重写当前线程的 CurrentUICulture 属性,对
|
||||
''' 使用此强类型资源类的所有资源查找执行重写。
|
||||
'''</summary>
|
||||
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Friend Property Culture() As Global.System.Globalization.CultureInfo
|
||||
Get
|
||||
Return resourceCulture
|
||||
End Get
|
||||
Set
|
||||
resourceCulture = value
|
||||
End Set
|
||||
End Property
|
||||
End Module
|
||||
End Namespace
|
||||
117
AUTS_DataService/My Project/Resources.resx
Normal file
117
AUTS_DataService/My Project/Resources.resx
Normal file
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
85
AUTS_DataService/My Project/Settings.Designer.vb
generated
Normal file
85
AUTS_DataService/My Project/Settings.Designer.vb
generated
Normal file
@@ -0,0 +1,85 @@
|
||||
'------------------------------------------------------------------------------
|
||||
' <auto-generated>
|
||||
' 此代码由工具生成。
|
||||
' 运行时版本:4.0.30319.42000
|
||||
'
|
||||
' 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
' 重新生成代码,这些更改将会丢失。
|
||||
' </auto-generated>
|
||||
'------------------------------------------------------------------------------
|
||||
|
||||
Option Strict On
|
||||
Option Explicit On
|
||||
|
||||
|
||||
Namespace My
|
||||
|
||||
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0"), _
|
||||
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Partial Friend NotInheritable Class MySettings
|
||||
Inherits Global.System.Configuration.ApplicationSettingsBase
|
||||
|
||||
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
|
||||
|
||||
#Region "My.Settings 自动保存功能"
|
||||
#If _MyType = "WindowsForms" Then
|
||||
Private Shared addedHandler As Boolean
|
||||
|
||||
Private Shared addedHandlerLockObject As New Object
|
||||
|
||||
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Private Shared Sub AutoSaveSettings(sender As Global.System.Object, e As Global.System.EventArgs)
|
||||
If My.Application.SaveMySettingsOnExit Then
|
||||
My.Settings.Save()
|
||||
End If
|
||||
End Sub
|
||||
#End If
|
||||
#End Region
|
||||
|
||||
Public Shared ReadOnly Property [Default]() As MySettings
|
||||
Get
|
||||
|
||||
#If _MyType = "WindowsForms" Then
|
||||
If Not addedHandler Then
|
||||
SyncLock addedHandlerLockObject
|
||||
If Not addedHandler Then
|
||||
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
|
||||
addedHandler = True
|
||||
End If
|
||||
End SyncLock
|
||||
End If
|
||||
#End If
|
||||
Return defaultInstance
|
||||
End Get
|
||||
End Property
|
||||
|
||||
<Global.System.Configuration.UserScopedSettingAttribute(), _
|
||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||
Global.System.Configuration.DefaultSettingValueAttribute("30")> _
|
||||
Public Property dbLogType() As Byte
|
||||
Get
|
||||
Return CType(Me("dbLogType"),Byte)
|
||||
End Get
|
||||
Set
|
||||
Me("dbLogType") = value
|
||||
End Set
|
||||
End Property
|
||||
End Class
|
||||
End Namespace
|
||||
|
||||
Namespace My
|
||||
|
||||
<Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
|
||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
|
||||
Friend Module MySettingsProperty
|
||||
|
||||
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
|
||||
Friend ReadOnly Property Settings() As Global.AUTS_DataService.My.MySettings
|
||||
Get
|
||||
Return Global.AUTS_DataService.My.MySettings.Default
|
||||
End Get
|
||||
End Property
|
||||
End Module
|
||||
End Namespace
|
||||
9
AUTS_DataService/My Project/Settings.settings
Normal file
9
AUTS_DataService/My Project/Settings.settings
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="My" GeneratedClassName="MySettings" UseMySettingsClassName="true">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="dbLogType" Type="System.Byte" Scope="User">
|
||||
<Value Profile="(Default)">30</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
47
AUTS_DataService/ProjectInstaller.Designer.vb
generated
Normal file
47
AUTS_DataService/ProjectInstaller.Designer.vb
generated
Normal file
@@ -0,0 +1,47 @@
|
||||
<System.ComponentModel.RunInstaller(True)> Partial Class ProjectInstaller
|
||||
Inherits System.Configuration.Install.Installer
|
||||
|
||||
'Installer 重写 Dispose,以清理组件列表。
|
||||
<System.Diagnostics.DebuggerNonUserCode()> _
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
Try
|
||||
If disposing AndAlso components IsNot Nothing Then
|
||||
components.Dispose()
|
||||
End If
|
||||
Finally
|
||||
MyBase.Dispose(disposing)
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
'组件设计器所必需的
|
||||
Private components As System.ComponentModel.IContainer
|
||||
|
||||
'注意: 以下过程是组件设计器所必需的
|
||||
'可使用组件设计器修改它。
|
||||
'不要使用代码编辑器修改它。
|
||||
<System.Diagnostics.DebuggerStepThrough()>
|
||||
Private Sub InitializeComponent()
|
||||
Me.ServiceProcessInstaller1 = New System.ServiceProcess.ServiceProcessInstaller()
|
||||
Me.ServiceInstaller1 = New System.ServiceProcess.ServiceInstaller()
|
||||
'
|
||||
'ServiceProcessInstaller1
|
||||
'
|
||||
Me.ServiceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem
|
||||
Me.ServiceProcessInstaller1.Password = Nothing
|
||||
Me.ServiceProcessInstaller1.Username = Nothing
|
||||
'
|
||||
'ServiceInstaller1
|
||||
'
|
||||
Me.ServiceInstaller1.Description = "AUTS_DataService"
|
||||
Me.ServiceInstaller1.DisplayName = "AUTS_DataService"
|
||||
Me.ServiceInstaller1.ServiceName = "AUTS_DataService"
|
||||
Me.ServiceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic
|
||||
'
|
||||
'ProjectInstaller
|
||||
'
|
||||
Me.Installers.AddRange(New System.Configuration.Install.Installer() {Me.ServiceProcessInstaller1, Me.ServiceInstaller1})
|
||||
|
||||
End Sub
|
||||
Private WithEvents ServiceInstaller1 As ServiceProcess.ServiceInstaller
|
||||
Private WithEvents ServiceProcessInstaller1 As ServiceProcess.ServiceProcessInstaller
|
||||
End Class
|
||||
129
AUTS_DataService/ProjectInstaller.resx
Normal file
129
AUTS_DataService/ProjectInstaller.resx
Normal file
@@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="ServiceProcessInstaller1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 56</value>
|
||||
</metadata>
|
||||
<metadata name="ServiceInstaller1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>14, 22</value>
|
||||
</metadata>
|
||||
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
</root>
|
||||
16
AUTS_DataService/ProjectInstaller.vb
Normal file
16
AUTS_DataService/ProjectInstaller.vb
Normal file
@@ -0,0 +1,16 @@
|
||||
Imports System.ComponentModel
|
||||
Imports System.Configuration.Install
|
||||
|
||||
Public Class ProjectInstaller
|
||||
|
||||
Public Sub New()
|
||||
MyBase.New()
|
||||
|
||||
'组件设计器需要此调用。
|
||||
InitializeComponent()
|
||||
|
||||
'调用 InitializeComponent 后添加初始化代码
|
||||
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
48
AUTS_DataService/Service1.Designer.vb
generated
Normal file
48
AUTS_DataService/Service1.Designer.vb
generated
Normal file
@@ -0,0 +1,48 @@
|
||||
Imports System.ServiceProcess
|
||||
|
||||
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
|
||||
Partial Class Service1
|
||||
Inherits System.ServiceProcess.ServiceBase
|
||||
|
||||
'UserService 重写 Dispose,以清理组件列表。
|
||||
<System.Diagnostics.DebuggerNonUserCode()> _
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
Try
|
||||
If disposing AndAlso components IsNot Nothing Then
|
||||
components.Dispose()
|
||||
End If
|
||||
Finally
|
||||
MyBase.Dispose(disposing)
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
' 此进程的主入口点
|
||||
<MTAThread()> _
|
||||
<System.Diagnostics.DebuggerNonUserCode()> _
|
||||
Shared Sub Main()
|
||||
Dim ServicesToRun() As System.ServiceProcess.ServiceBase
|
||||
|
||||
' 同一进程内可运行多个 NT 服务。若要将
|
||||
' 另一个服务添加到此进程中,请更改下行以
|
||||
' 创建另一个服务对象。例如,
|
||||
'
|
||||
' ServicesToRun = New System.ServiceProcess.ServiceBase () {New Service1, New MySecondUserService}
|
||||
'
|
||||
ServicesToRun = New System.ServiceProcess.ServiceBase() {New Service1}
|
||||
|
||||
System.ServiceProcess.ServiceBase.Run(ServicesToRun)
|
||||
End Sub
|
||||
|
||||
'组件设计器所必需的
|
||||
Private components As System.ComponentModel.IContainer
|
||||
|
||||
' 注意: 以下过程是组件设计器所必需的
|
||||
' 可使用组件设计器修改它。
|
||||
'不要使用代码编辑器修改它。
|
||||
<System.Diagnostics.DebuggerStepThrough()> _
|
||||
Private Sub InitializeComponent()
|
||||
components = New System.ComponentModel.Container()
|
||||
Me.ServiceName = "Service1"
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
2233
AUTS_DataService/Service1.vb
Normal file
2233
AUTS_DataService/Service1.vb
Normal file
File diff suppressed because it is too large
Load Diff
294
AUTS_DataService/ServiceConfig.vb
Normal file
294
AUTS_DataService/ServiceConfig.vb
Normal file
@@ -0,0 +1,294 @@
|
||||
Imports System.Management
|
||||
Imports System.Net
|
||||
Imports UTS_Core.Database
|
||||
Imports UTS_Core.UTSModule
|
||||
Imports UTS_Core.UTSModule.DbTableModel.Manage
|
||||
|
||||
Public Class ServiceConfig
|
||||
Private _privateIP As String
|
||||
|
||||
Private _publicIP As String
|
||||
|
||||
Private _mac As String
|
||||
|
||||
Private ReadOnly _dsIndex As Integer
|
||||
|
||||
Private ReadOnly _dsName As String
|
||||
|
||||
Private ReadOnly _dsVerString As String
|
||||
|
||||
Private _usVerString As String
|
||||
|
||||
Private ReadOnly _usName As String
|
||||
|
||||
Private _dsVer As Version
|
||||
|
||||
Private _usVer As Version
|
||||
|
||||
|
||||
Sub New()
|
||||
_dsIndex = CInt(UtsRegistry.DataServiceIndex)
|
||||
_dsName = My.Application.Info.ProductName
|
||||
_dsVer = My.Application.Info.Version
|
||||
_dsVerString = My.Application.Info.Version.ToString
|
||||
_usName = UtsRegistry.UpdateServiceName
|
||||
_usVerString = UtsRegistry.UpdateServiceVersion
|
||||
If Version.TryParse(_usVerString, _usVer) = False Then
|
||||
_usVer = New Version(0, 0, 0, 0)
|
||||
End If
|
||||
|
||||
BarnchNet = UtsRegistry.BarnchNet
|
||||
|
||||
If Integer.TryParse(UtsRegistry.Roles, Roles) = False Then
|
||||
Roles = 0
|
||||
End If
|
||||
|
||||
IsDBProxyConn = 0
|
||||
CacheCount = 0
|
||||
DbStatus = 0
|
||||
FtpStatus = 0
|
||||
NetworkNeiborhood = ""
|
||||
|
||||
UsConnected = 0
|
||||
|
||||
InitMacAndLocalIP()
|
||||
End Sub
|
||||
|
||||
Public ReadOnly Property DsIndex() As Integer
|
||||
Get
|
||||
Return _dsIndex
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' 数据服务的数据服务的名称
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public ReadOnly Property DsName() As String
|
||||
Get
|
||||
Return _dsName
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' 数据服务的版本字符串
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public ReadOnly Property DsVerString() As String
|
||||
Get
|
||||
Return _dsVerString
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' 更新服务的版本字符串
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property UsVerString() As String
|
||||
Get
|
||||
Return _usVerString
|
||||
End Get
|
||||
Set(value As String)
|
||||
_usVerString = value
|
||||
If Version.TryParse(_usVerString, _usVer) = False Then
|
||||
_usVer = New Version(0, 0, 0, 0)
|
||||
End If
|
||||
End Set
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' 数据服务的版本
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public ReadOnly Property DsVersion() As Version
|
||||
Get
|
||||
Return _dsVer
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' 更新服务的版本
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public ReadOnly Property UsVersion() As Version
|
||||
Get
|
||||
Return _usVer
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' 更新服务的名称
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public ReadOnly Property UsName() As String
|
||||
Get
|
||||
Return _usName
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' 设备的局域网IP
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public ReadOnly Property PrivateIP() As String
|
||||
Get
|
||||
Return _privateIP
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' 设备的MAC地址
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public ReadOnly Property Mac() As String
|
||||
Get
|
||||
Return _mac
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' 与更新服务的连接状态
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property UsConnected As Integer
|
||||
|
||||
''' <summary>
|
||||
''' 设备运行中产生的异常
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Private Property ErrMsg As String
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 局域网中与主机的连接状态
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property IsDBProxyConn As Integer
|
||||
|
||||
''' <summary>
|
||||
''' 设备加入的子网名称
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property BarnchNet As String
|
||||
|
||||
''' <summary>
|
||||
''' 当前设备在局域网中的角色
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property Roles As Integer
|
||||
|
||||
''' <summary>
|
||||
''' 网上邻居集合
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property NetworkNeiborhood As String
|
||||
|
||||
''' <summary>
|
||||
''' 当前缓存表字段数量
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property CacheCount As Integer
|
||||
|
||||
''' <summary>
|
||||
''' 云端数据库连接状态
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property DbStatus As Integer
|
||||
|
||||
''' <summary>
|
||||
''' Ftp服务器连接状态
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property FtpStatus As Integer
|
||||
|
||||
''' <summary>
|
||||
''' 私有IP地址变化
|
||||
''' </summary>
|
||||
''' <param name="ip"></param>
|
||||
Public Event PrivateIPChanged(ip As String)
|
||||
|
||||
''' <summary>
|
||||
''' MAC地址变化
|
||||
''' </summary>
|
||||
''' <param name="mac"></param>
|
||||
Public Event MACChanged(mac As String)
|
||||
|
||||
|
||||
Public Sub UpdateErrMsg(type As String, msg As String)
|
||||
ErrMsg = $"{type},{msg}"
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 初始化MAC地址与获取本地IP
|
||||
''' </summary>
|
||||
Public Sub InitMacAndLocalIP()
|
||||
' Dim ip As String
|
||||
Dim mac As String
|
||||
Dim searcher As New ManagementObjectSearcher("select * from win32_NetworkAdapterConfiguration")
|
||||
Dim moc2 As ManagementObjectCollection = searcher.Get()
|
||||
For Each mo As ManagementObject In moc2
|
||||
If CBool(mo("IPEnabled")) Then
|
||||
mac = mo("MACAddress").ToString()
|
||||
If String.Compare(_mac, mac) <> 0 Then
|
||||
_mac = mac
|
||||
'触发MAC地址变化
|
||||
RaiseEvent MACChanged(_mac)
|
||||
End If
|
||||
|
||||
Dim a() As String = CType(mo("IpAddress"), String())
|
||||
|
||||
Dim address As IPAddress = Nothing
|
||||
For Each ip As String In a
|
||||
If IPAddress.TryParse(ip, address) Then
|
||||
|
||||
'使用IPV4地址
|
||||
If address.AddressFamily = Sockets.AddressFamily.InterNetwork Then
|
||||
|
||||
If String.Compare(_privateIP, ip) <> 0 Then
|
||||
'触发IP地址变化
|
||||
_privateIP = ip
|
||||
RaiseEvent PrivateIPChanged(_privateIP)
|
||||
End If
|
||||
|
||||
Return
|
||||
End If
|
||||
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
Next
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 上传服务信息至数据库
|
||||
''' </summary>
|
||||
Public Sub UpdateServiceInfo()
|
||||
Using db As New DbExecutor(UtsDb.RemoteDbType, UtsDb.RemoteConnString)
|
||||
db.Open()
|
||||
|
||||
Dim cmdText As String
|
||||
Dim tbName As String = DataServiceListTable.TableName
|
||||
Dim filed As New Dictionary(Of String, String)
|
||||
filed.Add($"{DataServiceListTable.ColNames.ServiceVersion}", DsVerString)
|
||||
filed.Add($"{DataServiceListTable.ColNames.CacheCount}", CacheCount.ToString)
|
||||
filed.Add($"{DataServiceListTable.ColNames.IsDBProxyConn}", IsDBProxyConn.ToString)
|
||||
filed.Add($"{DataServiceListTable.ColNames.NetworkNeiborhood}", NetworkNeiborhood)
|
||||
|
||||
If String.IsNullOrEmpty(ErrMsg) = False Then
|
||||
filed.Add($"{DataServiceListTable.ColNames.ErrMsg}", ErrMsg)
|
||||
ErrMsg = String.Empty
|
||||
End If
|
||||
|
||||
Dim condition As String = $"`{DataServiceListTable.ColNames.ID}` = {_dsIndex}"
|
||||
cmdText = db.CmdHelper.DbUpdate(UtsDb.RemotePublicDb, tbName, filed, condition)
|
||||
|
||||
Try
|
||||
db.ExecuteNonQuery(cmdText)
|
||||
Catch ex As Exception
|
||||
ServiceLog.WriteErrorLog($"Update ServiceTable Error:{ex.Message}")
|
||||
End Try
|
||||
|
||||
db.Close()
|
||||
End Using
|
||||
End Sub
|
||||
End Class
|
||||
7
AUTS_DataService/ServiceError.vb
Normal file
7
AUTS_DataService/ServiceError.vb
Normal file
@@ -0,0 +1,7 @@
|
||||
Public Class ServiceError
|
||||
Public Shared Event ServiceError(type As String, msg As String)
|
||||
|
||||
Public Shared Sub RecodeError(type As String, msg As String)
|
||||
RaiseEvent ServiceError(type, msg)
|
||||
End Sub
|
||||
End Class
|
||||
334
AUTS_DataService/ServiceLog.vb
Normal file
334
AUTS_DataService/ServiceLog.vb
Normal file
@@ -0,0 +1,334 @@
|
||||
Imports UTS_Core.Database
|
||||
Imports UTS_Core.UTSModule
|
||||
Imports UTS_Core.UTSModule.DbConnect
|
||||
Imports UTS_Core.UTSModule.DbTableModel.Manage
|
||||
|
||||
Public Class ServiceLog
|
||||
|
||||
Private Shared ReadOnly LogLock As New Object()
|
||||
|
||||
Private Shared ReadOnly LogQueue As New List(Of Dictionary(Of String, String))
|
||||
|
||||
''' <summary>厂商名</summary>
|
||||
Public Shared VendorName As String
|
||||
|
||||
''' <summary>公网IP</summary>
|
||||
Public Shared PublicIp As String
|
||||
|
||||
''' <summary>本地IP</summary>
|
||||
Public Shared PrivateIp As String
|
||||
|
||||
''' <summary>本地MAC地址</summary>
|
||||
Public Shared MAC As String
|
||||
|
||||
''' <summary>服务索引</summary>
|
||||
Public Shared DsIndex As Integer
|
||||
|
||||
''' <summary>数据服务版本</summary>
|
||||
Public Shared DsVersion As String
|
||||
|
||||
''' <summary>更新服务版本</summary>
|
||||
Public Shared UsVersion As String
|
||||
|
||||
''' <summary>存入数据库日志类型</summary>
|
||||
Public Shared DbLogType As Byte
|
||||
|
||||
''' <summary>日志文件夹路径</summary>
|
||||
Public Shared Property LogDirPath As String
|
||||
Get
|
||||
Return UTS_Core.DebugLog.ApplicationLog.LogDirPath
|
||||
End Get
|
||||
Set(value As String)
|
||||
UTS_Core.DebugLog.ApplicationLog.LogDirPath = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
|
||||
''' <summary>日志文件前缀</summary>
|
||||
Public Shared Property LogFilePrefix As String
|
||||
Get
|
||||
Return UTS_Core.DebugLog.ApplicationLog.LogFilePrefix
|
||||
End Get
|
||||
Set(value As String)
|
||||
UTS_Core.DebugLog.ApplicationLog.LogFilePrefix = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
|
||||
Public Shared ReadOnly Property LogFilePath() As String
|
||||
Get
|
||||
Return UTS_Core.DebugLog.ApplicationLog.LogFilePath
|
||||
End Get
|
||||
End Property
|
||||
|
||||
|
||||
''' <summary>在线状态</summary>
|
||||
Public Shared Online As Boolean
|
||||
|
||||
''' <summary>将日志写入到本地文件</summary>
|
||||
Public Shared Sub WriteErrorLogToFile(logText As String)
|
||||
UTS_Core.DebugLog.ApplicationLog.WriteErrorLog(logText)
|
||||
End Sub
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 写入致命错误至本地与云端数据库
|
||||
''' </summary>
|
||||
''' <param name="logText">日志内容</param>
|
||||
Public Shared Sub WriteFatalLog(logText As String)
|
||||
WriteLogToLogQueue(UTS_Core.DebugLog.ApplicationLog.LogTypes.Fatal, logText)
|
||||
End Sub
|
||||
|
||||
|
||||
Public Shared Sub WriteErrorLog(logText As String)
|
||||
WriteLogToLogQueue(UTS_Core.DebugLog.ApplicationLog.LogTypes.Error, logText)
|
||||
End Sub
|
||||
|
||||
Public Shared Sub WriteWarningLog(logText As String)
|
||||
WriteLogToLogQueue(UTS_Core.DebugLog.ApplicationLog.LogTypes.Warn, logText)
|
||||
End Sub
|
||||
|
||||
Public Shared Sub WriteInfoLog(logText As String)
|
||||
WriteLogToLogQueue(UTS_Core.DebugLog.ApplicationLog.LogTypes.Info, logText)
|
||||
End Sub
|
||||
|
||||
Public Shared Sub WriteDebugLog(logText As String)
|
||||
WriteLogToLogQueue(UTS_Core.DebugLog.ApplicationLog.LogTypes.Debug, logText)
|
||||
End Sub
|
||||
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 添加日志内容至缓存的日志队列中
|
||||
''' 调用SaveLogQueueToDb将队列中的数据写入到数据库
|
||||
'''
|
||||
''' Tip:缓存队列仅记录每条日志不同的内容,例如写入时间,日志类型,日志内容等
|
||||
''' </summary>
|
||||
''' <param name="logType"></param>
|
||||
''' <param name="logText"></param>
|
||||
Public Shared Sub WriteLogToLogQueue(logType As UTS_Core.DebugLog.ApplicationLog.LogTypes, logText As String)
|
||||
UTS_Core.DebugLog.ApplicationLog.WriteLog($"{logType}", logText) '写入本地文本日志
|
||||
If ((DbLogType >> logType) And 1) = 0 Then Return '过滤不入库的信息
|
||||
|
||||
Dim dicFiled As New Dictionary(Of String, String)
|
||||
|
||||
dicFiled.Add($"{DataServiceLogTable.ColNames.DateTime}", $"{Now:yyyy-MM-dd HH:mm:ss}")
|
||||
|
||||
dicFiled.Add($"{DataServiceLogTable.ColNames.LogType}", $"{logType}")
|
||||
dicFiled.Add($"{DataServiceLogTable.ColNames.LogText}", $"{logText.Replace("'"c, """"c).Replace("`", """"c)}")
|
||||
|
||||
SyncLock LogLock
|
||||
LogQueue.Add(dicFiled) '将日志信息放入缓冲队列
|
||||
End SyncLock
|
||||
End Sub
|
||||
|
||||
Private Shared Sub SaveLogToLocalDb(count As Integer, Optional saveCache As Boolean = False)
|
||||
Dim tableName As String = DataServiceLogTable.TableName
|
||||
Using db As New DbExecutor(UtsDb.LocalDbType, UtsDb.LocalConnString)
|
||||
db.Open()
|
||||
|
||||
db.BeginTransaction()
|
||||
|
||||
Dim dicFiled As Dictionary(Of String, String)
|
||||
Dim cmdText As String
|
||||
Dim cmdHelper As DbCmdHelper = DbCmdHelper.CreateCmdHelper(UtsDb.RemoteDbType)
|
||||
|
||||
SyncLock LogLock
|
||||
For i As Integer = 0 To count - 1
|
||||
dicFiled = LogQueue.Item(i)
|
||||
|
||||
'修改上传方式为插值方式
|
||||
Dim colName As String
|
||||
Dim colNames As New List(Of String)
|
||||
Dim remoteFileds As New Dictionary(Of String, String)
|
||||
Try
|
||||
colName = $"{DataServiceLogTable.ColNames.ServiceID}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.Int32, colName, DsIndex)
|
||||
remoteFileds.Add(colName, DsIndex.ToString)
|
||||
|
||||
colName = $"{DataServiceLogTable.ColNames.ServiceVersion}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.AnsiString, colName, DsVersion)
|
||||
remoteFileds.Add(colName, DsVersion)
|
||||
|
||||
colName = $"{DataServiceLogTable.ColNames.UpdateServiceVersion}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.AnsiString, colName, UsVersion)
|
||||
remoteFileds.Add(colName, UsVersion)
|
||||
|
||||
colName = $"{DataServiceLogTable.ColNames.VendorName}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.AnsiString, colName, VendorName)
|
||||
remoteFileds.Add(colName, VendorName)
|
||||
|
||||
colName = $"{DataServiceLogTable.ColNames.DateTime}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.DateTime, colName, dicFiled(colName))
|
||||
remoteFileds.Add(colName, dicFiled(colName))
|
||||
|
||||
colName = $"{DataServiceLogTable.ColNames.PublicIp}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.AnsiString, colName, PublicIp)
|
||||
remoteFileds.Add(colName, PublicIp)
|
||||
|
||||
colName = $"{DataServiceLogTable.ColNames.PrivateIp}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.AnsiString, colName, PrivateIp)
|
||||
remoteFileds.Add(colName, PrivateIp)
|
||||
|
||||
colName = $"{DataServiceLogTable.ColNames.LogType}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.AnsiString, colName, dicFiled(colName))
|
||||
remoteFileds.Add(colName, dicFiled(colName))
|
||||
|
||||
colName = $"{DataServiceLogTable.ColNames.LogText}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.AnsiString, colName, dicFiled(colName))
|
||||
remoteFileds.Add(colName, dicFiled(colName).Replace("'", " ").Replace("’", " "))
|
||||
|
||||
cmdText = db.CmdHelper.InsertParam(tableName, colNames)
|
||||
|
||||
db.ExecuteNonQuery(cmdText) '执行语句
|
||||
Catch ex As Exception
|
||||
WriteErrorLogToFile($"Write LogQueue To Local DB Error: {ex.Message}")
|
||||
Continue For
|
||||
End Try
|
||||
|
||||
|
||||
If saveCache Then
|
||||
Try
|
||||
cmdText = cmdHelper.DbInsert(UtsDb.RemotePublicDb, tableName, remoteFileds)
|
||||
DbConnector.SaveCmdStringToCacheTable(db, cmdText) '执行命令入缓存库
|
||||
Catch ex As Exception
|
||||
WriteErrorLogToFile($"Write LogQueue To Chche DB Error: {ex.Message}")
|
||||
Continue For
|
||||
End Try
|
||||
End If
|
||||
Next
|
||||
End SyncLock
|
||||
|
||||
db.CommitTransaction()
|
||||
db.Close()
|
||||
End Using
|
||||
End Sub
|
||||
|
||||
Private Shared Function SaveLogToRemoteDb(count As Integer) As Boolean
|
||||
Dim tableName As String = DataServiceLogTable.TableName
|
||||
Using db As New DbExecutor(UtsDb.RemoteDbType, UtsDb.RemoteConnString)
|
||||
db.Open()
|
||||
|
||||
db.BeginTransaction()
|
||||
|
||||
Dim dicFiled As Dictionary(Of String, String)
|
||||
Dim cmdText As String
|
||||
Dim colName As String
|
||||
Dim colNames As New List(Of String)
|
||||
|
||||
For i As Integer = 0 To count - 1
|
||||
colNames.Clear()
|
||||
dicFiled = LogQueue.Item(i)
|
||||
|
||||
Try
|
||||
colName = $"{DataServiceLogTable.ColNames.ServiceID}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.Int32, colName, DsIndex)
|
||||
|
||||
colName = $"{DataServiceLogTable.ColNames.ServiceVersion}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.AnsiString, colName, DsVersion)
|
||||
|
||||
colName = $"{DataServiceLogTable.ColNames.UpdateServiceVersion}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.AnsiString, colName, UsVersion)
|
||||
|
||||
colName = $"{DataServiceLogTable.ColNames.VendorName}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.AnsiString, colName, VendorName)
|
||||
|
||||
colName = $"{DataServiceLogTable.ColNames.DateTime}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.DateTime, colName, dicFiled(colName))
|
||||
|
||||
colName = $"{DataServiceLogTable.ColNames.PublicIp}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.AnsiString, colName, PublicIp)
|
||||
|
||||
colName = $"{DataServiceLogTable.ColNames.PrivateIp}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.AnsiString, colName, PrivateIp)
|
||||
|
||||
colName = $"{DataServiceLogTable.ColNames.Mac}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.AnsiString, colName, MAC)
|
||||
|
||||
colName = $"{DataServiceLogTable.ColNames.LogType}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.AnsiString, colName, dicFiled(colName))
|
||||
|
||||
colName = $"{DataServiceLogTable.ColNames.LogText}"
|
||||
colNames.Add(colName)
|
||||
db.AddDbParameter(DbType.AnsiString, colName, dicFiled(colName))
|
||||
|
||||
cmdText = db.CmdHelper.DbInsertParam(UtsDb.RemotePublicDb, tableName, colNames)
|
||||
|
||||
db.ExecuteNonQuery(cmdText) '执行语句
|
||||
|
||||
db.ClearDbParameter()
|
||||
Catch ex As Exception
|
||||
WriteErrorLogToFile($"[{i}]Write LogQueue To Remote DB Error: {ex.Message}")
|
||||
|
||||
Try
|
||||
db.RollbackTransaction()
|
||||
db.Close()
|
||||
Catch ex2 As Exception
|
||||
WriteErrorLogToFile($"Write LogQueue To Remote DB Rollback Transaction Error: {ex.Message}")
|
||||
End Try
|
||||
|
||||
Return False
|
||||
End Try
|
||||
Next
|
||||
|
||||
db.CommitTransaction()
|
||||
db.Close()
|
||||
End Using
|
||||
|
||||
Return True
|
||||
End Function
|
||||
|
||||
|
||||
Public Shared Sub SaveLogQueueToDb()
|
||||
If LogQueue.Count <= 0 Then Return
|
||||
|
||||
Dim count As Integer = LogQueue.Count
|
||||
Dim saveCache As Boolean
|
||||
SyncLock LogLock
|
||||
'执行
|
||||
saveCache = SaveLogToRemoteDb(count) = False
|
||||
SaveLogToLocalDb(count, saveCache)
|
||||
|
||||
'删除
|
||||
For i As Integer = 0 To count - 1
|
||||
LogQueue.RemoveAt(0)
|
||||
Next
|
||||
End SyncLock
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 创建数据服务日志表,数据服务独有
|
||||
''' </summary>
|
||||
Public Shared Sub CreateServiceLogTable()
|
||||
|
||||
Using db As New DbExecutor(UtsDb.LocalDbType, UtsDb.LocalConnString)
|
||||
db.Open()
|
||||
|
||||
Dim cmdText As String = DataServiceLogTable.CreateTableString("", DbExecutor.DbTypeEnum.Sqlite)
|
||||
|
||||
db.ExecuteNonQuery(cmdText)
|
||||
|
||||
db.Close()
|
||||
End Using
|
||||
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
16
AUTS_DataService/ServiceSettings.vb
Normal file
16
AUTS_DataService/ServiceSettings.vb
Normal file
@@ -0,0 +1,16 @@
|
||||
Imports System.Xml.Serialization
|
||||
Imports UTS_Core.UTSModule.Service
|
||||
|
||||
|
||||
<XmlInclude(GetType(ServiceSettings))>
|
||||
<XmlInclude(GetType(ServiceTask))>
|
||||
<XmlInclude(GetType(DbSyncServiceTask))>
|
||||
<XmlInclude(GetType(ListenJsonFileServiceTask))>
|
||||
Public Class ServiceSettings
|
||||
Public Tasks As List(Of ServiceTask)
|
||||
|
||||
Sub New()
|
||||
Tasks = New List(Of ServiceTask)()
|
||||
|
||||
End Sub
|
||||
End Class
|
||||
219
AUTS_DataService/ServiceTask/DbSyncServiceTask.vb
Normal file
219
AUTS_DataService/ServiceTask/DbSyncServiceTask.vb
Normal file
@@ -0,0 +1,219 @@
|
||||
Imports System.Threading
|
||||
Imports System.Xml.Serialization
|
||||
Imports UTS_Core.Database
|
||||
Imports UTS_Core.UTSModule
|
||||
Imports UTS_Core.UTSModule.Service
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 数据库同步类
|
||||
''' </summary>
|
||||
<XmlInclude(GetType(DbSyncServiceTask))>
|
||||
Public Class DbSyncServiceTask
|
||||
Inherits ServiceTask
|
||||
|
||||
Sub New()
|
||||
TaskType = ServiceTaskTypeEnum.DbSync
|
||||
TaskStatus = ServiceTaskStatusEnum.Stop
|
||||
TaskName = "DbSync_Default"
|
||||
|
||||
Interval = 5
|
||||
|
||||
|
||||
LocalDbType = UtsDb.LocalDbType
|
||||
LocalConnString = UtsDb.LocalConnString
|
||||
|
||||
RemoteDbType = UtsDb.RemoteDbType
|
||||
RemoteConnString = UtsDb.RemoteConnString
|
||||
RemotePublicDb = UtsDb.RemotePublicDb
|
||||
RemotePrivateDb = UtsDb.RemotePrivateDb
|
||||
End Sub
|
||||
|
||||
Sub New(name As String, param As Dictionary(Of String, String))
|
||||
TaskType = ServiceTaskTypeEnum.DbSync
|
||||
TaskStatus = ServiceTaskStatusEnum.Stop
|
||||
TaskName = name
|
||||
|
||||
LocalDbType = UtsDb.LocalDbType
|
||||
LocalConnString = UtsDb.LocalConnString
|
||||
|
||||
RemoteDbType = UtsDb.RemoteDbType
|
||||
RemoteConnString = UtsDb.RemoteConnString
|
||||
RemotePublicDb = UtsDb.RemotePublicDb
|
||||
RemotePrivateDb = UtsDb.RemotePrivateDb
|
||||
|
||||
SetParams(param)
|
||||
End Sub
|
||||
|
||||
|
||||
Private Sub StartCallback(stat As Object)
|
||||
While TaskStatus = ServiceTaskStatusEnum.Start
|
||||
|
||||
'同步任务
|
||||
Try
|
||||
Dim syncParam As DbSynchronizer.SyncParam
|
||||
syncParam.LocalConnString = LocalConnString
|
||||
syncParam.LocalType = LocalDbType
|
||||
syncParam.RemoteType = RemoteDbType
|
||||
syncParam.RemoteConnString = RemoteConnString
|
||||
syncParam.PublicDb = RemotePublicDb
|
||||
syncParam.PrivateDb = RemotePrivateDb
|
||||
|
||||
'开始数据库同步
|
||||
Dim sync As DbSynchronizer
|
||||
sync = New DbSynchronizer(syncParam)
|
||||
sync.SyncDatabase()
|
||||
ServiceLog.WriteInfoLog($"DbSynchronizer Succeeded!")
|
||||
|
||||
'更新数据库更新时间
|
||||
LastUpdateTime = $"{Now:yyyy-MM-dd HH:mm:ss}"
|
||||
Catch ex As Exception
|
||||
ServiceLog.WriteErrorLog($"TaskName:{TaskName},SyncDatabase Error:{ex.Message}")
|
||||
End Try
|
||||
|
||||
'等待任务
|
||||
Dim lastTime As Date = Now
|
||||
While (Now - lastTime).TotalMinutes < Interval
|
||||
If TaskStatus = ServiceTaskStatusEnum.Stop Then
|
||||
Return
|
||||
End If
|
||||
|
||||
Thread.Sleep(1000)
|
||||
End While
|
||||
|
||||
End While
|
||||
End Sub
|
||||
|
||||
|
||||
Public Overrides Sub Start()
|
||||
TaskStatus = ServiceTaskStatusEnum.Start
|
||||
|
||||
If _syncThread IsNot Nothing AndAlso _syncThread.IsAlive Then
|
||||
ServiceLog.WriteDebugLog($"SyncThread IsAlive!")
|
||||
Return
|
||||
End If
|
||||
|
||||
_syncThread = New Thread(AddressOf StartCallback)
|
||||
_syncThread.IsBackground = True
|
||||
_syncThread.Start()
|
||||
|
||||
ServiceLog.WriteDebugLog($"DbSync Start!")
|
||||
End Sub
|
||||
|
||||
|
||||
Public Overrides Sub [Stop]()
|
||||
TaskStatus = ServiceTaskStatusEnum.Stop
|
||||
|
||||
Dim lastTime As Date = Now
|
||||
While _syncThread IsNot Nothing AndAlso _syncThread.IsAlive
|
||||
If (Now - lastTime).TotalMilliseconds > 10000 Then
|
||||
_syncThread.Abort()
|
||||
End If
|
||||
|
||||
Thread.Sleep(100)
|
||||
End While
|
||||
ServiceLog.WriteInfoLog($"DbSync Stop!")
|
||||
End Sub
|
||||
|
||||
|
||||
Public Overrides Sub Restart()
|
||||
If _syncThread IsNot Nothing AndAlso _syncThread.IsAlive Then
|
||||
[Stop]()
|
||||
End If
|
||||
|
||||
|
||||
Start()
|
||||
ServiceLog.WriteInfoLog($"DbSync Restart!")
|
||||
End Sub
|
||||
|
||||
|
||||
Public Overrides Sub SetParams(params As Dictionary(Of String, String))
|
||||
Dim tmpStatus As ServiceTaskStatusEnum = TaskStatus
|
||||
Dim tmpInterval As Integer = Interval
|
||||
|
||||
'将转换后的数据填充至临时缓存,一遍设置失败时可以保留上一次数据
|
||||
For Each param As KeyValuePair(Of String, String) In params
|
||||
Select Case param.Key
|
||||
Case "Interval"
|
||||
If Integer.TryParse(param.Value, tmpInterval) = False Then
|
||||
Throw New Exception($"Error Interval :{param.Value}")
|
||||
End If
|
||||
Case "LocalDbType"
|
||||
'If [Enum].TryParse(param.Value, tmpLocalType) = False Then
|
||||
' Throw New Exception($"Error LocalDbType :{param.Value}")
|
||||
'End If
|
||||
Case "LocalConnString"
|
||||
'tmpLocalConnString = UTS_Core.Security.Aes128.DecryptStr(param.Value, UTS_Core.Security.Aes128.ServerAesKey)
|
||||
Case "Status", "Type", "Name" '不处理的字段
|
||||
|
||||
|
||||
Case Else
|
||||
ServiceLog.WriteWarningLog($"DbSync Unknown param name :{param.Key}")
|
||||
End Select
|
||||
Next
|
||||
|
||||
TaskStatus = tmpStatus
|
||||
Interval = tmpInterval
|
||||
End Sub
|
||||
|
||||
|
||||
Public Overrides Function GetParams() As Dictionary(Of String, String)
|
||||
Dim params As New Dictionary(Of String, String)
|
||||
params.Add("Type", TaskType.ToString())
|
||||
params.Add("Name", TaskName)
|
||||
params.Add("Status", TaskStatus.ToString())
|
||||
params.Add("Interval", Interval.ToString())
|
||||
params.Add("LocalDbType", LocalDbType.ToString())
|
||||
params.Add("LocalConnString", UTS_Core.Security.Aes128.EncryptStr(LocalConnString, UTS_Core.Security.Aes128.ServerAesKey))
|
||||
|
||||
Return params
|
||||
End Function
|
||||
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 远程数据库的类型
|
||||
''' </summary>
|
||||
Private RemoteDbType As DbExecutor.DbTypeEnum
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 远程数据库的连接字符串
|
||||
''' </summary>
|
||||
Private RemoteConnString As String
|
||||
|
||||
''' <summary>
|
||||
''' 远端公共数据库名
|
||||
''' </summary>
|
||||
Private RemotePublicDb As String
|
||||
|
||||
''' <summary>
|
||||
''' 远端私有库名
|
||||
''' </summary>
|
||||
Private RemotePrivateDb As String
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 本地数据库的类型
|
||||
''' </summary>
|
||||
Private LocalDbType As DbExecutor.DbTypeEnum
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 本地数据库的连接字符串
|
||||
''' </summary>
|
||||
Private LocalConnString As String
|
||||
|
||||
''' <summary>
|
||||
''' 同步间隔,单位分钟,默认5分钟,最小值为1分钟
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property Interval() As Integer
|
||||
|
||||
Private _syncThread As Thread
|
||||
|
||||
''' <summary>
|
||||
''' 最后一次更新的时间字符串
|
||||
''' </summary>
|
||||
Public Shared LastUpdateTime As String = ""
|
||||
End Class
|
||||
678
AUTS_DataService/ServiceTask/DbSynchronizer.vb
Normal file
678
AUTS_DataService/ServiceTask/DbSynchronizer.vb
Normal file
@@ -0,0 +1,678 @@
|
||||
Imports System.Data.Common
|
||||
Imports System.Text
|
||||
Imports MySql.Data.MySqlClient
|
||||
Imports UTS_Core.Database
|
||||
Imports UTS_Core.UTSModule.DbTableModel
|
||||
|
||||
''' <summary>
|
||||
''' 数据库同步器
|
||||
''' </summary>
|
||||
Public Class DbSynchronizer
|
||||
|
||||
''' <summary>
|
||||
''' 同步表内容
|
||||
''' </summary>
|
||||
Structure SyncTableScheme
|
||||
''' <summary>表名</summary>
|
||||
Public TableName As String
|
||||
''' <summary>同步类型</summary>
|
||||
Public SyncType As String
|
||||
''' <summary>是否存在当前数据表</summary>
|
||||
Public IsExistsTable As Boolean
|
||||
''' <summary>更新版本</summary>
|
||||
Public RevisionID As String
|
||||
''' <summary>上一次更新时间字符串</summary>
|
||||
Public LastSyncTime As String
|
||||
''' <summary>同步后更新的时间字符串</summary>
|
||||
Public NowSyncTime As String
|
||||
End Structure
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 同步数据库参数
|
||||
''' </summary>
|
||||
Structure SyncParam
|
||||
Public PublicDb As String
|
||||
|
||||
Public PrivateDb As String
|
||||
|
||||
Public RemoteType As DbExecutor.DbTypeEnum
|
||||
|
||||
Public RemoteConnString As String
|
||||
|
||||
Public LocalType As DbExecutor.DbTypeEnum
|
||||
|
||||
Public LocalConnString As String
|
||||
End Structure
|
||||
|
||||
|
||||
Sub New(param As SyncParam)
|
||||
Parameters = param
|
||||
End Sub
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 连接参数
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property Parameters() As SyncParam
|
||||
|
||||
''' <summary>
|
||||
''' 同步数据库,开始同步
|
||||
''' </summary>
|
||||
Public Sub SyncDatabase()
|
||||
Using remoteDb As New DbExecutor(Parameters.RemoteType, Parameters.RemoteConnString)
|
||||
remoteDb.Open()
|
||||
|
||||
Using localDb As New DbExecutor(Parameters.LocalType, Parameters.LocalConnString)
|
||||
localDb.Open()
|
||||
|
||||
SyncDatabase(localDb, remoteDb, Parameters.PublicDb, Parameters.PrivateDb)
|
||||
|
||||
localDb.Close()
|
||||
End Using
|
||||
|
||||
remoteDb.Close()
|
||||
End Using
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 同步数据库执行过程
|
||||
''' </summary>
|
||||
''' <param name="localDb">本地数据库执行器</param>
|
||||
''' <param name="remoteDb">云端数据库执行器</param>
|
||||
''' <param name="publicDb">远端数据库公共库名</param>
|
||||
''' <param name="privateDb">远端数据库私有库名</param>
|
||||
Public Sub SyncDatabase(localDb As DbExecutor, remoteDb As DbExecutor, publicDb As String, privateDb As String)
|
||||
If remoteDb Is Nothing Then Return
|
||||
If localDb Is Nothing Then Return
|
||||
|
||||
'上传本地缓存数据
|
||||
remoteDb.BeginTransaction()
|
||||
UploadCacheData(remoteDb, localDb)
|
||||
remoteDb.CommitTransaction()
|
||||
ServiceLog.WriteDebugLog($"UploadCacheData Successded!")
|
||||
|
||||
'获取需要公有下载的数据表
|
||||
DownloadSyncTable(remoteDb, localDb, publicDb, Manage.SyncListTable.TableName)
|
||||
ServiceLog.WriteDebugLog($"Download Puclic SyncTable Successded!")
|
||||
|
||||
'获取需要私有下载的数据表
|
||||
DownloadSyncTable(remoteDb, localDb, privateDb, Customer.SyncListTable.TableName)
|
||||
ServiceLog.WriteDebugLog($"Download Private SyncTable Successded!")
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 上传本地缓存数据,DataTable的方式
|
||||
''' </summary>
|
||||
''' <param name="remoteDb">远程数据库执行器</param>
|
||||
''' <param name="localDb">本地数据库执行器</param>
|
||||
Private Sub UploadCacheData(remoteDb As DbExecutor, localDb As DbExecutor)
|
||||
|
||||
CreateCacheTableWhenNotExists(localDb)
|
||||
|
||||
Dim dataTable As DataTable = SearchCacheData(localDb)
|
||||
|
||||
UploadCacheData(remoteDb, localDb, dataTable)
|
||||
|
||||
End Sub
|
||||
|
||||
#Region "上传本地缓存数据"
|
||||
''' <summary>
|
||||
''' 本地创建缓存记录表,如果不存在则创建
|
||||
''' </summary>
|
||||
''' <param name="localDb">本地数据库的执行器</param>
|
||||
Private Sub CreateCacheTableWhenNotExists(localDb As DbExecutor)
|
||||
localDb.ExecuteNonQuery(LocalPrivate.CacheTable.CreateTableString)
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 查询本地未上传的数据,单次查询5000条数据
|
||||
''' </summary>
|
||||
''' <param name="localDb">本地数据库的执行器</param>
|
||||
''' <returns></returns>
|
||||
Private Function SearchCacheData(localDb As DbExecutor) As DataTable
|
||||
Dim tableName As String = LocalPrivate.CacheTable.TableName
|
||||
Dim colNames As String = $"{LocalPrivate.CacheTable.ColNamesEnum.ID},{LocalPrivate.CacheTable.ColNamesEnum.SqlCmd}"
|
||||
Dim condition As String = $"{LocalPrivate.CacheTable.ColNamesEnum.IsUpload} = 0 order by `{LocalPrivate.CacheTable.ColNamesEnum.ID}` Limit 5000"
|
||||
Dim cmdText As String = localDb.CmdHelper.Search(colNames, tableName, condition)
|
||||
Return localDb.ExecuteDataTable(cmdText)
|
||||
End Function
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 上传本地数据至云端数据库
|
||||
''' </summary>
|
||||
''' <param name="remoteDb"></param>
|
||||
''' <param name="localDb"></param>
|
||||
''' <param name="dataTable"></param>
|
||||
Private Sub UploadCacheData(remoteDb As DbExecutor, localDb As DbExecutor, dataTable As DataTable)
|
||||
ServiceLog.WriteDebugLog($"Begin Upload Cache DataTable [{dataTable.Rows.Count}] Rows!")
|
||||
For Each row As DataRow In dataTable.Rows
|
||||
Try
|
||||
Dim cmdText As String = row(LocalPrivate.CacheTable.ColNamesEnum.SqlCmd.ToString()).ToString()
|
||||
remoteDb.ExecuteNonQuery(cmdText)
|
||||
|
||||
Catch ex As MySqlException
|
||||
'记录失败
|
||||
Dim id As String = row(LocalPrivate.CacheTable.ColNamesEnum.ID.ToString()).ToString()
|
||||
|
||||
ServiceLog.WriteErrorLog($"UploadData Error:{ex.Message},ErrorNumber:{ex.Number},ID:{id}")
|
||||
|
||||
Select Case ex.Number
|
||||
Case MySqlErrorCode.DuplicateFieldName '重复字段
|
||||
ServiceLog.WriteInfoLog($"DuplicateFieldName,Ignore the error!")
|
||||
Case Else
|
||||
ServiceLog.WriteWarningLog($"Unknown,Continue to perform!")
|
||||
Exit For
|
||||
End Select
|
||||
Catch ex As Exception
|
||||
'记录失败
|
||||
ServiceLog.WriteErrorLog($"UploadData Error:{ex.Message}")
|
||||
|
||||
ServiceError.RecodeError("DbSync", $"UploadData Error:{ex.Message}")
|
||||
Exit For
|
||||
End Try
|
||||
|
||||
Try
|
||||
DeleteUploadData(localDb, row(LocalPrivate.CacheTable.ColNamesEnum.ID).ToString)
|
||||
Catch ex As Exception
|
||||
'记录失败
|
||||
ServiceLog.WriteErrorLog($"UpdateCacheTable Error:{ex.Message}")
|
||||
End Try
|
||||
Next
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 数据上传完成后,删除本地数据库中对应序号的记录
|
||||
''' </summary>
|
||||
''' <param name="localDb"></param>
|
||||
''' <param name="sn"></param>
|
||||
Private Sub DeleteUploadData(localDb As DbExecutor, sn As String)
|
||||
Dim tableName As String = LocalPrivate.CacheTable.TableName
|
||||
Dim condition As String = $"{LocalPrivate.CacheTable.ColNamesEnum.ID} = '{sn}'"
|
||||
localDb.ExecuteNonQuery(localDb.CmdHelper.DeleteRows(tableName, condition))
|
||||
End Sub
|
||||
#End Region
|
||||
|
||||
#Region "获取需要下载表集合"
|
||||
''' <summary>
|
||||
''' 比对本地与云端版本表,下载变化的数据表
|
||||
''' </summary>
|
||||
''' <param name="remoteDb"></param>
|
||||
''' <param name="localDb"></param>
|
||||
''' <param name="dbName"></param>
|
||||
''' <param name="tbName"></param>
|
||||
Public Sub DownloadSyncTable(remoteDb As DbExecutor, localDb As DbExecutor, dbName As String, tbName As String)
|
||||
Dim downloadTables As List(Of SyncTableScheme)
|
||||
downloadTables = CompareVersionTable(remoteDb, localDb, dbName, tbName)
|
||||
UpdateTables(remoteDb, localDb, dbName, downloadTables) '更新本地数据
|
||||
End Sub
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 比较本地与云端版本表的差异,获取需要下载的数据表
|
||||
''' </summary>
|
||||
''' <param name="remoteDb"></param>
|
||||
''' <param name="localDb"></param>
|
||||
''' <param name="tableName"></param>
|
||||
''' <returns></returns>
|
||||
Private Function CompareVersionTable(remoteDb As DbExecutor, localDb As DbExecutor, dbName As String, tableName As String) As List(Of SyncTableScheme)
|
||||
CreateVersionTableWhenNotExists(localDb)
|
||||
Dim localTable As DataTable = localDb.ExecuteDataTable(localDb.CmdHelper.SearchAll(Customer.SyncListTable.TableName))
|
||||
Dim remoteTable As DataTable = remoteDb.ExecuteDataTable(remoteDb.CmdHelper.DbSearchAll(dbName, tableName))
|
||||
Return CompareVersionTable(localTable, remoteTable)
|
||||
End Function
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 创建本地数据库表版本记录表
|
||||
''' </summary>
|
||||
''' <param name="localDb"></param>
|
||||
Private Sub CreateVersionTableWhenNotExists(localDb As DbExecutor)
|
||||
Try
|
||||
localDb.ExecuteNonQuery(Customer.SyncListTable.CreateTableString(localDb.DatabaseType))
|
||||
Catch ex As Exception
|
||||
'记录失败
|
||||
ServiceLog.WriteErrorLog($"CreateVersionTableWhenNotExists Error:{ex.Message}")
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 比较本地与云端版本表的差异
|
||||
''' </summary>
|
||||
''' <param name="srcDataTable">源DataTable</param>
|
||||
''' <param name="destDataTable">目标DataTable</param>
|
||||
''' <returns>差异信息列表</returns>
|
||||
Private Function CompareVersionTable(srcDataTable As DataTable, destDataTable As DataTable) As List(Of SyncTableScheme)
|
||||
Dim result As New List(Of SyncTableScheme)
|
||||
Dim srcTableName As String
|
||||
Dim destTableName As String
|
||||
Dim isFind As Boolean
|
||||
Dim srcReVId As String = String.Empty
|
||||
Dim destRevId As String
|
||||
For i As Integer = 0 To destDataTable.Rows.Count - 1
|
||||
destTableName = $"{destDataTable.Rows(i)($"{Customer.SyncListTable.ColNamesEnum.TableName}")}"
|
||||
isFind = False
|
||||
|
||||
For j As Integer = 0 To srcDataTable.Rows.Count - 1
|
||||
srcTableName = $"{srcDataTable.Rows(j)($"{Customer.SyncListTable.ColNamesEnum.TableName}")}"
|
||||
|
||||
If String.Compare(destTableName, srcTableName, True) = 0 Then
|
||||
srcReVId = $"{srcDataTable.Rows(j)($"{Customer.SyncListTable.ColNamesEnum.RevisionID}")}"
|
||||
isFind = True
|
||||
Exit For
|
||||
End If
|
||||
Next
|
||||
|
||||
If isFind Then
|
||||
destRevId = $"{destDataTable.Rows(i)($"{Customer.SyncListTable.ColNamesEnum.RevisionID}")}"
|
||||
If String.Compare(srcReVId, destRevId, True) <> 0 Then '源表中存在记录且与目的表记录时间不相同
|
||||
result.Add(New SyncTableScheme() With {.TableName = destTableName,
|
||||
.SyncType = $"{destDataTable.Rows(i)($"{Customer.SyncListTable.ColNamesEnum.SyncType}")}",
|
||||
.LastSyncTime = $"{srcDataTable.Rows(i)($"{Customer.SyncListTable.ColNamesEnum.SyncTime}")}",
|
||||
.RevisionID = destRevId,
|
||||
.IsExistsTable = True})
|
||||
End If
|
||||
Else
|
||||
result.Add(New SyncTableScheme() With {.TableName = destTableName,
|
||||
.SyncType = $"{destDataTable.Rows(i)($"{Customer.SyncListTable.ColNamesEnum.SyncType}")}",
|
||||
.LastSyncTime = $"2000-01-01 00:00:00",
|
||||
.RevisionID = $"{destDataTable.Rows(i)($"{Customer.SyncListTable.ColNamesEnum.RevisionID}")}",
|
||||
.IsExistsTable = False})
|
||||
End If
|
||||
Next
|
||||
Return result
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "下载远程数据至本地"
|
||||
''' <summary>
|
||||
''' 更新下载数据表
|
||||
''' </summary>
|
||||
''' <param name="remoteDb">远程数据库执行器</param>
|
||||
''' <param name="localDb">本地数据库执行器</param>
|
||||
''' <param name="tables">需要同步的数据表信息集合</param>
|
||||
Private Sub UpdateTables(remoteDb As DbExecutor, localDb As DbExecutor, dbName As String, tables As List(Of SyncTableScheme))
|
||||
Dim ts As Date
|
||||
Try
|
||||
ts = CDate(remoteDb.ExecuteScalar("select current_timestamp()"))
|
||||
Catch ex As Exception
|
||||
ServiceLog.WriteErrorLog($"Get DB System Time Error:{ex.Message}")
|
||||
Return
|
||||
End Try
|
||||
|
||||
For Each table As SyncTableScheme In tables
|
||||
table.NowSyncTime = ts.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
localDb.BeginTransaction()
|
||||
Try
|
||||
If String.Compare(table.SyncType, "all", True) = 0 Then
|
||||
UpdateTableForAll(remoteDb, localDb, dbName, table)
|
||||
ElseIf String.Compare(table.SyncType, "new", True) = 0 Then
|
||||
'增量更新Update限制,必须包含ID、UpdateTime字段,且ID字段为主键
|
||||
UpdateTableForNew(remoteDb, localDb, dbName, table)
|
||||
Else
|
||||
UpdateTableForAll(remoteDb, localDb, dbName, table)
|
||||
End If
|
||||
|
||||
UpdateVersionTable(localDb, table)
|
||||
Catch ex As Exception
|
||||
ServiceLog.WriteErrorLog($"UpdateTable {table.TableName} Error:{ex.Message}")
|
||||
End Try
|
||||
localDb.CommitTransaction()
|
||||
Next
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 下载修改全表修改部分的方式下载表
|
||||
''' </summary>
|
||||
''' <param name="remoteDb"></param>
|
||||
''' <param name="localDb"></param>
|
||||
''' <param name="dbName"></param>
|
||||
''' <param name="table"></param>
|
||||
Private Sub UpdateTableForNew(remoteDb As DbExecutor, localDb As DbExecutor, dbName As String, table As SyncTableScheme)
|
||||
Dim maxID As Integer = 0
|
||||
If table.IsExistsTable = False Then
|
||||
Dim remoteTable As DataTable = remoteDb.ExecuteDataTable(remoteDb.CmdHelper.DbSearchAll(dbName, table.TableName, "1 = 0"))
|
||||
Dim createTableString As String = CreateTableStringByDataTable(table.TableName, remoteTable) '获取建表语句
|
||||
localDb.ExecuteNonQuery(createTableString)
|
||||
Else
|
||||
'查询本地最大ID,主键必须为ID
|
||||
Dim cmd As String = localDb.CmdHelper.SearchOrder(New List(Of String)() From {"ID"}, table.TableName, "ORDER BY [ID] DESC LIMIT 1")
|
||||
Dim maxIdObject As Object = localDb.ExecuteScalar(cmd)
|
||||
If IsDBNull(maxIdObject) = False Then
|
||||
maxID = CInt(maxIdObject)
|
||||
End If
|
||||
End If
|
||||
|
||||
'通过dataReader插入数据,查询远程更新时间后的所有内容
|
||||
Using reader As DbDataReader = remoteDb.ExecuteReader(remoteDb.CmdHelper.DbSearchAll(dbName, table.TableName, $"`UpdateTime` > '{table.LastSyncTime}'"))
|
||||
While reader.Read()
|
||||
If CInt(reader("ID")) > maxID Then '小于最大ID则更新,大于最大ID则插入
|
||||
InsertDataByDataReader(localDb, table.TableName, reader)
|
||||
Else
|
||||
UpdateDataByDataReader(localDb, table.TableName, reader)
|
||||
End If
|
||||
End While
|
||||
reader.Close()
|
||||
End Using
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 更新全表的方式下载表
|
||||
''' </summary>
|
||||
''' <param name="remoteDb"></param>
|
||||
''' <param name="localDb"></param>
|
||||
''' <param name="table"></param>
|
||||
Private Sub UpdateTableForAll(remoteDb As DbExecutor, localDb As DbExecutor, dbName As String, table As SyncTableScheme)
|
||||
'删除本地表
|
||||
If table.IsExistsTable Then
|
||||
localDb.ExecuteNonQuery(localDb.CmdHelper.DropTable(table.TableName))
|
||||
End If
|
||||
|
||||
'新建表(考虑是否应该查询总数后,依此取1000行的方式下载,或考虑使用DataReader)
|
||||
Dim remoteTable As DataTable = remoteDb.ExecuteDataTable(remoteDb.CmdHelper.DbSearchAll(dbName, table.TableName, "1 = 0"))
|
||||
Dim createTableString As String = CreateTableStringByDataTable(table.TableName, remoteTable) '获取建表语句
|
||||
localDb.ExecuteNonQuery(createTableString)
|
||||
|
||||
'通过dataReader插入数据
|
||||
Using reader As DbDataReader = remoteDb.ExecuteReader(remoteDb.CmdHelper.DbSearchAll(dbName, table.TableName))
|
||||
While reader.Read()
|
||||
InsertDataByDataReader(localDb, table.TableName, reader)
|
||||
End While
|
||||
reader.Close()
|
||||
End Using
|
||||
End Sub
|
||||
|
||||
Private Sub UpdateDataByDataReader(localDb As DbExecutor, tableName As String, dbReader As DbDataReader)
|
||||
Dim colNames As New List(Of String)
|
||||
|
||||
Using comm As DbCommand = localDb.CreateCommand()
|
||||
For i As Integer = 0 To dbReader.FieldCount - 1
|
||||
colNames.Add(dbReader.GetName(i))
|
||||
|
||||
Dim param As DbParameter = comm.CreateParameter()
|
||||
param.DbType = DbType.Object
|
||||
param.ParameterName = $"@{dbReader.GetName(i)}"
|
||||
param.Value = dbReader.Item(i)
|
||||
|
||||
comm.Parameters.Add(param)
|
||||
Next
|
||||
|
||||
comm.CommandText = localDb.CmdHelper.UpdateParam(tableName, colNames, $"`ID` = {dbReader("ID")}")
|
||||
|
||||
comm.ExecuteNonQuery()
|
||||
End Using
|
||||
End Sub
|
||||
|
||||
|
||||
Private Sub InsertDataByDataReader(localDb As DbExecutor, tableName As String, dbReader As DbDataReader)
|
||||
Dim colNames As New List(Of String)
|
||||
|
||||
Using comm As DbCommand = localDb.CreateCommand()
|
||||
For i As Integer = 0 To dbReader.FieldCount - 1
|
||||
colNames.Add(dbReader.GetName(i))
|
||||
|
||||
Dim param As DbParameter = comm.CreateParameter()
|
||||
param.DbType = DbType.Object
|
||||
param.ParameterName = $"@{dbReader.GetName(i)}"
|
||||
param.Value = dbReader.Item(i)
|
||||
|
||||
comm.Parameters.Add(param)
|
||||
Next
|
||||
|
||||
comm.CommandText = localDb.CmdHelper.InsertParam(tableName, colNames)
|
||||
|
||||
comm.ExecuteNonQuery()
|
||||
End Using
|
||||
End Sub
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 将目标DataTable的所有数据插入到指定数据表中,不检测是否需要新增列
|
||||
'''
|
||||
''' 后续插入字符需要区别数值与字符串
|
||||
''' </summary>
|
||||
''' <param name="localDb"></param>
|
||||
''' <param name="tableName"></param>
|
||||
''' <param name="dataTable"></param>
|
||||
Private Sub InsertDataByDataTable(localDb As DbExecutor, tableName As String, dataTable As DataTable)
|
||||
Dim colNameParams As New Dictionary(Of String, String)
|
||||
' Dim colParamValues As New Dictionary(Of String, Object)
|
||||
|
||||
For Each dtRow As DataRow In dataTable.Rows
|
||||
For Each dtCol As DataColumn In dataTable.Columns
|
||||
colNameParams.Add(dtCol.ColumnName, $"@{dtCol.ColumnName}")
|
||||
' colParamValues.Add($"@{dtCol.ColumnName}", dtRow(dtCol.ColumnName))
|
||||
|
||||
'存疑是否可以修改
|
||||
Dim param As DbParameter = localDb.Command.CreateParameter()
|
||||
param.DbType = DbType.Object
|
||||
param.ParameterName = $"@{dtCol.ColumnName}"
|
||||
param.Value = dtRow(dtCol.ColumnName)
|
||||
|
||||
localDb.Command.Parameters.Add(param)
|
||||
Next
|
||||
|
||||
Dim cmdText As String = localDb.CmdHelper.Insert(tableName, colNameParams)
|
||||
localDb.ExecuteNonQuery(cmdText) '执行插入
|
||||
localDb.Command.Parameters.Clear() '清空参数
|
||||
|
||||
|
||||
colNameParams.Clear() '复位
|
||||
Next
|
||||
End Sub
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 更新本地数据成功后,同步更新本地版本记录表
|
||||
''' </summary>
|
||||
''' <param name="localDb">本地数据库执行器</param>
|
||||
''' <param name="table">需要同步的数据表信息</param>
|
||||
Private Sub UpdateVersionTable(localDb As DbExecutor, table As SyncTableScheme)
|
||||
Dim tableName As String = Customer.SyncListTable.TableName
|
||||
Dim cmdText As String
|
||||
|
||||
If table.IsExistsTable Then
|
||||
Dim colNameValue As New Dictionary(Of String, String) From {
|
||||
{$"{Customer.SyncListTable.ColNamesEnum.RevisionID}", table.RevisionID},
|
||||
{$"{Customer.SyncListTable.ColNamesEnum.SyncTime}", table.NowSyncTime}
|
||||
}
|
||||
Dim condition As String = $"{Customer.SyncListTable.ColNamesEnum.TableName} = '{table.TableName}'"
|
||||
cmdText = localDb.CmdHelper.Update(tableName, colNameValue, condition)
|
||||
Else
|
||||
Dim colNameValue As New Dictionary(Of String, String) From {
|
||||
{$"{Customer.SyncListTable.ColNamesEnum.TableName}", table.TableName},
|
||||
{$"{Customer.SyncListTable.ColNamesEnum.RevisionID}", table.RevisionID},
|
||||
{$"{Customer.SyncListTable.ColNamesEnum.SyncType}", table.SyncType},
|
||||
{$"{Customer.SyncListTable.ColNamesEnum.SyncTime}", table.NowSyncTime}
|
||||
}
|
||||
cmdText = localDb.CmdHelper.Insert(tableName, colNameValue)
|
||||
End If
|
||||
|
||||
Try
|
||||
localDb.ExecuteNonQuery(cmdText)
|
||||
Catch ex As Exception
|
||||
ServiceLog.WriteErrorLog($"UpdateVersionTable Error:{ex.Message}")
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
|
||||
|
||||
#Region "数据类型转换"
|
||||
Enum SystemTypeEnum
|
||||
[AnsiString]
|
||||
[AnsiStringFixedLength]
|
||||
Binary
|
||||
[Boolean]
|
||||
[Byte]
|
||||
[DateTime]
|
||||
[Decimal]
|
||||
[Double]
|
||||
[Guid]
|
||||
[Int16]
|
||||
[Int32]
|
||||
[Int64]
|
||||
[SByte]
|
||||
[Single]
|
||||
[String]
|
||||
[TimeSpan]
|
||||
[UInt16]
|
||||
[UInt32]
|
||||
[UInt64]
|
||||
End Enum
|
||||
|
||||
''' <summary>
|
||||
''' 将.net数据类型转换为Sqlite数据类型
|
||||
''' </summary>
|
||||
''' <param name="dataType">.net数据类型</param>
|
||||
''' <returns>转换后的Sqlite数据类型</returns>
|
||||
Public Shared Function ConvertSystemTypeToSqliteType(dataType As String) As String
|
||||
Dim reType As String
|
||||
|
||||
Select Case dataType
|
||||
Case SystemTypeEnum.AnsiString.ToString()
|
||||
reType = Sqlite.DataParam.DataTypeEnum.Varchar.ToString()
|
||||
|
||||
Case SystemTypeEnum.[AnsiStringFixedLength].ToString()
|
||||
reType = Sqlite.DataParam.DataTypeEnum.Nchar.ToString()
|
||||
|
||||
Case SystemTypeEnum.Binary.ToString(), SystemTypeEnum.Byte.ToString()
|
||||
reType = Sqlite.DataParam.DataTypeEnum.Blob.ToString()
|
||||
|
||||
Case SystemTypeEnum.[Boolean].ToString()
|
||||
reType = Sqlite.DataParam.DataTypeEnum.Bit.ToString()
|
||||
|
||||
Case SystemTypeEnum.[DateTime].ToString()
|
||||
reType = Sqlite.DataParam.DataTypeEnum.Datetime.ToString()
|
||||
|
||||
Case SystemTypeEnum.[Decimal].ToString()
|
||||
reType = Sqlite.DataParam.DataTypeEnum.[Decimal].ToString()
|
||||
|
||||
Case SystemTypeEnum.[Double].ToString()
|
||||
reType = Sqlite.DataParam.DataTypeEnum.Real.ToString()
|
||||
|
||||
Case SystemTypeEnum.[Guid].ToString()
|
||||
reType = Sqlite.DataParam.DataTypeEnum.UniqueIdentifier.ToString()
|
||||
|
||||
Case SystemTypeEnum.[Int16].ToString()
|
||||
reType = Sqlite.DataParam.DataTypeEnum.SmallInt.ToString()
|
||||
|
||||
Case SystemTypeEnum.[Int32].ToString()
|
||||
reType = Sqlite.DataParam.DataTypeEnum.[Integer].ToString()
|
||||
|
||||
Case SystemTypeEnum.[Int64].ToString()
|
||||
reType = Sqlite.DataParam.DataTypeEnum.[Integer].ToString()
|
||||
|
||||
Case SystemTypeEnum.[SByte].ToString()
|
||||
reType = Sqlite.DataParam.DataTypeEnum.TinyInt.ToString()
|
||||
|
||||
Case SystemTypeEnum.[Single].ToString()
|
||||
reType = Sqlite.DataParam.DataTypeEnum.[Single].ToString()
|
||||
|
||||
Case SystemTypeEnum.[String].ToString()
|
||||
reType = Sqlite.DataParam.DataTypeEnum.Nvarchar.ToString()
|
||||
|
||||
Case SystemTypeEnum.TimeSpan.ToString()
|
||||
reType = Sqlite.DataParam.DataTypeEnum.Datetime.ToString()
|
||||
|
||||
Case SystemTypeEnum.[UInt16].ToString()
|
||||
reType = Sqlite.DataParam.DataTypeEnum.SmallUint.ToString()
|
||||
|
||||
Case SystemTypeEnum.[UInt32].ToString()
|
||||
reType = Sqlite.DataParam.DataTypeEnum.Uint.ToString()
|
||||
|
||||
Case SystemTypeEnum.[UInt64].ToString()
|
||||
reType = Sqlite.DataParam.DataTypeEnum.UnsignedInteger.ToString()
|
||||
|
||||
Case "Byte[]"
|
||||
reType = Sqlite.DataParam.DataTypeEnum.Blob.ToString()
|
||||
|
||||
Case Else
|
||||
'reType = Sqlite.DataParam.DataTypeEnum.Varchar.ToString()
|
||||
Throw New Exception($"ConvertSystemTypeToSqliteType,UnDealType:{dataType}{vbNewLine}")
|
||||
End Select
|
||||
|
||||
Return reType
|
||||
End Function
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 通过解析DbDataReader列名与列类型,暂不可用
|
||||
''' </summary>
|
||||
''' <param name="tableName"></param>
|
||||
''' <param name="reader"></param>
|
||||
''' <returns></returns>
|
||||
Private Function CreateTableStringByDataReader(tableName As String, reader As DbDataReader) As String
|
||||
Dim builder As New StringBuilder
|
||||
builder.Append($"CREATE TABLE If Not Exists [{tableName}] (")
|
||||
|
||||
For i As Integer = 0 To reader.FieldCount - 1
|
||||
If i = 0 Then
|
||||
'应该修改成通用的类型转换
|
||||
builder.Append($"[{reader.GetName(i)}] {ConvertSystemTypeToSqliteType(reader.GetDataTypeName(i))}")
|
||||
Else
|
||||
builder.Append($", [{reader.GetName(i)}] {ConvertSystemTypeToSqliteType(reader.GetDataTypeName(i))}")
|
||||
End If
|
||||
Next
|
||||
|
||||
builder.Append(" )")
|
||||
Return builder.ToString()
|
||||
End Function
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 通过解析DataTable,获取建表语句
|
||||
''' </summary>
|
||||
''' <param name="tableName">数据表名</param>
|
||||
''' <param name="destTable">需要解析的内存数据表</param>
|
||||
''' <returns></returns>
|
||||
Private Function CreateTableStringByDataTable(tableName As String, destTable As DataTable) As String
|
||||
Dim builder As New StringBuilder
|
||||
builder.Append($"CREATE TABLE If Not Exists [{tableName}] (")
|
||||
For i As Integer = 0 To destTable.Columns.Count - 1
|
||||
If i = 0 Then
|
||||
'应该修改成通用的类型转换
|
||||
builder.Append($"[{destTable.Columns(i).ColumnName}] {ConvertSystemTypeToSqliteType(destTable.Columns(i).DataType.Name)}")
|
||||
Else
|
||||
builder.Append($", [{destTable.Columns(i).ColumnName}] {ConvertSystemTypeToSqliteType(destTable.Columns(i).DataType.Name)}")
|
||||
End If
|
||||
|
||||
'列名长度
|
||||
If destTable.Columns(i).MaxLength > -1 Then
|
||||
builder.Append($"({destTable.Columns(i).MaxLength})")
|
||||
End If
|
||||
|
||||
'列为空
|
||||
If destTable.Columns(i).AllowDBNull = False Then
|
||||
builder.Append($" NOT NULL")
|
||||
End If
|
||||
|
||||
'列自增(默认列自增为主键)
|
||||
If destTable.Columns(i).AutoIncrement Then
|
||||
builder.Append($" PRIMARY KEY AutoIncrement")
|
||||
'Else
|
||||
' '唯一值
|
||||
' If destTable.Columns(i).Unique Then
|
||||
' builder.Append($" Unique")
|
||||
' End If
|
||||
End If
|
||||
|
||||
''默认值
|
||||
'If destTable.Columns(i).DefaultValue IsNot Nothing Then
|
||||
' If String.IsNullOrEmpty(destTable.Columns(i).DefaultValue.ToString()) = False Then
|
||||
' builder.Append($" DEFAULT '{destTable.Columns(i).DefaultValue}'")
|
||||
' End If
|
||||
'End If
|
||||
|
||||
Next
|
||||
|
||||
builder.Append(" )")
|
||||
Return builder.ToString()
|
||||
End Function
|
||||
#End Region
|
||||
|
||||
End Class
|
||||
33
AUTS_DataService/ServiceTask/IServiceTask.vb
Normal file
33
AUTS_DataService/ServiceTask/IServiceTask.vb
Normal file
@@ -0,0 +1,33 @@
|
||||
''' <summary>
|
||||
''' 任务类型接口,每个任务必须实现的功能
|
||||
''' </summary>
|
||||
Public Interface IServiceTask
|
||||
''' <summary>
|
||||
''' 任务开始
|
||||
''' </summary>
|
||||
Sub Start()
|
||||
|
||||
''' <summary>
|
||||
''' 任务退出
|
||||
''' </summary>
|
||||
Sub [Stop]()
|
||||
|
||||
''' <summary>
|
||||
''' 重启任务
|
||||
''' </summary>
|
||||
Sub Restart()
|
||||
|
||||
''' <summary>
|
||||
''' 设置任务参数
|
||||
''' </summary>
|
||||
''' <param name="params"></param>
|
||||
Sub SetParams(params As Dictionary(Of String, String))
|
||||
|
||||
''' <summary>
|
||||
''' 获取任务参数
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Function GetParams() As Dictionary(Of String, String)
|
||||
|
||||
|
||||
End Interface
|
||||
127
AUTS_DataService/ServiceTask/JsonFileListen.vb
Normal file
127
AUTS_DataService/ServiceTask/JsonFileListen.vb
Normal file
@@ -0,0 +1,127 @@
|
||||
Imports System.IO
|
||||
Imports Newtonsoft.Json
|
||||
|
||||
Imports UTS_Core.Database
|
||||
Imports UTS_Core.UTSModule.DbConnect
|
||||
|
||||
Public Class JsonFileListen
|
||||
|
||||
''' <summary>
|
||||
''' 读取文件并将内容保存在本地数据库中
|
||||
''' </summary>
|
||||
''' <param name="path"></param>
|
||||
''' <returns></returns>
|
||||
Public Function ReadFile(db As DbExecutor, path As String) As Boolean
|
||||
ServiceLog.WriteInfoLog($"FileListen Begin ReadFile!")
|
||||
|
||||
If File.Exists(path) = False Then
|
||||
Throw New Exception($"{path}不存在!")
|
||||
End If
|
||||
|
||||
ServiceLog.WriteInfoLog($"FileListen Get fileLength!")
|
||||
|
||||
Dim fileInfo As New FileInfo(path) '获取文件大小
|
||||
If fileInfo.Length = 0 Then Return True
|
||||
|
||||
ServiceLog.WriteInfoLog($"FileListen Begin Read Text String!")
|
||||
|
||||
Using reader As New StreamReader(path)
|
||||
While reader.Peek() <> -1
|
||||
Dim line As String = reader.ReadLine()
|
||||
If String.IsNullOrWhiteSpace(line) Then Continue While '过滤信息
|
||||
line = line.Replace("\", "\\") '处理转义字符
|
||||
|
||||
Dim tmpField As Dictionary(Of String, String)
|
||||
Try
|
||||
tmpField = CType(JsonConvert.DeserializeObject(line, GetType(Dictionary(Of String, String))), Dictionary(Of String, String))
|
||||
Catch ex As Exception
|
||||
ServiceLog.WriteErrorLog($"FileListen JsonConvertToKeyValue Error:{ex.Message};JsonString:{line}")
|
||||
Continue While
|
||||
End Try
|
||||
|
||||
ServiceLog.WriteInfoLog($"FileListen Filter Text String!")
|
||||
|
||||
''过滤缺失字段字符串
|
||||
If tmpField.ContainsKey("ProjectName") = False OrElse tmpField.ContainsKey("StationName") = False Then
|
||||
ServiceLog.WriteErrorLog($"FileListen Unexist ProjectName Or StationName Filed,JsonString:{line}")
|
||||
Continue While
|
||||
End If
|
||||
|
||||
ServiceLog.WriteInfoLog($"FileListen Filter Text String Success!")
|
||||
|
||||
'数据处理,根据表名进行分类,增删必要字段
|
||||
Dim tableName As String
|
||||
Try
|
||||
Dim projectIndex As Integer = DbConnector.SearchProjectIndex(db, tmpField("ProjectName"))
|
||||
Dim stationIndex As Integer = DbConnector.SearchStationIndex(db, projectIndex, tmpField("StationName"))
|
||||
tableName = UTS_Core.UTSModule.DbTableModel.Customer.TestLogTable.TableName(projectIndex, stationIndex)
|
||||
Catch ex As Exception
|
||||
ServiceLog.WriteErrorLog($"FileListen GetTestLogTableName Error:{ex.Message};ProjectName:{tmpField("ProjectName")};StationName:{tmpField("StationName")}")
|
||||
Continue While
|
||||
End Try
|
||||
|
||||
ServiceLog.WriteInfoLog($"FileListen Begin CreateTestLogTable!")
|
||||
|
||||
Try '本地表格新建
|
||||
DbConnector.UtsCreateTestLogTableToLocal(db, tableName)
|
||||
Catch ex As Exception
|
||||
ServiceLog.WriteErrorLog($"FileListen CreateTestLogTable Error:{ex.Message}")
|
||||
Continue While
|
||||
End Try
|
||||
|
||||
ServiceLog.WriteInfoLog($"FileListen Begin CreateTestLogTable Success!")
|
||||
|
||||
|
||||
ServiceLog.WriteInfoLog($"FileListen Begin Filter Db Filed!")
|
||||
|
||||
|
||||
Dim fields As New Dictionary(Of String, String) '入库字段
|
||||
For Each valuePair As KeyValuePair(Of String, String) In tmpField
|
||||
If String.IsNullOrWhiteSpace(valuePair.Key) Then Continue For
|
||||
If String.Compare(valuePair.Key, "ProjectName", True) = 0 Then Continue For
|
||||
If String.Compare(valuePair.Key, "StationName", True) = 0 Then Continue For
|
||||
|
||||
If String.Compare(valuePair.Key, "ProductionLineID", True) = 0 Then
|
||||
If String.IsNullOrWhiteSpace(valuePair.Value) Then Continue For
|
||||
End If
|
||||
|
||||
If String.Compare(valuePair.Key, "OrderID", True) = 0 Then
|
||||
If String.IsNullOrWhiteSpace(valuePair.Value) Then Continue For
|
||||
End If
|
||||
|
||||
If String.Compare(valuePair.Key, "ServiceID", True) = 0 Then
|
||||
If String.IsNullOrWhiteSpace(valuePair.Value) Then Continue For
|
||||
End If
|
||||
|
||||
If String.Compare(valuePair.Key, "UserID", True) = 0 Then
|
||||
If String.IsNullOrWhiteSpace(valuePair.Value) Then Continue For
|
||||
End If
|
||||
|
||||
fields.Add(valuePair.Key, valuePair.Value) '过滤字段,保留有效字段
|
||||
Next
|
||||
|
||||
ServiceLog.WriteInfoLog($"FileListen Begin Filter Db Filed Success!")
|
||||
|
||||
ServiceLog.WriteInfoLog($"FileListen SaveTestRecord!")
|
||||
Try '存储
|
||||
DbConnector.UtsInsertToLocal(db, UTS_Core.UTSModule.UtsDb.RemotePrivateDb, tableName, fields)
|
||||
Catch ex As Exception
|
||||
ServiceLog.WriteErrorLog($"FileListen SaveTestRecord Error:{ex.Message}")
|
||||
Continue While
|
||||
End Try
|
||||
|
||||
ServiceLog.WriteInfoLog($"FileListen SaveTestRecord Success!")
|
||||
End While
|
||||
|
||||
reader.Close()
|
||||
End Using
|
||||
|
||||
ServiceLog.WriteInfoLog($"FileListen Begin Clear!")
|
||||
|
||||
File.WriteAllText(path, String.Empty) '清空文件内容,由于多地同时写的原因,有可能会失败
|
||||
|
||||
ServiceLog.WriteInfoLog($"FileListen Success!")
|
||||
|
||||
Return True
|
||||
End Function
|
||||
End Class
|
||||
162
AUTS_DataService/ServiceTask/ListenJsonFileServiceTask.vb
Normal file
162
AUTS_DataService/ServiceTask/ListenJsonFileServiceTask.vb
Normal file
@@ -0,0 +1,162 @@
|
||||
Imports System.Threading
|
||||
Imports System.Xml.Serialization
|
||||
Imports UTS_Core.UTSModule.Service
|
||||
|
||||
<XmlInclude(GetType(ListenJsonFileServiceTask))>
|
||||
Public Class ListenJsonFileServiceTask
|
||||
Inherits ServiceTask
|
||||
|
||||
Private ReadOnly _jsonFile As JsonFileListen
|
||||
|
||||
Sub New()
|
||||
TaskType = ServiceTaskTypeEnum.ListenJsonFile
|
||||
TaskStatus = ServiceTaskStatusEnum.Stop
|
||||
TaskName = "ListenJsonFile"
|
||||
|
||||
_jsonFile = New JsonFileListen()
|
||||
End Sub
|
||||
|
||||
Sub New(name As String)
|
||||
TaskType = ServiceTaskTypeEnum.ListenJsonFile
|
||||
TaskStatus = ServiceTaskStatusEnum.Stop
|
||||
TaskName = name
|
||||
|
||||
_jsonFile = New JsonFileListen()
|
||||
End Sub
|
||||
|
||||
Sub New(name As String, param As Dictionary(Of String, String))
|
||||
TaskType = ServiceTaskTypeEnum.ListenJsonFile
|
||||
TaskStatus = ServiceTaskStatusEnum.Stop
|
||||
TaskName = name
|
||||
|
||||
_jsonFile = New JsonFileListen()
|
||||
|
||||
SetParams(param)
|
||||
|
||||
|
||||
End Sub
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 具体的执行过程
|
||||
''' </summary>
|
||||
''' <param name="stat">状态值,暂未启用</param>
|
||||
Private Sub StartCallback(stat As Object)
|
||||
While TaskStatus = ServiceTaskStatusEnum.Start
|
||||
ServiceLog.WriteInfoLog($"SyncTask Wait Timeout.")
|
||||
|
||||
'等待任务
|
||||
Dim lastTime As DateTime = Now
|
||||
While (Now - lastTime).TotalMinutes < Interval
|
||||
If TaskStatus = ServiceTaskStatusEnum.Stop Then
|
||||
Return
|
||||
End If
|
||||
|
||||
Thread.Sleep(1000)
|
||||
End While
|
||||
|
||||
|
||||
Using localDb As New UTS_Core.Database.DbExecutor(UTS_Core.UTSModule.UtsDb.LocalDbType, UTS_Core.UTSModule.UtsDb.LocalConnString) '连接本地字符串
|
||||
localDb.Open()
|
||||
localDb.BeginTransaction()
|
||||
Try
|
||||
_jsonFile.ReadFile(localDb, FilePath)
|
||||
Catch ex As Exception
|
||||
ServiceLog.WriteErrorLog($"_jsonFile.ReadFile TaskName:{TaskName},ListenJsonFile Error:{ex.Message}")
|
||||
End Try
|
||||
localDb.CommitTransaction()
|
||||
localDb.Close()
|
||||
End Using
|
||||
End While
|
||||
End Sub
|
||||
|
||||
|
||||
Public Overrides Sub Start()
|
||||
ServiceLog.WriteInfoLog($"FileListen Befor StartCallback")
|
||||
|
||||
TaskStatus = ServiceTaskStatusEnum.Start
|
||||
|
||||
If _syncThread IsNot Nothing AndAlso _syncThread.IsAlive Then
|
||||
ServiceLog.WriteInfoLog($"FileListenThread IsAlive!")
|
||||
Return
|
||||
End If
|
||||
|
||||
_syncThread = New Thread(AddressOf StartCallback)
|
||||
_syncThread.IsBackground = True
|
||||
_syncThread.Start()
|
||||
|
||||
ServiceLog.WriteInfoLog($"FileListen After StartCallback")
|
||||
End Sub
|
||||
|
||||
|
||||
Public Overrides Sub [Stop]()
|
||||
ServiceLog.WriteInfoLog($"FileListen Befor Stop!")
|
||||
TaskStatus = ServiceTaskStatusEnum.Stop
|
||||
|
||||
Dim lastTime As DateTime = Now
|
||||
While _syncThread IsNot Nothing AndAlso _syncThread.IsAlive
|
||||
If (Now - lastTime).TotalMilliseconds > 10000 Then
|
||||
_syncThread.Abort()
|
||||
End If
|
||||
|
||||
Thread.Sleep(10)
|
||||
End While
|
||||
|
||||
ServiceLog.WriteInfoLog($"FileListen Stop!")
|
||||
End Sub
|
||||
|
||||
|
||||
Public Overrides Sub Restart()
|
||||
ServiceLog.WriteInfoLog($"FileListen Befor Restart!")
|
||||
If _syncThread IsNot Nothing AndAlso _syncThread.IsAlive Then
|
||||
[Stop]()
|
||||
|
||||
End If
|
||||
|
||||
Start()
|
||||
ServiceLog.WriteInfoLog($"FileListen Restart!")
|
||||
End Sub
|
||||
|
||||
|
||||
Public Overrides Sub SetParams(params As Dictionary(Of String, String))
|
||||
Dim tmpStatus As ServiceTaskStatusEnum
|
||||
Dim tmpInterval As Integer
|
||||
Dim tmpPath As String = String.Empty
|
||||
|
||||
'将转换后的数据填充至临时缓存,一遍设置失败时可以保留上一次数据
|
||||
For Each param As KeyValuePair(Of String, String) In params
|
||||
Select Case param.Key
|
||||
Case "Interval"
|
||||
If Integer.TryParse(param.Value, tmpInterval) = False Then
|
||||
Throw New Exception($"Error Interval :{param.Value}")
|
||||
End If
|
||||
Case "Path"
|
||||
tmpPath = param.Value
|
||||
Case "Status", "Type", "Name" '不处理的字段
|
||||
End Select
|
||||
Next
|
||||
|
||||
TaskStatus = tmpStatus
|
||||
Interval = tmpInterval
|
||||
FilePath = tmpPath
|
||||
End Sub
|
||||
|
||||
|
||||
Public Overrides Function GetParams() As Dictionary(Of String, String)
|
||||
Dim params As New Dictionary(Of String, String) From {
|
||||
{"Type", TaskType.ToString()},
|
||||
{"Name", TaskName},
|
||||
{"Status", TaskStatus.ToString()},
|
||||
{"Interval", Interval.ToString()},
|
||||
{"Path", FilePath}
|
||||
}
|
||||
Return params
|
||||
End Function
|
||||
|
||||
|
||||
Public Property Interval() As Integer
|
||||
|
||||
Public Property FilePath() As String
|
||||
|
||||
Private _syncThread As Thread
|
||||
End Class
|
||||
88
AUTS_DataService/ServiceTask/ServiceTask.vb
Normal file
88
AUTS_DataService/ServiceTask/ServiceTask.vb
Normal file
@@ -0,0 +1,88 @@
|
||||
Imports System.Xml.Serialization
|
||||
|
||||
|
||||
<Serializable>
|
||||
<XmlInclude(GetType(DbSyncServiceTask))>
|
||||
<XmlInclude(GetType(ListenJsonFileServiceTask))>
|
||||
Public MustInherit Class ServiceTask
|
||||
Implements IServiceTask
|
||||
|
||||
''' <summary>
|
||||
''' 服务任务类型枚举集合
|
||||
''' </summary>
|
||||
Enum ServiceTaskTypeEnum
|
||||
''' <summary>
|
||||
''' 数据库同步
|
||||
''' </summary>
|
||||
DbSync
|
||||
|
||||
''' <summary>
|
||||
''' 监听Json文件
|
||||
''' </summary>
|
||||
ListenJsonFile
|
||||
End Enum
|
||||
|
||||
''' <summary>
|
||||
''' 服务任务状态枚举值
|
||||
''' </summary>
|
||||
Enum ServiceTaskStatusEnum
|
||||
''' <summary>
|
||||
''' 启动状态
|
||||
''' </summary>
|
||||
Start
|
||||
|
||||
''' <summary>
|
||||
''' 停止状态
|
||||
''' </summary>
|
||||
[Stop]
|
||||
End Enum
|
||||
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 服务任务类型
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property TaskType() As ServiceTaskTypeEnum
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 服务任务名,服务任务的唯一索引
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property TaskName() As String
|
||||
|
||||
''' <summary>
|
||||
''' 服务任务的状态
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property TaskStatus() As ServiceTaskStatusEnum
|
||||
|
||||
''' <summary>
|
||||
''' 任务开启
|
||||
''' </summary>
|
||||
Public MustOverride Sub Start() Implements IServiceTask.Start
|
||||
|
||||
''' <summary>
|
||||
''' 任务停止
|
||||
''' </summary>
|
||||
Public MustOverride Sub [Stop]() Implements IServiceTask.[Stop]
|
||||
|
||||
''' <summary>
|
||||
''' 任务重启
|
||||
''' </summary>
|
||||
Public MustOverride Sub Restart() Implements IServiceTask.Restart
|
||||
|
||||
''' <summary>
|
||||
''' 任务参数集合设置
|
||||
''' </summary>
|
||||
''' <param name="params">任务参数键值对</param>
|
||||
Public MustOverride Sub SetParams(params As Dictionary(Of String, String)) Implements IServiceTask.SetParams
|
||||
|
||||
''' <summary>
|
||||
''' 任务参数集合获取
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public MustOverride Function GetParams() As Dictionary(Of String, String) Implements IServiceTask.GetParams
|
||||
|
||||
End Class
|
||||
230
AUTS_DataService/ServiceTask/ServiceTasks.vb
Normal file
230
AUTS_DataService/ServiceTask/ServiceTasks.vb
Normal file
@@ -0,0 +1,230 @@
|
||||
Imports UTS_Core.UTSModule.Service
|
||||
|
||||
''' <summary>
|
||||
''' 服务任务列表,管理服务的所有任务
|
||||
''' </summary>
|
||||
Public Class ServiceTasks
|
||||
Private ReadOnly _tasks As Dictionary(Of String, ServiceTask)
|
||||
|
||||
Public Event AddTask(task As Dictionary(Of String, String))
|
||||
Public Event UpdateTask(task As Dictionary(Of String, String))
|
||||
Public Event DelTask(task As String)
|
||||
Public Event ClearTask()
|
||||
|
||||
|
||||
|
||||
Sub New()
|
||||
_tasks = New Dictionary(Of String, ServiceTask)()
|
||||
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 任务总数
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Function Count() As Integer
|
||||
Return _tasks.Count
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' 获取所有的服务任务
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Function GetAllServiceTasks() As List(Of ServiceTask)
|
||||
Return _tasks.Values.ToList()
|
||||
End Function
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 添加任务,默认开启任务
|
||||
''' </summary>
|
||||
Public Sub Add(task As ServiceTask, Optional start As Boolean = True)
|
||||
If String.IsNullOrEmpty(task.TaskName) Then '无效的任务名
|
||||
Throw New Exception($"TaskName {task.TaskName} is invalid!")
|
||||
End If
|
||||
|
||||
If _tasks.ContainsKey(task.TaskName) Then '已存在的任务名
|
||||
Throw New Exception($"TaskName {task.TaskName} already exists!")
|
||||
End If
|
||||
|
||||
_tasks.Add(task.TaskName, task)
|
||||
If start Then task.Start() '默认添加任务时,开启任务
|
||||
RaiseEvent AddTask(task.GetParams())
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 添加任务,默认开启服务
|
||||
''' </summary>
|
||||
Public Sub Add(taskInfo As Dictionary(Of String, String), Optional start As Boolean = True)
|
||||
If taskInfo.ContainsKey("Type") AndAlso taskInfo.ContainsKey("Name") Then
|
||||
Dim task As ServiceTask
|
||||
Select Case taskInfo("Type")'根据类型进行不同任务的初始化
|
||||
Case $"{ ServiceTask.ServiceTaskTypeEnum.DbSync}"
|
||||
task = New DbSyncServiceTask(taskInfo("Name"), taskInfo)
|
||||
Add(task, start)
|
||||
ServiceLog.WriteInfoLog($"taskParam:{task.TaskName} {task.TaskStatus} {task.TaskType}")
|
||||
Case $"{ ServiceTask.ServiceTaskTypeEnum.ListenJsonFile}"
|
||||
task = New ListenJsonFileServiceTask(taskInfo("Name"), taskInfo)
|
||||
Add(task, start)
|
||||
Case Else
|
||||
Throw New Exception($"Unknown Type:{taskInfo("Type")}")
|
||||
End Select
|
||||
Else
|
||||
Throw New Exception($"AddTask Invalid TaskInfo")
|
||||
End If
|
||||
End Sub
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 添加任务列表
|
||||
''' </summary>
|
||||
''' <param name="tasks"></param>
|
||||
Public Sub AddRange(tasks As List(Of ServiceTask), Optional start As Boolean = True)
|
||||
For Each task As ServiceTask In tasks
|
||||
Add(task, start)
|
||||
Next
|
||||
End Sub
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 移除指定的服务任务
|
||||
''' </summary>
|
||||
''' <param name="task"></param>
|
||||
Sub Remove(task As ServiceTask)
|
||||
If _tasks.ContainsKey(task.TaskName) Then
|
||||
task.Stop()
|
||||
RaiseEvent DelTask(task.TaskName)
|
||||
_tasks.Remove(task.TaskName)
|
||||
End If
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 移除指定名称的服务任务
|
||||
''' </summary>
|
||||
Sub RemoveAt(taskName As String)
|
||||
If _tasks.ContainsKey(taskName) Then
|
||||
Remove(_tasks.Item(taskName))
|
||||
End If
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 清空所有的服务任务
|
||||
''' </summary>
|
||||
Sub Clear()
|
||||
'关闭所有任务
|
||||
For Each task As KeyValuePair(Of String, ServiceTask) In _tasks
|
||||
task.Value.Stop()
|
||||
Next
|
||||
|
||||
'清空任务列表
|
||||
_tasks.Clear()
|
||||
RaiseEvent ClearTask()
|
||||
End Sub
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 设置指定任务的任务参数
|
||||
''' </summary>
|
||||
''' <param name="taskName"></param>
|
||||
''' <param name="param"></param>
|
||||
Public Sub SetTaskParams(taskName As String, param As Dictionary(Of String, String))
|
||||
If _tasks.ContainsKey(taskName) = False Then '不存在的任务
|
||||
Throw New Exception($"TaskName {taskName} is nonexistent!")
|
||||
End If
|
||||
_tasks.Item(taskName).SetParams(param)
|
||||
RaiseEvent UpdateTask(_tasks.Item(taskName).GetParams())
|
||||
End Sub
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 返回指定任务名称的任务参数
|
||||
''' </summary>
|
||||
''' <param name="taskName"></param>
|
||||
''' <returns></returns>
|
||||
Public Function GetTaskParams(taskName As String) As Dictionary(Of String, String)
|
||||
If _tasks.ContainsKey(taskName) = False Then '不存在的任务
|
||||
Throw New Exception($"TaskName {taskName} is nonexistent!")
|
||||
End If
|
||||
Return _tasks.Item(taskName).GetParams()
|
||||
End Function
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 获取所有任务的参数信息
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Function GetAllTasksParam() As List(Of Dictionary(Of String, String))
|
||||
Dim allParams As New List(Of Dictionary(Of String, String))
|
||||
For Each task As KeyValuePair(Of String, ServiceTask) In _tasks
|
||||
allParams.Add(task.Value.GetParams())
|
||||
Next
|
||||
Return allParams
|
||||
End Function
|
||||
|
||||
Public Sub StartTask(taskName As String)
|
||||
If _tasks.ContainsKey(taskName) = False Then '不存在的任务
|
||||
Throw New Exception($"TaskName {taskName} is nonexistent!")
|
||||
End If
|
||||
|
||||
_tasks.Item(taskName).Start()
|
||||
RaiseEvent UpdateTask(_tasks.Item(taskName).GetParams())
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
'''开启所有任务
|
||||
''' </summary>
|
||||
Public Sub StartAllTasks()
|
||||
For Each task As KeyValuePair(Of String, ServiceTask) In _tasks
|
||||
task.Value.Start()
|
||||
RaiseEvent UpdateTask(task.Value.GetParams())
|
||||
Next
|
||||
End Sub
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 结束休眠,立即执行任务
|
||||
''' </summary>
|
||||
''' <param name="taskName"></param>
|
||||
Public Sub RestartTask(taskName As String)
|
||||
If _tasks.ContainsKey(taskName) = False Then '不存在的任务
|
||||
Throw New Exception($"TaskName {taskName} is nonexistent!")
|
||||
End If
|
||||
|
||||
_tasks.Item(taskName).Restart()
|
||||
RaiseEvent UpdateTask(_tasks.Item(taskName).GetParams())
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
'''开启所有任务
|
||||
''' </summary>
|
||||
Public Sub RestartAllTasks()
|
||||
For Each task As KeyValuePair(Of String, ServiceTask) In _tasks
|
||||
task.Value.Restart()
|
||||
RaiseEvent UpdateTask(task.Value.GetParams())
|
||||
Next
|
||||
End Sub
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 停止指定任务名的任务
|
||||
''' </summary>
|
||||
''' <param name="taskName"></param>
|
||||
Public Sub StopTask(taskName As String)
|
||||
If _tasks.ContainsKey(taskName) = False Then '不存在的任务
|
||||
Throw New Exception($"TaskName {taskName} is nonexistent!")
|
||||
End If
|
||||
|
||||
_tasks.Item(taskName).Stop()
|
||||
RaiseEvent UpdateTask(_tasks.Item(taskName).GetParams())
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
'''停止所有任务
|
||||
''' </summary>
|
||||
Public Sub StopAllTasks()
|
||||
For Each task As KeyValuePair(Of String, ServiceTask) In _tasks
|
||||
task.Value.Stop()
|
||||
RaiseEvent UpdateTask(task.Value.GetParams())
|
||||
Next
|
||||
End Sub
|
||||
End Class
|
||||
55
AUTS_DataService/UtsApp/UtsApp.vb
Normal file
55
AUTS_DataService/UtsApp/UtsApp.vb
Normal file
@@ -0,0 +1,55 @@
|
||||
Imports System.Net.Sockets
|
||||
Imports Newtonsoft.Json
|
||||
Imports Newtonsoft.Json.Converters
|
||||
Imports UTS_Core.UTSModule.Test.StatusMonitor
|
||||
Public Class UtsApp
|
||||
Public Property Name As String
|
||||
|
||||
Public Property ProjectName As String
|
||||
|
||||
Public Property StationName As String
|
||||
|
||||
Public Property TestPlan As String
|
||||
|
||||
Public Property Version As String
|
||||
|
||||
<JsonConverter(GetType(StringEnumConverter))>
|
||||
Public Property Status As AppStatus
|
||||
|
||||
<JsonIgnore>
|
||||
Public Property UtsStatus As ComportStatusMonitor.ComPortConnectStatusEnum
|
||||
|
||||
<JsonIgnore>
|
||||
Public Property TestStatus As TestCommandStatusMonitor.TestCommandStatusEnum
|
||||
|
||||
<JsonIgnore>
|
||||
Public Property Client As TcpClient
|
||||
|
||||
|
||||
|
||||
Sub New()
|
||||
Name = String.Empty
|
||||
ProjectName = String.Empty
|
||||
StationName = String.Empty
|
||||
TestPlan = String.Empty
|
||||
Version = String.Empty
|
||||
|
||||
UtsStatus = ComportStatusMonitor.ComPortConnectStatusEnum.UnConnected
|
||||
TestStatus = TestCommandStatusMonitor.TestCommandStatusEnum.None
|
||||
Status = AppStatus.Closed
|
||||
End Sub
|
||||
|
||||
|
||||
|
||||
|
||||
Enum AppStatus
|
||||
''' <summary>
|
||||
''' 已启动
|
||||
''' </summary>
|
||||
Started
|
||||
''' <summary>
|
||||
''' 已关闭
|
||||
''' </summary>
|
||||
Closed
|
||||
End Enum
|
||||
End Class
|
||||
83
AUTS_DataService/UtsApp/UtsAppManager.vb
Normal file
83
AUTS_DataService/UtsApp/UtsAppManager.vb
Normal file
@@ -0,0 +1,83 @@
|
||||
Public Class UtsAppManager
|
||||
''' <summary>
|
||||
''' 设备运行APP列表,键为APP名称,值为App对象
|
||||
''' </summary>
|
||||
Private _appDic As Dictionary(Of String, UtsApp)
|
||||
|
||||
Private _clientDic As Dictionary(Of Net.Sockets.TcpClient, UtsApp)
|
||||
|
||||
Sub New()
|
||||
_appDic = New Dictionary(Of String, UtsApp)
|
||||
_clientDic = New Dictionary(Of Net.Sockets.TcpClient, UtsApp)
|
||||
End Sub
|
||||
|
||||
Public Sub AddApp(app As UtsApp)
|
||||
If _appDic.ContainsKey(app.Name) = False Then
|
||||
_appDic.Add(app.Name, app)
|
||||
End If
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 判断App是否存在队列中
|
||||
''' </summary>
|
||||
''' <param name="appName"></param>
|
||||
''' <returns></returns>
|
||||
Public Function AppExists(appName As String) As Boolean
|
||||
Return _appDic.ContainsKey(appName)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' 获取UtsApp对象,没有则添加对象至队列后再返回
|
||||
''' </summary>
|
||||
''' <param name="appName"></param>
|
||||
''' <returns></returns>
|
||||
Public Function GetApp(appName As String) As UtsApp
|
||||
Static lock As New Object
|
||||
|
||||
SyncLock lock
|
||||
If _appDic.ContainsKey(appName) = False Then
|
||||
ServiceLog.WriteDebugLog($"{appName} Add!")
|
||||
_appDic.Add(appName, New UtsApp())
|
||||
End If
|
||||
End SyncLock
|
||||
|
||||
Return _appDic(appName)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' 获取当前App列表
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Function GetAllApps() As List(Of UtsApp)
|
||||
Return _appDic.Values.ToList()
|
||||
End Function
|
||||
|
||||
Public Function GetClientBindApp(client As Net.Sockets.TcpClient) As UtsApp
|
||||
If _clientDic.ContainsKey(client) Then
|
||||
Return _clientDic(client)
|
||||
Else
|
||||
Return Nothing
|
||||
End If
|
||||
End Function
|
||||
|
||||
Public Sub BindClientAndApp(client As Net.Sockets.TcpClient, app As UtsApp)
|
||||
Static lock As New Object
|
||||
|
||||
SyncLock lock
|
||||
If _clientDic.ContainsKey(client) = False Then
|
||||
_clientDic.Add(client, app)
|
||||
ServiceLog.WriteDebugLog($"{_clientDic(client).Name} Connect!")
|
||||
End If
|
||||
End SyncLock
|
||||
End Sub
|
||||
|
||||
|
||||
Public Sub CancelClientBind(client As Net.Sockets.TcpClient)
|
||||
If _clientDic.ContainsKey(client) Then
|
||||
ServiceLog.WriteDebugLog($"{_clientDic(client).Name} Disconnect!")
|
||||
_clientDic(client).Status = UtsApp.AppStatus.Closed
|
||||
_clientDic(client).Client = Nothing
|
||||
_clientDic.Remove(client)
|
||||
End If
|
||||
End Sub
|
||||
End Class
|
||||
31
AUTS_DataService/UtsGroup/ServiceGroup.vb
Normal file
31
AUTS_DataService/UtsGroup/ServiceGroup.vb
Normal file
@@ -0,0 +1,31 @@
|
||||
Public Class ServiceGroup
|
||||
Sub New()
|
||||
'Fileds = New Dictionary(Of String, String)
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 当前服务所属子网组
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property ServiceGroup As String
|
||||
|
||||
''' <summary>
|
||||
''' 当前服务索引
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property ServiceIndex As Integer
|
||||
|
||||
''' <summary>
|
||||
''' 当前命令类型
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property Type As String
|
||||
|
||||
''' <summary>
|
||||
''' 当前包号
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property Index As Integer
|
||||
|
||||
Public Property GroupInfo As New Dictionary(Of String, String)
|
||||
End Class
|
||||
116
AUTS_DataService/UtsGroup/ServiceGroupManager.vb
Normal file
116
AUTS_DataService/UtsGroup/ServiceGroupManager.vb
Normal file
@@ -0,0 +1,116 @@
|
||||
Imports System.Text
|
||||
|
||||
Public Class ServiceGroupManager
|
||||
''' <summary>历史通讯数据服务集合</summary>
|
||||
Private _groupService As Dictionary(Of Integer, OtherService)
|
||||
|
||||
Sub New()
|
||||
_groupService = New Dictionary(Of Integer, OtherService)
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 添加网上邻居,已存在则更新存活时间与状态
|
||||
''' </summary>
|
||||
''' <param name="other"></param>
|
||||
Public Sub Add(other As OtherService)
|
||||
If _groupService.ContainsKey(other.ServiceIndex) Then
|
||||
_groupService(other.ServiceIndex).LastTime = Now
|
||||
_groupService(other.ServiceIndex).IsAlive = True
|
||||
Else
|
||||
_groupService.Add(other.ServiceIndex, other)
|
||||
End If
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 校验其他服务的当前发送包索引是否与上一包索引重复,相同返回True,不相同返回False
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Function CheckServiceSendIndex(serviceId As Integer, sendId As Integer) As Boolean
|
||||
If _groupService.ContainsKey(serviceId) Then
|
||||
If _groupService(serviceId).LastPacketIndex = sendId Then
|
||||
Return True
|
||||
Else
|
||||
Return False
|
||||
End If
|
||||
Else
|
||||
Return False
|
||||
End If
|
||||
End Function
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 校验服务是否存活
|
||||
''' </summary>
|
||||
Public Sub CheckAliveService()
|
||||
For Each other As KeyValuePair(Of Integer, OtherService) In _groupService
|
||||
If (Now - other.Value.LastTime).TotalSeconds > 30 Then
|
||||
other.Value.IsAlive = False
|
||||
End If
|
||||
Next
|
||||
End Sub
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 获取存活状态的所有网上邻居的索引字符串,以逗号分割
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Function GetAliveServiceIndexString() As String
|
||||
'排序后输出
|
||||
Dim sb As New StringBuilder
|
||||
Dim bt() As Integer = _groupService.Keys.ToArray()
|
||||
Array.Sort(bt)
|
||||
For i As Integer = 0 To bt.Length - 1
|
||||
If _groupService(bt(i)).IsAlive = False Then Continue For
|
||||
If sb.Length = 0 Then
|
||||
sb.Append(bt(i))
|
||||
Else
|
||||
sb.Append("," & bt(i))
|
||||
End If
|
||||
Next
|
||||
|
||||
Return sb.ToString
|
||||
|
||||
|
||||
'原来的顺序输出
|
||||
'For Each other As KeyValuePair(Of Integer, OtherService) In _groupService
|
||||
' If other.Value.IsAlive = False Then Continue For
|
||||
' If sb.Length = 0 Then
|
||||
' sb.Append(other.Key)
|
||||
' Else
|
||||
' sb.Append("," & other.Key)
|
||||
' End If
|
||||
'Next
|
||||
End Function
|
||||
End Class
|
||||
|
||||
|
||||
Public Class OtherService
|
||||
Sub New(index As Integer, packetIndex As Integer)
|
||||
ServiceIndex = index
|
||||
LastPacketIndex = packetIndex
|
||||
LastTime = Now
|
||||
IsAlive = True
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' 最后通讯时间
|
||||
''' </summary>
|
||||
Public Property LastTime As DateTime
|
||||
|
||||
''' <summary>
|
||||
''' 最后通讯包ID
|
||||
''' </summary>
|
||||
Public Property LastPacketIndex As Integer
|
||||
|
||||
''' <summary>
|
||||
''' 服务索引
|
||||
''' </summary>
|
||||
Public Property ServiceIndex As Integer
|
||||
|
||||
''' <summary>
|
||||
''' 是否判定为在线
|
||||
''' </summary>
|
||||
Public Property IsAlive As Boolean
|
||||
|
||||
|
||||
End Class
|
||||
18
AUTS_DataService/UtsWeb/CheckSum.vb
Normal file
18
AUTS_DataService/UtsWeb/CheckSum.vb
Normal file
@@ -0,0 +1,18 @@
|
||||
Public Class CheckSum
|
||||
''' <summary>
|
||||
''' 获取数据包的和校验
|
||||
''' </summary>
|
||||
''' <param name="packet">数据包的内容</param>
|
||||
''' <returns></returns>
|
||||
Public Shared Function GetPacketCheck(packet() As Byte) As Byte
|
||||
Dim result As Integer
|
||||
|
||||
'当packet的相加综合超过INT_MAX则会异常
|
||||
For Each b As Byte In packet
|
||||
result += b
|
||||
Next
|
||||
|
||||
Return CByte(&HFF - (result And &HFF))
|
||||
End Function
|
||||
|
||||
End Class
|
||||
5
AUTS_DataService/UtsWeb/IDataPacket.vb
Normal file
5
AUTS_DataService/UtsWeb/IDataPacket.vb
Normal file
@@ -0,0 +1,5 @@
|
||||
Public Interface IDataPacket
|
||||
Function FillPacket(cmd As Byte, param() As Byte) As Byte()
|
||||
Function CheckPacket(packet() As Byte) As Boolean
|
||||
|
||||
End Interface
|
||||
194
AUTS_DataService/UtsWeb/UtsWebPacket.vb
Normal file
194
AUTS_DataService/UtsWeb/UtsWebPacket.vb
Normal file
@@ -0,0 +1,194 @@
|
||||
Imports System.Net
|
||||
|
||||
Public Class UtsWebPacket
|
||||
Implements IDataPacket
|
||||
|
||||
Private _packetSn As Integer
|
||||
|
||||
Sub New()
|
||||
_packetSn = 0
|
||||
End Sub
|
||||
|
||||
|
||||
Public Function FillPacket(cmd As Byte) As Byte()
|
||||
Dim packet(PacketBits.Command) As Byte
|
||||
packet(PacketBits.Head) = &HAA
|
||||
packet(PacketBits.SerialNumber) = CByte(_packetSn)
|
||||
packet(PacketBits.ParamLength) = &H0
|
||||
packet(PacketBits.ParamLength + 1) = &H0
|
||||
packet(PacketBits.CheckValue) = &H0
|
||||
packet(PacketBits.Command) = cmd
|
||||
packet(PacketBits.CheckValue) = CheckSum.GetPacketCheck(packet)
|
||||
|
||||
_packetSn += 1
|
||||
If _packetSn > &HFF Then _packetSn = 0
|
||||
Return packet
|
||||
End Function
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' 用于填充发送包
|
||||
''' </summary>
|
||||
''' <param name="cmd">发送包命令</param>
|
||||
''' <param name="param">发送包参数</param>
|
||||
''' <returns></returns>
|
||||
Public Function FillPacket(cmd As Byte, param() As Byte) As Byte() Implements IDataPacket.FillPacket
|
||||
Dim packet(PacketBits.Command + param.Length) As Byte
|
||||
packet(PacketBits.Head) = &HAA
|
||||
packet(PacketBits.SerialNumber) = CByte(_packetSn)
|
||||
Array.Copy(BitConverter.GetBytes(CShort(param.Length)), 0, packet, PacketBits.ParamLength, 2)
|
||||
packet(PacketBits.CheckValue) = &H0
|
||||
packet(PacketBits.Command) = cmd
|
||||
|
||||
Array.Copy(param, 0, packet, PacketBits.Param, param.Length)
|
||||
packet(PacketBits.CheckValue) = CheckSum.GetPacketCheck(packet)
|
||||
|
||||
_packetSn += 1
|
||||
If _packetSn > &HFF Then _packetSn = 0
|
||||
Return packet
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' 一般用于填充回复包
|
||||
''' </summary>
|
||||
''' <param name="sn">接收包序号</param>
|
||||
''' <param name="cmd">接收包命令</param>
|
||||
''' <param name="param">回复包参数</param>
|
||||
''' <returns></returns>
|
||||
Public Function FillPacket(sn As Byte, cmd As Byte, param() As Byte) As Byte()
|
||||
Dim packet(PacketBits.Command + param.Length) As Byte
|
||||
packet(PacketBits.Head) = &HAA
|
||||
packet(PacketBits.SerialNumber) = sn
|
||||
Array.Copy(BitConverter.GetBytes(CShort(param.Length)), 0, packet, PacketBits.ParamLength, 2)
|
||||
packet(PacketBits.CheckValue) = &H0
|
||||
packet(PacketBits.Command) = cmd
|
||||
|
||||
Array.Copy(param, 0, packet, PacketBits.Param, param.Length)
|
||||
|
||||
packet(PacketBits.CheckValue) = CheckSum.GetPacketCheck(packet)
|
||||
|
||||
Return packet
|
||||
End Function
|
||||
|
||||
|
||||
Public Function CheckPacket(packet() As Byte) As Boolean Implements IDataPacket.CheckPacket
|
||||
If packet(PacketBits.Head) <> &HAA Then
|
||||
Throw New Exception($"Invalid Packet Head!Src:{packet(PacketBits.Head)} Dest:{&HAA}")
|
||||
End If
|
||||
|
||||
'If packet(PacketBits.SerialNumber) <> _packetSn Then
|
||||
' Throw New Exception($"Invalid Packet Sn!Src: {packet(PacketBits.SerialNumber)} Dest:{_packetSn}")
|
||||
'End If
|
||||
|
||||
Dim destLength As Integer = packet.Length - PacketBits.Param
|
||||
|
||||
If BitConverter.ToInt16(packet, PacketBits.ParamLength) <> destLength Then
|
||||
Throw New Exception($"Invalid Packet Lengnt!Src:{packet(PacketBits.ParamLength)} Dest:{destLength}")
|
||||
End If
|
||||
|
||||
If CheckSum.GetPacketCheck(packet) <> &H0 Then
|
||||
Throw New Exception($"Invalid Packet CheckValue!Src:{BitConverter.ToString(packet)}")
|
||||
End If
|
||||
|
||||
Return True
|
||||
End Function
|
||||
|
||||
|
||||
Enum PacketBits
|
||||
''' <summary>包头</summary>
|
||||
Head
|
||||
|
||||
''' <summary>序号</summary>
|
||||
SerialNumber
|
||||
|
||||
''' <summary>包长,两位,小端模式</summary>
|
||||
ParamLength
|
||||
|
||||
''' <summary>校验</summary>
|
||||
CheckValue = ParamLength + 2
|
||||
|
||||
''' <summary>命令</summary>
|
||||
Command
|
||||
|
||||
''' <summary>参数</summary>
|
||||
Param
|
||||
End Enum
|
||||
|
||||
|
||||
<Flags>
|
||||
Enum Commands
|
||||
''' <summary>心跳包</summary>
|
||||
Heartbeat = &H1
|
||||
|
||||
|
||||
''' <summary>设置日志上报</summary>
|
||||
SetLogType = &H2
|
||||
|
||||
''' <summary>读取日志上报</summary>
|
||||
GetLogType = &H3
|
||||
|
||||
|
||||
''' <summary>服务任务状态变化时,主动上报状态</summary>
|
||||
UploadTaskStatus = &H10
|
||||
|
||||
''' <summary>增加服务任务</summary>
|
||||
AddServiceTask = &H11
|
||||
|
||||
''' <summary>删除服务任务</summary>
|
||||
DelServiceTask = &H12
|
||||
|
||||
''' <summary>获取服务任务</summary>
|
||||
GetServiceTask = &H13
|
||||
|
||||
''' <summary>设置服务任务</summary>
|
||||
SetServiceTask = &H14
|
||||
|
||||
''' <summary>开启服务任务</summary>
|
||||
StartServiceTask = &H15
|
||||
|
||||
''' <summary>停止服务任务</summary>
|
||||
StopServiceTask = &H16
|
||||
|
||||
''' <summary>重启服务任务</summary>
|
||||
RestartServiceTask = &H17
|
||||
|
||||
|
||||
''' <summary>上传文件</summary>
|
||||
UploadFile = &H21
|
||||
|
||||
''' <summary>读取指定文件大小</summary>
|
||||
ReadFileSize = &H22
|
||||
|
||||
|
||||
''' <summary>App状态变化时,主动上报状态</summary>
|
||||
UploadAppStatus = &H30
|
||||
|
||||
''' <summary>获取App状态</summary>
|
||||
GetAppStatus = &H31
|
||||
|
||||
''' <summary>设置App状态</summary>
|
||||
SetAppStatus = &H32
|
||||
|
||||
End Enum
|
||||
|
||||
|
||||
Public Class PublicIpChangedEventArgs
|
||||
Inherits EventArgs
|
||||
|
||||
Sub New(ip As IPAddress)
|
||||
PublicIP = ip
|
||||
End Sub
|
||||
|
||||
Public Property PublicIP As IPAddress
|
||||
End Class
|
||||
|
||||
Public Class AddTaskEventArgs
|
||||
Inherits EventArgs
|
||||
|
||||
Sub New(jsonString As String)
|
||||
Me.JsonString = jsonString
|
||||
End Sub
|
||||
|
||||
Public Property JsonString As String
|
||||
End Class
|
||||
End Class
|
||||
248
AUTS_DataService/WebService.vb
Normal file
248
AUTS_DataService/WebService.vb
Normal file
@@ -0,0 +1,248 @@
|
||||
'Imports System.Net
|
||||
'Imports System.Net.Sockets
|
||||
|
||||
'Public Class WebService
|
||||
' Implements IDisposable
|
||||
|
||||
' Enum PacketDataEnum
|
||||
' Head
|
||||
' SerialNumber
|
||||
' ParamLength
|
||||
' CheckValue
|
||||
' Command
|
||||
' Param
|
||||
' End Enum
|
||||
|
||||
' <Flags()>
|
||||
' Enum PacketSendCmdEnum
|
||||
' Heartbeat = &H1
|
||||
|
||||
' End Enum
|
||||
|
||||
' <Flags()>
|
||||
' Enum PacketReceiveCmdEnum
|
||||
' Heartbeat = &HA1
|
||||
|
||||
' End Enum
|
||||
|
||||
' Private _localPublicIp As String
|
||||
|
||||
' Private ReadOnly _udpClient As UdpClient
|
||||
|
||||
' Private _sendPacketSn As Integer
|
||||
|
||||
' Private ReadOnly _hostName As String
|
||||
|
||||
' Private ReadOnly _remotePort As Integer
|
||||
|
||||
' Private _online As Boolean
|
||||
|
||||
' Private _failCount As Integer
|
||||
|
||||
' Sub New(hostName As String, port As Integer)
|
||||
' _hostName = hostName
|
||||
' _remotePort = port
|
||||
|
||||
' _udpClient = New UdpClient()
|
||||
' _sendPacketSn = 0
|
||||
|
||||
' RetryCount = 2
|
||||
' RetryInterval = 5
|
||||
' WaitRelayTimeout = 2000
|
||||
|
||||
' _online = False
|
||||
' _localPublicIp = String.Empty
|
||||
' End Sub
|
||||
|
||||
|
||||
' Public ReadOnly Property LocalPublicIp() As String
|
||||
' Get
|
||||
' Return _localPublicIp
|
||||
' End Get
|
||||
' End Property
|
||||
|
||||
|
||||
' Public ReadOnly Property Online() As Boolean
|
||||
' Get
|
||||
' Return _online
|
||||
' End Get
|
||||
' End Property
|
||||
|
||||
' ''' <summary>
|
||||
' ''' 重试次数,不包含第一次发送次数,默认值2
|
||||
' ''' </summary>
|
||||
' ''' <returns></returns>
|
||||
' Public Property RetryCount() As Integer
|
||||
|
||||
' ''' <summary>
|
||||
' ''' 重试间隔,单位ms,默认5ms
|
||||
' ''' </summary>
|
||||
' ''' <returns></returns>
|
||||
' Public Property RetryInterval() As Integer
|
||||
|
||||
' ''' <summary>
|
||||
' ''' 等待接收超时时间,单位ms,默认2000ms
|
||||
' ''' </summary>
|
||||
' ''' <returns></returns>
|
||||
' Public Property WaitRelayTimeout() As Integer
|
||||
|
||||
|
||||
' Public Sub SendHeartbeatPacket(serviceIndex As Integer)
|
||||
' Dim sendByte() As Byte = FillPacket(CByte(PacketSendCmdEnum.Heartbeat), BitConverter.GetBytes(serviceIndex))
|
||||
|
||||
' Send(sendByte)
|
||||
' End Sub
|
||||
|
||||
|
||||
' Public Function FillPacket(cmd As Byte, param() As Byte) As Byte()
|
||||
' Dim result(PacketDataEnum.Command + param.Length) As Byte
|
||||
' result(PacketDataEnum.Head) = &HAA
|
||||
' result(PacketDataEnum.SerialNumber) = CByte(_sendPacketSn)
|
||||
' result(PacketDataEnum.ParamLength) = CByte(param.Length)
|
||||
' result(PacketDataEnum.CheckValue) = &H0
|
||||
' result(PacketDataEnum.Command) = cmd
|
||||
|
||||
' Array.Copy(param, 0, result, PacketDataEnum.Param, param.Length)
|
||||
' result(PacketDataEnum.CheckValue) = GetCheckSum(result)
|
||||
|
||||
' Return result
|
||||
' End Function
|
||||
|
||||
|
||||
' Public Sub Send(packet() As Byte)
|
||||
' Static receivedReply As Boolean = False
|
||||
' Static waitReplyStartTime As DateTime
|
||||
|
||||
' receivedReply = False
|
||||
' For i As Integer = 0 To RetryCount
|
||||
' _udpClient.Send(packet, packet.Length, _hostName, _remotePort)
|
||||
' waitReplyStartTime = Now
|
||||
|
||||
|
||||
' While receivedReply = False AndAlso (Now - waitReplyStartTime).TotalMilliseconds < WaitRelayTimeout
|
||||
' If _udpClient.Available <= 0 Then
|
||||
' Threading.Thread.Sleep(50)
|
||||
' Continue While
|
||||
' End If
|
||||
|
||||
' Dim ep As IPEndPoint = Nothing
|
||||
' Dim receiveByte() As Byte = _udpClient.Receive(ep)
|
||||
|
||||
' '校验
|
||||
' Try
|
||||
' CheckPacket(receiveByte)
|
||||
' Catch ex As Exception
|
||||
' ApplicationLog.WriteErrorLog($"Check Receive Data Error:{ex.Message}")
|
||||
' Continue While
|
||||
' End Try
|
||||
|
||||
|
||||
' '处理
|
||||
' Try
|
||||
' DealPacket(receiveByte)
|
||||
' Catch ex As Exception
|
||||
' ApplicationLog.WriteErrorLog($"Deal Receive Data Error:{ex.Message}")
|
||||
' Continue While
|
||||
' End Try
|
||||
|
||||
' receivedReply = True
|
||||
' End While
|
||||
|
||||
' If receivedReply Then
|
||||
' Exit For
|
||||
' End If
|
||||
|
||||
' Threading.Thread.Sleep(RetryInterval)
|
||||
' Next
|
||||
|
||||
' If _sendPacketSn + 1 >= 256 Then
|
||||
' _sendPacketSn = 0
|
||||
' Else
|
||||
' _sendPacketSn += 1
|
||||
' End If
|
||||
|
||||
' If receivedReply = False Then
|
||||
' _failCount += 1
|
||||
' If _failCount >= 3 Then
|
||||
' _failCount = 3
|
||||
' _online = False
|
||||
' End If
|
||||
' Else
|
||||
' _failCount = 0
|
||||
' _online = True
|
||||
' End If
|
||||
' End Sub
|
||||
|
||||
|
||||
' Private Sub CheckPacket(packet() As Byte)
|
||||
' If packet(PacketDataEnum.Head) <> &HAA Then
|
||||
' Throw New Exception($"Invalid Packet Head!Src:{packet(PacketDataEnum.Head)} Dest:{&HAA}")
|
||||
' End If
|
||||
|
||||
' If packet(PacketDataEnum.SerialNumber) <> _sendPacketSn Then
|
||||
' Throw New Exception($"Invalid Packet Sn!Src: {packet(PacketDataEnum.SerialNumber)} Dest:{_sendPacketSn}")
|
||||
' End If
|
||||
|
||||
' Dim destLength As Integer = packet.Length - PacketDataEnum.Param
|
||||
' If packet(PacketDataEnum.ParamLength) <> destLength Then
|
||||
' Throw New Exception($"Invalid Packet Lengnt!Src:{packet(PacketDataEnum.ParamLength)} Dest:{destLength}")
|
||||
' End If
|
||||
|
||||
' If GetBytesSum(packet) <> &HFF Then
|
||||
' Throw New Exception($"Invalid Packet CheckValue!Src:{BitConverter.ToString(packet)}")
|
||||
' End If
|
||||
|
||||
' End Sub
|
||||
|
||||
|
||||
' Private Function GetCheckSum(packet() As Byte) As Byte
|
||||
' Dim result As Integer
|
||||
|
||||
' For Each b As Byte In packet
|
||||
' result += b
|
||||
' result = result And &HFF
|
||||
' Next
|
||||
|
||||
' Return CByte(&HFF - result)
|
||||
' End Function
|
||||
|
||||
|
||||
' Private Function GetBytesSum(packet() As Byte) As Byte
|
||||
' Dim result As Integer
|
||||
|
||||
' For Each b As Byte In packet
|
||||
' result += b
|
||||
' result = result And &HFF
|
||||
' Next
|
||||
|
||||
' Return CByte(result)
|
||||
' End Function
|
||||
|
||||
|
||||
' Public Sub DealPacket(packet() As Byte)
|
||||
' Select Case packet(PacketDataEnum.Command)
|
||||
' Case CByte(PacketReceiveCmdEnum.Heartbeat)
|
||||
' DealHeartbeatPacket(packet)
|
||||
' Case Else
|
||||
' Throw New Exception($"Unknown Command:{packet(PacketDataEnum.Command)}")
|
||||
' End Select
|
||||
|
||||
' End Sub
|
||||
|
||||
|
||||
' Private Sub DealHeartbeatPacket(packet() As Byte)
|
||||
' Dim tmpIp As String
|
||||
' tmpIp = $"{packet(PacketDataEnum.Param)}.{packet(PacketDataEnum.Param + 1)}.{packet(PacketDataEnum.Param + 2)}.{packet(PacketDataEnum.Param + 3)}"
|
||||
|
||||
' If String.Compare(LocalPublicIp,tmpIp) <> 0 Then
|
||||
' _localPublicIp = tmpIp
|
||||
' End If
|
||||
|
||||
' End Sub
|
||||
|
||||
' Public Sub Dispose() Implements IDisposable.Dispose
|
||||
' _udpClient.Dispose()
|
||||
|
||||
' End Sub
|
||||
|
||||
'End Class
|
||||
105
AUTS_DataService/版本说明.txt
Normal file
105
AUTS_DataService/版本说明.txt
Normal file
@@ -0,0 +1,105 @@
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
1<><31><EFBFBD>ƶ˽<C6B6><CBBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݿ⣺Weistech
|
||||
<20><><EFBFBD>ݱ<EFBFBD><DDB1><EFBFBD>SW-430-BattTestTool
|
||||
|
||||
2<><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˺ţ<CBBA>sa
|
||||
<20><>¼<EFBFBD><C2BC><EFBFBD>룺%*UgFTR#SW*kj?n
|
||||
Զ<><D4B6>IP<49><50>122.152.232.170
|
||||
<20><><EFBFBD>ʶ˿<CAB6>:2233
|
||||
|
||||
3<><33><EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><DDB1>ֶΣ<D6B6>
|
||||
Device:<3A><><EFBFBD>ͱ<EFBFBD><CDB1><EFBFBD>
|
||||
FW<46><57><EFBFBD>̼<EFBFBD><CCBC>汾<EFBFBD><E6B1BE>
|
||||
SN<53><4E><EFBFBD><EFBFBD><EFBFBD>к<EFBFBD> <20><>ͨ<EFBFBD><CDA8>ɨ<EFBFBD><C9A8>ǹɨ<C7B9><C9A8><EFBFBD><EFBFBD><EFBFBD>룩
|
||||
DateTime_1st<73><74><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
|
||||
BattLevel_1st<73><74><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>¼<EFBFBD><C2BC>ʱ<EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD>
|
||||
DateTime_2nd<6E><64><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
|
||||
BattLevel_2nd<6E><64><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD>¼<EFBFBD><C2BC>ʱ<EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD>
|
||||
|
||||
TimeDiff<66><66><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD>
|
||||
BattDiff<66><66><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD><CEB5><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD>
|
||||
|
||||
4<><34>ʹ<EFBFBD><CAB9>ʱ<EFBFBD><CAB1><EFBFBD>û<EFBFBD><C3BB>ȸ<EFBFBD><C8B8><EFBFBD>Ʒ<EFBFBD><C6B7><EFBFBD>ϵ磬Ȼ<E7A3AC><C8BB><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>һ<EFBFBD><D2BB>¼<EFBFBD>롣
|
||||
<20><>һ<EFBFBD><D2BB>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><F3A3ACBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>죬Ȼ<ECA3AC><C8BB>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>еڶ<D0B5><DAB6><EFBFBD>¼<EFBFBD>롣
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܾ<EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>ݲ<EFBFBD><DDB2><EFBFBD>ʾ<EFBFBD>û<EFBFBD><C3BB><EFBFBD>
|
||||
1<><31><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>¼<EFBFBD><C2BC>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>100%
|
||||
2<><32><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD>¼<EFBFBD><C2BC>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD><DDBF>в<EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
3<><33><EFBFBD><EFBFBD><EFBFBD>ͱ<EFBFBD><CDB1>Ų<EFBFBD><C5B2>Ի<EFBFBD>FW<46>汾<EFBFBD><E6B1BE><EFBFBD><EFBFBD>
|
||||
|
||||
5<><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><F2BFAABA>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD>Ҫд<D2AA><D0B4><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD>ݿ<EFBFBD>
|
||||
6<><36><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>кŲ<D0BA>ѯ<EFBFBD><D1AF><EFBFBD>ݼ<EFBFBD>¼
|
||||
|
||||
|
||||
V1.0.0: 2020-06-19 Momo/QiZhengBiao Frist Released
|
||||
|
||||
V2.0.0: 2020-7-20 Momo
|
||||
1<><31><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>¼<EFBFBD>룬ԭ<EBA3AC><EFBFBD><DEB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ100%<25><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>90~100%֮<>䣬<EFBFBD><E4A3AC><EFBFBD><EFBFBD>С<EFBFBD><D0A1>100%<25><>
|
||||
|
||||
V2.1.0: 2020-7-27 Momo
|
||||
1<><31><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>¼<EFBFBD>룬<EFBFBD><EBA3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>30~99%֮<>䡣
|
||||
2<><32><EFBFBD><EFBFBD>FW<46>汾<EFBFBD><E6B1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>V1_36<33><36>
|
||||
|
||||
V2.2.0<EFBFBD><EFBFBD>2020-8-21 Qizhenbiao
|
||||
1<><31><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><DEB6>ģ<DEB8>30~95%֮<>䣬<EFBFBD><E4A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD>ܾ<F3B2A2BE>¼<EFBFBD><C2BC>
|
||||
2<><32><EFBFBD>ڶ<EFBFBD><DAB6>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD>С<EFBFBD>ڵ<EFBFBD><DAB5>ڵ<EFBFBD>һ<EFBFBD>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD>ܾ<F3B2A2BE>¼<EFBFBD><C2BC>
|
||||
3<><33><EFBFBD>ڶ<EFBFBD><DAB6>ε<EFBFBD><CEB5><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>һ<EFBFBD><D2BB>¼<EFBFBD><C2BC><EFBFBD><EFBFBD>48~144Сʱ<D0A1><CAB1>2~6<>죩֮<ECA3A9>䣬<EFBFBD><E4A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD>ܾ<F3B2A2BE>¼<EFBFBD><C2BC>
|
||||
4<><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ǰ<EFBFBD><C7B0><EFBFBD>£<EFBFBD><C2A3><EFBFBD><EFBFBD>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-5%~0%֮<>䣬<EFBFBD><E4A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD><CEA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>룬<EFBFBD>ж<EFBFBD>Ϊʧ<CEAA>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ժ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ,<2C><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>PASS<53><53>FAIL<49><4C>ʾ<EFBFBD><CABE>
|
||||
5<><35><EFBFBD>ڼ<EFBFBD><DABC>ز<EFBFBD><D8B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD>4<EFBFBD><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
6<><36><EFBFBD>ڼ<EFBFBD><DABC>ز<EFBFBD><D8B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0%<25><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ժ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>ֱ<EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
7<><37><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˫<EFBFBD><CBAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><F2A3ACB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
8<><38>״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳ<EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD>һ<EFBFBD><D2BB>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD>
|
||||
|
||||
V2.2.1.1<EFBFBD><EFBFBD>2020-8-21 Qizhenbiao
|
||||
1<><31>ָ<EFBFBD><D6B8>Sn<53><6E>ѯʱ<D1AF><CAB1>Ӧ<EFBFBD><D3A6>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>ѯ<EFBFBD><D1AF>ͳ<EFBFBD>ƹ<EFBFBD><C6B9>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD>¼<EFBFBD><C2BC>ʾ<EFBFBD><CABE>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD>Բ<EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>ɫ<EFBFBD><C9AB>δ<EFBFBD><CEB4><EFBFBD>ɲ<EFBFBD><C9B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>ɫ<EFBFBD><C9AB>
|
||||
2<><32>Sn<53><6E>ѯ֧<D1AF><D6A7>ɨ<EFBFBD><C9A8><EFBFBD><EFBFBD><EFBFBD>룬<EFBFBD><EBA3AC><EFBFBD><EFBFBD>ѯһ<D1AF><D2BB><EFBFBD><EFBFBD><EFBFBD>ݲ<EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD>ַ<EFBFBD>Χ<EFBFBD><CEA7><EFBFBD>ݲ<EFBFBD>ѯ<EFBFBD><D1AF>
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯʱ<D1AF><CAB1><EFBFBD>꽹<EFBFBD><EABDB9><EFBFBD>Զ<EFBFBD><D4B6>ص<EFBFBD>SN<53><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><F2A3ACB2>ҽ<EFBFBD><D2BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫѡ<C8AB><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɨ<EFBFBD><C9A8>ǹɨ<C7B9><C9A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
3<><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯʱ<D1AF><CAB1>pass<73><73>fail<69><6C>ʾ<EFBFBD><CABE>ɫ<EFBFBD><C9AB>ͬʱ<CDAC><CAB1><EFBFBD>Ͻ<EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD>ʾPASS<53><53>FAIL<49><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD>в<EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>---<2D><><EFBFBD><EFBFBD>
|
||||
4, ÿ<>γ<EFBFBD><CEB3><EFBFBD><EFBFBD>ر<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݲ<EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>xls<6C><73>ʽ<EFBFBD>ı<EFBFBD><C4B1>ݡ<EFBFBD>
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> app.path\DATA\BAK\ Ŀ¼<C4BF>£<EFBFBD><C2A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DAT_BAK_20200827_111606<30><36>
|
||||
|
||||
V2.2.2.0<EFBFBD><EFBFBD>2020-8-21 Qizhenbiao
|
||||
1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>зǿ<D0B7><C7BF>жϣ<D0B6><CFA3><EFBFBD><DEB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>ʱ<EFBFBD><CAB1><EFBFBD>µ<EFBFBD><C2B5>쳣<EFBFBD><ECB3A3>
|
||||
|
||||
|
||||
V2.3.0.0<EFBFBD><EFBFBD>2020-9-10 MomoWen
|
||||
1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ԭ2~6<>죬<EFBFBD><ECA3AC>Ϊ8~12<31>졣
|
||||
2<><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭС<D4AD>ڵ<EFBFBD><DAB5><EFBFBD>5%<25><><EFBFBD><EFBFBD>ΪС<CEAA><D0A1>5%<25><>
|
||||
3<><33>ÿ<EFBFBD>ιرճ<D8B1><D5B3><EFBFBD><F2A3ACB1><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
|
||||
|
||||
V2.4.0.0<EFBFBD><EFBFBD>2020-9-15 QiZhengbiao
|
||||
1<><31><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>һ<EFBFBD>Ρ<EFBFBD><CEA1>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD><DDB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㣬ֱ<E3A3AC>ӱȽϵ<C8BD><CFB5><EFBFBD>ֵ<EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>=50%Ϊpass<73><73>
|
||||
2<><32>load<61><64><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Dz<EFBFBD><C7B2><EFBFBD><EFBFBD><EFBFBD>pass<73><73>fail<69>ж<EFBFBD>
|
||||
3<><33>load<61><64><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>Ե<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD><DDBC><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϣ<D0B6>С<EFBFBD><D0A1>8<EFBFBD><38><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>12<31><32><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><C3B5><EFBFBD>ɫ<EFBFBD><C9AB>ɫ<EFBFBD><C9AB>ע<EFBFBD><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD>Ե<EFBFBD><D4B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>pass<73><73>fail<69><6C><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>
|
||||
4<><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>һ<EFBFBD>㣬<EFBFBD><E3A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><DDB1><EFBFBD>
|
||||
|
||||
V2.5.0.0:2020-11-02 Qizengbiao
|
||||
1.<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>UTS_Core<72><65><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><DDB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><DDB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
V2.5.1.0:2020-12-09 Qizengbiao
|
||||
1.<2E><><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD>ԭ8~12<31>죬<EFBFBD><EFBFBD>Ϊ6~12<31><32>
|
||||
|
||||
V2.5.3.0:2020-12-10 Qizengbiao
|
||||
1.<2E>ϴ<EFBFBD><CFB4><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΪDevSN<53>ֶ<EFBFBD>
|
||||
2.<2E><>һ<EFBFBD><D2BB>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>Ӽ<EFBFBD>¼UserID<49><44>StartTime
|
||||
3.<2E>ڶ<EFBFBD><DAB6><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>Ӽ<EFBFBD>¼TestResult
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user