初始化提交

仓库转移到Gitea,初始化提交,可能丢失以前的git版本日志
This commit is contained in:
2025-11-27 16:41:05 +08:00
commit 027d0f8024
663 changed files with 171319 additions and 0 deletions

View File

@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30804.86
MinimumVisualStudioVersion = 10.0.40219.1
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "AUTS_UpdateService", "AUTS_UpdateService.vbproj", "{1B6959C2-F675-4596-B065-2394EA66C970}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1B6959C2-F675-4596-B065-2394EA66C970}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1B6959C2-F675-4596-B065-2394EA66C970}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1B6959C2-F675-4596-B065-2394EA66C970}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1B6959C2-F675-4596-B065-2394EA66C970}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B94D74EA-7725-498A-9DED-D8AF04DFF9EB}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,195 @@
<?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>{1B6959C2-F675-4596-B065-2394EA66C970}</ProjectGuid>
<OutputType>WinExe</OutputType>
<StartupObject>AUTS_UpdateService.UpdateService</StartupObject>
<RootNamespace>AUTS_UpdateService</RootNamespace>
<AssemblyName>AUTS_UpdateService</AssemblyName>
<FileAlignment>512</FileAlignment>
<MyType>Console</MyType>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<IsWebBootstrapper>true</IsWebBootstrapper>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Web</InstallFrom>
<UpdateEnabled>true</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<InstallUrl>http://auth.blv-oa.com/Apps/AUTS_UpdateService/</InstallUrl>
<ProductName>UpdateServise</ProductName>
<PublisherName>ML</PublisherName>
<MinimumRequiredVersion>1.0.0.0</MinimumRequiredVersion>
<CreateWebPageOnPublish>true</CreateWebPageOnPublish>
<WebPage>Index.html</WebPage>
<ApplicationRevision>1</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<PublishWizardCompleted>true</PublishWizardCompleted>
<BootstrapperEnabled>true</BootstrapperEnabled>
</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_UpdateService.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_UpdateService.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>
<PropertyGroup>
<ApplicationManifest>My Project\app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup>
<SignManifests>false</SignManifests>
</PropertyGroup>
<PropertyGroup>
<ManifestCertificateThumbprint>0A24DBE81683427A18C6FFDAD761CAAF5FF0B642</ManifestCertificateThumbprint>
</PropertyGroup>
<PropertyGroup>
<GenerateManifests>true</GenerateManifests>
</PropertyGroup>
<PropertyGroup>
<TargetZone>LocalIntranet</TargetZone>
</PropertyGroup>
<ItemGroup>
<Reference Include="FluentFTP, Version=33.0.3.0, Culture=neutral, PublicKeyToken=f4af092b1d8df44f, processorArchitecture=MSIL">
<HintPath>..\packages\FluentFTP.33.0.3\lib\net45\FluentFTP.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration.Install" />
<Reference Include="System.Data" />
<Reference Include="System.Management" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
</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="ApplicationLog.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="UpdatePackageInfo.vb" />
<Compile Include="UpdateService.vb">
<SubType>Component</SubType>
</Compile>
<Compile Include="UpdateService.Designer.vb">
<DependentUpon>UpdateService.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="WinService.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\app.manifest" />
<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" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="FluentFTP.dll" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.8">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.8 %28x86 和 x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</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>

Binary file not shown.

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.4.0" newVersion="4.1.4.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.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="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
</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>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -0,0 +1,199 @@
Imports System.Management
Imports System.Threading
Imports UTS_Core.Database
Imports UTS_Core.UTSModule
Imports UTS_Core.UTSModule.DbConnect
Imports UTS_Core.UTSModule.DbTableModel.Manage
Public Class ApplicationLog
Private Shared _serviceRunning As Boolean
Private Shared _startThread As Thread
Private Shared ReadOnly LogLock As Object = New Object()
Private Shared ReadOnly LogQueue As New Queue(Of Dictionary(Of String, String))
''' <summary>
''' 厂商名
''' </summary>
Public Shared VendorName As String
Public Shared Sub WriteErrorLog(msg As String)
UTS_Core.DebugLog.ApplicationLog.WriteErrorLog(msg)
WriteLogToLogQueue($"{UTS_Core.DebugLog.ApplicationLog.LogTypes.Error}", msg)
End Sub
Public Shared Sub WriteWarningLog(msg As String)
UTS_Core.DebugLog.ApplicationLog.WriteWarningLog(msg)
WriteLogToLogQueue($"{UTS_Core.DebugLog.ApplicationLog.LogTypes.Warn}", msg)
End Sub
Public Shared Sub WriteTraceLog(msg As String)
UTS_Core.DebugLog.ApplicationLog.WriteInfoLog(msg)
WriteLogToLogQueue($"{UTS_Core.DebugLog.ApplicationLog.LogTypes.Info}", msg)
End Sub
Private Shared Sub WriteLogToLogQueue(logType As String, msg As String)
Try
Static mac As String = ""
Static ip As String = ""
If String.IsNullOrEmpty(mac) OrElse String.IsNullOrEmpty(ip) Then
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()
Dim a() As String = CType(mo("IpAddress"), String())
ip = a(0)
Exit For
End If
Next
End If
Static userName As String = Environment.UserName '获取用户名 eg:Admin
Static machineName As String = Environment.MachineName '获取电脑名称 PC
Static osVersion As String = Environment.OSVersion.VersionString 'os 版本
Static appName As String = $"{My.Application.Info.ProductName}" 'os 版本
Static appVersion As String = $"{My.Application.Info.Version}" 'os 版本
Dim dicFiled As New Dictionary(Of String, String)
dicFiled.Add($"{ServiceLogTable.ColNamesEnum.DateTime}", Date.Now.ToString("yyyy-MM-dd HH:mm:ss"))
dicFiled.Add($"{ServiceLogTable.ColNamesEnum.DevPrivateIP}", ip)
dicFiled.Add($"{ServiceLogTable.ColNamesEnum.DevMac}", mac)
dicFiled.Add($"{ServiceLogTable.ColNamesEnum.DevOS}", osVersion)
dicFiled.Add($"{ServiceLogTable.ColNamesEnum.DevName}", machineName)
dicFiled.Add($"{ServiceLogTable.ColNamesEnum.DevUserName}", userName)
dicFiled.Add($"{ServiceLogTable.ColNamesEnum.LogType}", logType)
dicFiled.Add($"{ServiceLogTable.ColNamesEnum.LogText}", msg.Replace("'", "_"))
dicFiled.Add($"{ServiceLogTable.ColNamesEnum.CompanyName}", VendorName)
dicFiled.Add($"{ServiceLogTable.ColNamesEnum.AppName}", appName)
dicFiled.Add($"{ServiceLogTable.ColNamesEnum.AppVersion}", appVersion)
SyncLock LogLock
LogQueue.Enqueue(dicFiled) '将日志信息放入缓冲队列
End SyncLock
Catch ex As Exception
UTS_Core.DebugLog.ApplicationLog.WriteErrorLog($"Write ApplicationLog To LogQueue Error:{ex.Message}")
End Try
End Sub
Private Shared Sub WriteLogT()
End Sub
Private Shared Sub WriteLogToDatabase()
Static firstJoin As Boolean = True
If String.IsNullOrWhiteSpace(UtsDb.LocalConnString) Then
UTS_Core.DebugLog.ApplicationLog.WriteErrorLog($"Invalid LocalConnString!")
Return
End If
Try
Using db As New DbExecutor(UtsDb.LocalDbType, UtsDb.LocalConnString)
db.Open()
If firstJoin Then
db.ExecuteNonQuery(ServiceLogTable.CreateTableString(DbExecutor.DbTypeEnum.Sqlite))
firstJoin = False
End If
db.BeginTransaction()
Dim dicFiled As Dictionary(Of String, String)
Dim cmdText As String
Dim cmdHelper As DbCmdHelper = DbCmdHelper.CreateCmdHelper(UtsDb.RemoteDbType)
For i As Integer = 0 To LogQueue.Count - 1
dicFiled = LogQueue.Dequeue()
cmdText = db.CmdHelper.Insert(ServiceLogTable.TableName, dicFiled)
db.ExecuteNonQuery(cmdText) '执行语句
cmdText = cmdHelper.DbInsert(UtsDb.RemotePublicDb, ServiceLogTable.TableName, dicFiled)
DbConnector.SaveCmdStringToCacheTable(db, cmdText) '执行命令入缓存库
Next
db.CommitTransaction()
db.Close()
End Using
Catch ex As Exception
UTS_Core.DebugLog.ApplicationLog.WriteErrorLog($"Write ApplicationLog To LocalDB Error:{ex.Message}")
End Try
End Sub
Private Shared Sub LogQueueMonitor()
Static writeInterval As Integer = 16 '写入间隔单位S
Static writeMinValue As Integer = 64 '写入数据库最小值包数
Static lastWriteTime As DateTime = Now '上一次写入间隔
While _serviceRunning
If (LogQueue.Count >= writeMinValue) OrElse ((Now - lastWriteTime).TotalSeconds >= writeInterval) Then
WriteLogToDatabase()
lastWriteTime = Now
End If
Thread.Sleep(100)
End While
End Sub
''' <summary>
''' 初始化应用日志信息
''' </summary>
Public Shared Sub InitApplicationLogInfo(logDirPath As String, logFilePrefix As String)
UTS_Core.DebugLog.ApplicationLog.LogDirPath = logDirPath
UTS_Core.DebugLog.ApplicationLog.LogFilePrefix = logFilePrefix
End Sub
''' <summary>
''' 开启更新服务监听
''' </summary>
Public Shared Sub StartSaveLogToDatabase()
_serviceRunning = True
If _startThread IsNot Nothing AndAlso _startThread.IsAlive Then
StopSaveLogToDatabase()
End If
_startThread = New Thread(AddressOf LogQueueMonitor)
_startThread.Start()
End Sub
Public Shared Sub StopSaveLogToDatabase()
_serviceRunning = False
Dim lastTime As DateTime = Now
While _startThread IsNot Nothing AndAlso _startThread.IsAlive
If (Now - lastTime).TotalMilliseconds > 1000 Then
_startThread.Abort()
End If
Thread.Sleep(10)
End While
If LogQueue.Count > 0 Then
WriteLogToDatabase()
End If
End Sub
End Class

Binary file not shown.

View File

@@ -0,0 +1,50 @@
Imports FluentFTP
Public Class FtpService
Private _ftpUser As String
Private _ftpPwd As String
Private _ftpPort As Integer
Private _ftpHost As String
Sub New(host As String, port As Integer, user As String, pwd As String)
_ftpHost = host
_ftpPort = port
_ftpUser = user
_ftpPwd = pwd
End Sub
Private Sub OnValidateCertificate(control As FtpClient, e As FtpSslValidationEventArgs)
e.Accept = True
End Sub
''' <summary>
''' 文件上传
''' 将本地指定路径压缩包上传到FTP服务器上manager文件夹下
''' </summary>
Public Sub FtpUpload(remotePath As String, loadPath As String)
Using ftpClient As FtpClient = New FtpClient(_ftpHost, _ftpPort, _ftpUser, _ftpPwd)
AddHandler ftpClient.ValidateCertificate, AddressOf OnValidateCertificate
ftpClient.EncryptionMode = FtpEncryptionMode.Auto
ftpClient.Connect()
ftpClient.UploadFile(loadPath, remotePath)
ftpClient.Disconnect()
End Using
End Sub
''' <summary>
''' 文件下载
''' 从FTP下载压缩包到本地指定路径
''' </summary>
Public Sub FtpDownload(remotePath As String, loadPath As String)
Using ftpClient As FtpClient = New FtpClient(_ftpHost, _ftpPort, _ftpUser, _ftpPwd)
AddHandler ftpClient.ValidateCertificate, AddressOf OnValidateCertificate
ftpClient.EncryptionMode = FtpEncryptionMode.Auto
ftpClient.Connect()
ftpClient.DownloadFile(loadPath, remotePath)
ftpClient.Disconnect()
End Using
End Sub
End Class

View File

@@ -0,0 +1,13 @@
'------------------------------------------------------------------------------
' <auto-generated>
' 此代码由工具生成。
' 运行时版本:4.0.30319.42000
'
' 对此文件的更改可能会导致不正确的行为,并且如果
' 重新生成代码,这些更改将会丢失。
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On

View 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>

View File

@@ -0,0 +1,35 @@
Imports System
Imports System.Reflection
Imports System.Runtime.InteropServices
' 有关程序集的一般信息由以下
' 控制。更改这些特性值可修改
' 与程序集关联的信息。
'查看程序集特性的值
<Assembly: AssemblyTitle("AUTS_UpdateService")>
<Assembly: AssemblyDescription("")>
<Assembly: AssemblyCompany("Microsoft")>
<Assembly: AssemblyProduct("AUTS_UpdateService")>
<Assembly: AssemblyCopyright("Copyright © Microsoft 2021")>
<Assembly: AssemblyTrademark("")>
<Assembly: ComVisible(False)>
'如果此项目向 COM 公开,则下列 GUID 用于 typelib 的 ID
<Assembly: Guid("2ab29d81-279d-4235-8747-1f1a04986539")>
' 程序集的版本信息由下列四个值组成:
'
' 主版本
' 次版本
' 生成号
' 修订号
'
'可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
'通过使用 "*",如下所示:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("2.4.3.0")>
<Assembly: AssemblyFileVersion("2.4.3.0")>

View 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_UpdateService.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

View 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>

View File

@@ -0,0 +1,73 @@
'------------------------------------------------------------------------------
' <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
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_UpdateService.My.MySettings
Get
Return Global.AUTS_UpdateService.My.MySettings.Default
End Get
End Property
End Module
End Namespace

View File

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" UseMySettingsClassName="true">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC 清单选项
如果想要更改 Windows 用户帐户控制级别,请使用
以下节点之一替换 requestedExecutionLevel 节点。n
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
指定 requestedExecutionLevel 元素将禁用文件和注册表虚拟化。
如果你的应用程序需要此虚拟化来实现向后兼容性,则删除此
元素。
-->
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
<applicationRequestMinimum>
<PermissionSet Unrestricted="true" ID="Custom" SameSite="site" />
<defaultAssemblyRequest permissionSetReference="Custom" />
</applicationRequestMinimum>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- 设计此应用程序与其一起工作且已针对此应用程序进行测试的
Windows 版本的列表。取消评论适当的元素,
Windows 将自动选择最兼容的环境。 -->
<!-- Windows Vista -->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
<!-- Windows 7 -->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
<!-- Windows 8 -->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
<!-- Windows 8.1 -->
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
<!-- Windows 10 -->
<!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
</application>
</compatibility>
<!-- 指示该应用程序可感知 DPI 且 Windows 在 DPI 较高时将不会对其进行
自动缩放。Windows Presentation Foundation (WPF)应用程序自动感知 DPI无需
选择加入。选择加入此设置的 Windows 窗体应用程序(面向 .NET Framework 4.6)还应
在其 app.config 中将 "EnableWindowsFormsHighDpiAutoResizing" 设置设置为 "true"。
将应用程序设为感知长路径。请参阅 https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation -->
<!--
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
-->
<!-- 启用 Windows 公共控件和对话框的主题(Windows XP 和更高版本) -->
<!--
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
-->
</assembly>

View 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_UpdateService"
Me.ServiceInstaller1.DisplayName = "AUTS_UpdateService"
Me.ServiceInstaller1.ServiceName = "AUTS_UpdateService"
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

View 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>17, 17</value>
</metadata>
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
</root>

View 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

View File

@@ -0,0 +1,212 @@
Imports Microsoft.Win32.Registry
Public Class Registry
''' <summary>
''' 注册表存放根路径配置信息
''' </summary>
Public Shared ReadOnly AutsRootDirPath As String = $"software\AUTS"
''' <summary>
''' 注册表存放数据服务名称配置信息
''' </summary>
Public Shared ReadOnly _dataServiceName As String = $"AUTS_DataService"
''' <summary>
''' 注册表存放更新服务名称配置信息
''' </summary>
Public Shared ReadOnly _updateServiceName As String = $"AUTS_UpdateService"
''' <summary>
''' 获取注册表是否存在
''' </summary>
''' <returns></returns>
Public Shared Function RootDirExists() As Boolean
Return LocalMachine.OpenSubKey(AutsRootDirPath) IsNot Nothing
End Function
''' <summary>
''' 获取和设置Root根文件路径
''' </summary>
''' <returns></returns>
Public Shared Property RootPath() As String
Get
Return LocalMachine.OpenSubKey($"{AutsRootDirPath}").GetValue("Path", "").ToString()
End Get
Set(value As String)
LocalMachine.CreateSubKey($"{AutsRootDirPath}").SetValue("Path", value, Microsoft.Win32.RegistryValueKind.String)
End Set
End Property
''' <summary>
''' 获取和设置License路径
''' </summary>
''' <returns></returns>
Public Shared Property LicensePath() As String
Get
Return LocalMachine.OpenSubKey($"{AutsRootDirPath}\License").GetValue("Path", "").ToString()
End Get
Set(value As String)
LocalMachine.CreateSubKey($"{AutsRootDirPath}\License").SetValue("Path", value, Microsoft.Win32.RegistryValueKind.String)
End Set
End Property
''' <summary>
''' 获取和设置LocalDb路径
''' </summary>
''' <returns></returns>
Public Shared Property LocalDb() As String
Get
Return LocalMachine.OpenSubKey($"{AutsRootDirPath}\LocalDb").GetValue("Path", "").ToString()
End Get
Set(value As String)
LocalMachine.CreateSubKey($"{AutsRootDirPath}\LocalDb").SetValue("Path", value, Microsoft.Win32.RegistryValueKind.String)
End Set
End Property
''' <summary>
''' 获取和设置DataService名称
''' </summary>
''' <returns></returns>
Public Shared Property DataServiceName() As String
Get
Return LocalMachine.OpenSubKey($"{AutsRootDirPath}\{_dataServiceName}").GetValue("Name", "").ToString()
End Get
Set(value As String)
LocalMachine.CreateSubKey($"{AutsRootDirPath}\{_dataServiceName}").SetValue("Name", value, Microsoft.Win32.RegistryValueKind.String)
End Set
End Property
''' <summary>
''' 获取和设置DataService版本信息
''' </summary>
''' <returns></returns>
Public Shared Property DataServiceVersion() As String
Get
Return LocalMachine.OpenSubKey($"{AutsRootDirPath}\{_dataServiceName}").GetValue("Version", "").ToString()
End Get
Set(value As String)
LocalMachine.CreateSubKey($"{AutsRootDirPath}\{_dataServiceName}").SetValue("Version", value, Microsoft.Win32.RegistryValueKind.String)
End Set
End Property
''' <summary>
''' 获取和设置UpdateService名称
''' </summary>
''' <returns></returns>
Public Shared Property UpdateServiceName() As String
Get
Return LocalMachine.OpenSubKey($"{AutsRootDirPath}\{_updateServiceName}").GetValue("Name", "").ToString()
End Get
Set(value As String)
LocalMachine.CreateSubKey($"{AutsRootDirPath}\{_updateServiceName}").SetValue("Name", value, Microsoft.Win32.RegistryValueKind.String)
End Set
End Property
''' <summary>
''' 获取和设置UpdateService版本信息
''' </summary>
''' <returns></returns>
Public Shared Property UpdateServiceVersion() As String
Get
Return LocalMachine.OpenSubKey($"{AutsRootDirPath}\{_updateServiceName}").GetValue("Version", "").ToString()
End Get
Set(value As String)
LocalMachine.CreateSubKey($"{AutsRootDirPath}\{_updateServiceName}").SetValue("Version", value, Microsoft.Win32.RegistryValueKind.String)
End Set
End Property
''' <summary>
''' 获取和设置DataService文件路径
''' </summary>
''' <returns></returns>
Public Shared Property DataServiceDirPath() As String
Get
Return LocalMachine.OpenSubKey($"{AutsRootDirPath}\{_dataServiceName}").GetValue("DirPath", "").ToString()
End Get
Set(value As String)
LocalMachine.CreateSubKey($"{AutsRootDirPath}\{_dataServiceName}").SetValue("DirPath", value, Microsoft.Win32.RegistryValueKind.String)
End Set
End Property
''' <summary>
''' 获取和设置DataService启动程序名称
''' </summary>
''' <returns></returns>
Public Shared Property DataServiceExeName() As String
Get
Return LocalMachine.OpenSubKey($"{AutsRootDirPath}\{_dataServiceName}").GetValue("ExeName", "").ToString()
End Get
Set(value As String)
LocalMachine.CreateSubKey($"{AutsRootDirPath}\{_dataServiceName}").SetValue("ExeName", value, Microsoft.Win32.RegistryValueKind.String)
End Set
End Property
''' <summary>
''' 获取和设置UpdateService文件路径
''' </summary>
''' <returns></returns>
Public Shared Property UpdateServiceDirPath() As String
Get
Return LocalMachine.OpenSubKey($"{AutsRootDirPath}\{_updateServiceName}").GetValue("DirPath", "").ToString()
End Get
Set(value As String)
LocalMachine.CreateSubKey($"{AutsRootDirPath}\{_updateServiceName}").SetValue("DirPath", value, Microsoft.Win32.RegistryValueKind.String)
End Set
End Property
''' <summary>
''' 获取和设置UpdateService启动程序名称
''' </summary>
''' <returns></returns>
Public Shared Property UpdateServiceExeName() As String
Get
Return LocalMachine.OpenSubKey($"{AutsRootDirPath}\{_updateServiceName}").GetValue("ExeName", "").ToString()
End Get
Set(value As String)
LocalMachine.CreateSubKey($"{AutsRootDirPath}\{_updateServiceName}").SetValue("ExeName", value, Microsoft.Win32.RegistryValueKind.String)
End Set
End Property
End Class

View File

@@ -0,0 +1,38 @@
Public Class UpdatePackageInfo
''' <summary>
''' 软件索引
''' </summary>
''' <returns></returns>
Property SoftwareID() As Integer
''' <summary>
''' 软件名称
''' </summary>
''' <returns></returns>
Property SoftwareName() As String
''' <summary>
''' 软件最新版本
''' </summary>
''' <returns></returns>
Property LastVersion() As String
''' <summary>
''' 软件包MD5
''' </summary>
''' <returns></returns>
Property BinPackageMd5() As String
''' <summary>
''' 软件包名,不含完整路径
''' </summary>
''' <returns></returns>
Property PackageName() As String
''' <summary>
''' 软件发布日期
''' </summary>
''' <returns></returns>
Property ReleaseDate() As DateTime
End Class

View File

@@ -0,0 +1,48 @@
Imports System.ServiceProcess
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class UpdateService
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 UpdateService}
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

View File

@@ -0,0 +1,769 @@
Imports System.IO
Imports System.Threading
Imports UTS_Core.Compress
Imports UTS_Core.Database
Imports UTS_Core.Security
Imports UTS_Core.UTSModule
Imports UTS_Core.UTSModule.License
Imports UTS_Core.UTSModule.Service
Imports UTS_Core.UTSModule.DbConnect
Imports UTS_Core.UTSModule.DbTableModel.Manage
Imports System.Text
Public Class UpdateService
''' <summary> AUTS_DataService服务名 </summary>
Private _dsName As String
''' <summary> AUTS_DataService的索引 </summary>
Private _dsIndex As String
''' <summary>数据服务的文件夹路径,不包含版本</summary>
Private _dsDirPath As String
''' <summary>数据服务升级时存放从FTP下载的最新包文件夹路径</summary>
Private _dsPacketDirPath As String
''' <summary>服务本地版本</summary>
Private _dsVersion As String
''' <summary>数据服务在线状态0离线1在线</summary>
Private _dsOnline As Integer
''' <summary>服务上一次本地版本</summary>
Private _lastDsVersion As String
''' <summary>当前服务正在运行</summary>
Private _serviceRunning As Boolean
''' <summary>Log文件夹路径</summary>
Private _logDirPath As String
''' <summary>设置文件夹路径</summary>
Private _settingsDirPath As String
''' <summary>更新服务版本</summary>
Private _usVersion As String
''' <summary>更新服务版本</summary>
Private _usErrMsg As String
''' <summary>更新服务名称</summary>
Private _usName As String
''' <summary>是否已更新过版本</summary>
Private _uploaded As Boolean
''' <summary>当前服务正在升级</summary>
Private _serviceUpdating As Boolean
''' <summary>等待检测服务</summary>
Private _waitCheckService As Boolean
Protected Overrides Sub OnStart(args() As String)
' 请在此处添加代码以启动您的服务。此方法应完成设置工作,
' 以使您的服务开始工作。
Thread.Sleep(3000)
InitServiceInfo()
CreateSystemFolder()
ApplicationLog.InitApplicationLogInfo(_logDirPath, My.Application.Info.ProductName)
If CheckLicense() = False Then Return
UtsDb.InitConnectParams(_license) '根据License信息,初始化数据库连接信息
UTS_Core.DebugLog.ApplicationLog.WriteInfoLog($"InitConnectParams Success.")
ApplicationLog.VendorName = _license.VendorName '写入数据前指定软件公司名
ApplicationLog.StartSaveLogToDatabase() '需要先指定数据库路径
_ftpClient = New FtpService(UtsRegistry.FtpHost, CInt(_license.FtpPort), _license.FtpUser, _license.FtpPwd)
_serviceRunning = True
ApplicationLog.WriteTraceLog($"Start Monitor!")
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf KeepServiceConnect))
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf UpdateMonitor))
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf UpdateServiceInfo))
End Sub
Protected Overrides Sub OnStop()
' 在此处添加代码以执行任何必要的拆解操作,从而停止您的服务。
StopUpdateMonitor()
ApplicationLog.WriteTraceLog($"UpdateService OnStop")
ApplicationLog.StopSaveLogToDatabase()
End Sub
#Region "准备工作"
''' <summary>
''' 初始化服务信息
''' </summary>
Private Sub InitServiceInfo()
_dsOnline = 1
_dsIndex = UtsRegistry.DataServiceIndex
_dsName = UtsRegistry.DataServiceName
_dsDirPath = $"{UtsRegistry.RootPath}\{UtsRegistry.DataServiceName}"
_dsPacketDirPath = $"{UtsRegistry.RootPath}\DataServiceDownload"
_usName = My.Application.Info.ProductName
_usVersion = My.Application.Info.Version.ToString
_usErrMsg = String.Empty
_logDirPath = $"{UtsRegistry.RootPath}\Log\{My.Application.Info.ProductName}"
_settingsDirPath = $"{UtsRegistry.UpdateServiceDirPath}\Settings"
UtsRegistry.UpdateServiceVersion = _usVersion
End Sub
''' <summary>
''' 创建运行时必要文件夹
''' </summary>
Private Sub CreateSystemFolder()
Directory.CreateDirectory(_dsDirPath) '数据服务文件夹路径
Directory.CreateDirectory(_dsPacketDirPath) '数据服务下载文件夹路径
Directory.CreateDirectory(_settingsDirPath) '创建设置文件夹
Directory.CreateDirectory(_logDirPath) '创建日志文件夹
End Sub
''' <summary>
''' 关闭更新服务
''' </summary>
Private Sub StopUpdateMonitor()
_serviceRunning = False
End Sub
#End Region
#Region "更新服务操作"
''' <summary>
''' 保持与服务的定期通讯
''' </summary>
Private Sub KeepServiceConnect(obj As Object)
While _serviceRunning
Thread.Sleep(1000)
'升级状态中,取消通讯
If _serviceUpdating Then Continue While
'开始通讯
If InitTcpClient() AndAlso GetServiceLocalVersion() Then '初始化网络客户端连接,进行获取版本号通讯
ResetServiceHeartBeatFailCount()
Else
UpdateServiceHeartBeatFailCount()
End If
End While
End Sub
''' <summary>
''' 定期更新数据库中服务的状态
''' </summary>
Private Sub UpdateServiceInfo(obj As Object)
Dim Interval As Integer = 1 * 60 * 1000
While _serviceRunning
Dim sb As New StringBuilder
sb.Append($"update `{UtsDb.RemotePublicDb}`.`{DataServiceListTable.TableName}` set ")
sb.Append($"`{DataServiceListTable.ColNames.USVer}` = '{_usVersion}' ")
sb.Append($",`{DataServiceListTable.ColNames.IsOnline}` = {_dsOnline} ")
sb.Append($",`{DataServiceListTable.ColNames.ServiceLastActiveDateTime}` = current_timestamp() ")
If String.IsNullOrEmpty(_usErrMsg) = False Then
sb.Append($",`{DataServiceListTable.ColNames.USErrMsg}` = '{_usErrMsg}' ")
_usErrMsg = String.Empty
End If
sb.Append($"where `{DataServiceListTable.ColNames.ID}` = {_dsIndex}")
Try
Using db As New DbExecutor(UtsDb.RemoteDbType, UtsDb.RemoteConnString)
db.Open()
db.ExecuteNonQuery(sb.ToString)
db.Close()
End Using
Catch ex As Exception
ApplicationLog.WriteErrorLog($"Update ServiceInfo Error:{ex.Message}")
End Try
Thread.Sleep(Interval)
End While
End Sub
''' <summary>
''' 定期检查DataService是否需要更新
''' </summary>
''' <param name="obj"></param>
Private Sub UpdateMonitor(obj As Object)
Dim Interval As Integer = 5 * 60 * 1000
While _serviceRunning
Try
DetectionService()
Catch ex As Exception
ApplicationLog.WriteErrorLog($"DetectionService Error:{ex.Message}")
End Try
'等待任务
Dim lastTime As Date = Now
_waitCheckService = True
While (Now - lastTime).TotalMilliseconds < Interval
If _waitCheckService = False Then
Exit While
End If
Thread.Sleep(1000)
End While
End While
End Sub
Private _startServiceFailCount As Integer = 0
Private ReadOnly _startServiceFailMaxCount As Integer = 3
Private _upgradeServiceFailCount As Integer = 0
Private ReadOnly _upgradeerviceFailMaxCount As Integer = 3
Private _serviceHeartBeatFailCount As Integer = 0
Private ReadOnly _serviceHeartBeatFailMaxCount As Integer = 30
''' <summary>
''' 检测服务
''' </summary>
Private Sub DetectionService()
'服务不存在处理
If WinService.ServicesExists(_dsName) = False Then
ApplicationLog.WriteTraceLog($"{_dsName} Service Not Exists,Begin Download Packet And Install Service!")
InstallDataService()
Return
End If
'服务存在未启动
If WinService.ServicesStatus(_dsName) <> WinService.ServiceStatusEnum.Started Then '存在,则检测是否启动
ApplicationLog.WriteTraceLog($"{_dsName} Service Not Running!Status:{WinService.ServicesStatus(_dsName)},Begin StartService!")
If WinService.StartService(_dsName) = False Then
UpdateStartServiceFailCount()
Return
End If
ApplicationLog.WriteTraceLog($"Start {_dsName} Service Success!")
Return
End If
'服务启动但失联
If _dsOnline = 0 Then
If WinService.RestartService(_dsName) = False Then
UpdateStartServiceFailCount()
Return
End If
ApplicationLog.WriteTraceLog($"ReStart {_dsName} Service Success!")
Return
End If
ResetStartServiceFailCount() '重置启动失败次数
If UpgradeDataService() Then
InstallDataService()
Else
Console.WriteLine($"服务已是最新版本!")
End If
End Sub
''' <summary>
''' 数据服务正常运行时,检查数据服务更新
''' </summary>
Private Function UpgradeDataService() As Boolean
'获取云端信息
Dim packetInfo As UpdatePackageInfo = GetDataServiceInfo()
If packetInfo Is Nothing Then Return False
'获取本地旧版本服务
Dim dataSerFilePath As String = UtsRegistry.DataServiceFilePath
'确定需要更新服务
If NeedToUpdateService(_dsVersion, packetInfo.LastVersion) = False Then
Return False
End If
ApplicationLog.WriteTraceLog($"Relldy To Update DataService,LocalVer:{_dsVersion},RemoteVer:{packetInfo.LastVersion}")
'卸载服务
Try
WinService.UnInstallService(dataSerFilePath, Nothing)
ApplicationLog.WriteTraceLog($"{dataSerFilePath} UnInstallService Success!")
Catch ex As Exception
ApplicationLog.WriteTraceLog($"{dataSerFilePath} UnInstallService Fail,{ex.Message}")
Return False
End Try
'ResetTcpConnection()
Return True
End Function
''' <summary>
''' 从远程获取数据服务信息,安装或覆盖数据服务
''' </summary>
''' <param name="serviceExists">服务存在状态,如果服务存在则覆盖原文件,不存在则安装服务</param>
Private Sub InstallDataService(Optional serviceExists As Boolean = False)
_serviceUpdating = True
Dim packetInfo As UpdatePackageInfo = GetDataServiceInfo()
If packetInfo Is Nothing Then Return
ApplicationLog.WriteTraceLog($"Begin DownloadServicePacket...")
If DownloadServicePacket(packetInfo, serviceExists) = False Then
ApplicationLog.WriteTraceLog($"DownloadServicePacket Fail!")
'添加下载失败计数
UpdateUpgradeFailCount()
_serviceUpdating = False
Return
End If
ApplicationLog.WriteTraceLog($"DownloadServicePacket Success!")
_serviceUpdating = False
End Sub
''' <summary>
''' 获取数据服务的最新信息
''' </summary>
Private Function GetDataServiceInfo() As UpdatePackageInfo
Try
If DbConnector.CanConnectToRemote = False Then '判断网络连接状态
ApplicationLog.WriteWarningLog($"Cant Connect To Database!")
Return Nothing
End If
Using db As New DbExecutor(UtsDb.RemoteDbType, UtsDb.RemoteConnString)
db.Open()
Dim tableName As String = $"{SwUpdateTable.TableName}"
Dim colNames As New List(Of String) From {
$"{SwUpdateTable.ColNamesEnum.LastVersion}",
$"{SwUpdateTable.ColNamesEnum.BinPackageMd5}",
$"{SwUpdateTable.ColNamesEnum.PackageName}"
}
Dim condition As String = $"`{SwUpdateTable.ColNamesEnum.SoftwareName}` = '{_dsName}'"
Dim dtServiceInfo As DataTable = db.ExecuteDataTable(db.CmdHelper.DbSearch(UtsDb.RemotePublicDb, colNames, tableName, condition))
If dtServiceInfo.Rows.Count <= 0 Then
ApplicationLog.WriteErrorLog($"Database Cant Find [{_dsName}] Software!")
db.Close()
Return Nothing
End If
Dim packetInfo As New UpdatePackageInfo
packetInfo.BinPackageMd5 = dtServiceInfo.Rows(0)($"{SwUpdateTable.ColNamesEnum.BinPackageMd5}").ToString()
packetInfo.LastVersion = dtServiceInfo.Rows(0)($"{SwUpdateTable.ColNamesEnum.LastVersion}").ToString()
packetInfo.PackageName = dtServiceInfo.Rows(0)($"{SwUpdateTable.ColNamesEnum.PackageName}").ToString()
db.Close()
Return packetInfo
End Using
Catch ex As Exception
ApplicationLog.WriteErrorLog($"GetServiceRemoteVersion Error:{ex.Message}!")
Return Nothing
End Try
End Function
''' <summary>
''' 重置心跳包失败计数
''' </summary>
Private Sub ResetServiceHeartBeatFailCount()
_serviceHeartBeatFailCount = 0
End Sub
''' <summary>
''' 心跳包通讯失败后,更新心跳包失败计数
''' </summary>
Private Sub UpdateServiceHeartBeatFailCount()
_serviceHeartBeatFailCount += 1
If _serviceHeartBeatFailCount < _serviceHeartBeatFailMaxCount Then Return
ApplicationLog.WriteErrorLog($"Services NetWork FailCount [{_serviceHeartBeatFailCount}] Is greater than the limit {_serviceHeartBeatFailMaxCount}")
_dsOnline = 0
ResetServiceHeartBeatFailCount()
ResetTcpConnection()
'立刻检测服务状态
_waitCheckService = False
End Sub
''' <summary>
''' 重置启动服务失败计数
''' </summary>
Private Sub ResetStartServiceFailCount()
_startServiceFailCount = 0
End Sub
''' <summary>
''' 重启或则启动服务失败后,更新启动服务失败计数,超过计数上限则重置数据服务内容
''' </summary>
Private Sub UpdateStartServiceFailCount()
_startServiceFailCount += 1
ApplicationLog.WriteWarningLog($"StartDataService Fail,FailCount:{_startServiceFailCount}!")
If _startServiceFailCount < _startServiceFailMaxCount Then Return
ApplicationLog.WriteErrorLog($"StartDataService Fail,FailCount:{_startServiceFailCount} Is Greater Than The Limit {_startServiceFailMaxCount},Begin Reset DataService!")
ResetStartServiceFailCount()
InstallDataService(WinService.ServicesExists(_dsName))
End Sub
Private Sub ResetUpgradeFailCount()
_upgradeServiceFailCount = 0
End Sub
Private Sub UpdateUpgradeFailCount()
_upgradeServiceFailCount += 1
ApplicationLog.WriteErrorLog($"Upgrade DataService Error,Count{_upgradeServiceFailCount}")
If _upgradeServiceFailCount >= 3 Then
_upgradeServiceFailCount = 0
_usErrMsg = "DataService unable upgrade"
ApplicationLog.WriteErrorLog($"DataService unable upgrade")
End If
End Sub
''' <summary>
''' 下载服务包,完成服务安装
''' </summary>
''' <param name="packetInfo">数据库中该程序包的信息</param>
''' <param name="serviceExists">服务是否已经安装</param>
''' <returns></returns>
Private Function DownloadServicePacket(packetInfo As UpdatePackageInfo, Optional serviceExists As Boolean = True) As Boolean
Dim localFilePath As String = $"{_dsPacketDirPath}\{packetInfo.PackageName}"
Dim ftpFilePath As String = $"{_ftpUpdateDirPath}/{packetInfo.PackageName}"
Dim newDataServiceVerDirPath As String = $"{_dsDirPath}\{packetInfo.LastVersion}"
'检测本地包是否存在
If Directory.Exists(_dsPacketDirPath) = False Then Directory.CreateDirectory(_dsPacketDirPath)
If Directory.Exists(newDataServiceVerDirPath) = False Then Directory.CreateDirectory(newDataServiceVerDirPath)
'下载FTP文件
If File.Exists(localFilePath) = False Then
ApplicationLog.WriteTraceLog($"Begin FtpDownloadFile...")
If FtpDownloadFile(ftpFilePath, localFilePath) = False Then
ApplicationLog.WriteErrorLog($"ftpPath:{ftpFilePath},localPath:{localFilePath},FtpDownloadFile Fail!")
Return False
End If
ApplicationLog.WriteTraceLog($"ftpPath:{ftpFilePath},localPath:{localFilePath},FtpDownloadFile Success!")
End If
Thread.Sleep(2000)
'更新包文件校验
ApplicationLog.WriteTraceLog($"Begin CheckDataServicePacket...")
If CheckDataServicePacket(localFilePath, packetInfo) = False Then
'文件非法,删除下载文件
ApplicationLog.WriteErrorLog($"CheckDataServicePacket Fail,Delete {localFilePath} File!")
File.Delete(localFilePath)
Return False
End If
ApplicationLog.WriteTraceLog($"CheckDataServicePacket Success!")
Thread.Sleep(2000)
'解压更新包
ApplicationLog.WriteTraceLog($"Begin Uncompress {localFilePath} File To {newDataServiceVerDirPath}...")
Try
Compress.LoadFromZip(newDataServiceVerDirPath, localFilePath)
Catch ex As Exception
ApplicationLog.WriteErrorLog($"Uncompress Fail!{ex.Message}")
Return False
End Try
ApplicationLog.WriteTraceLog($"Uncompress Success!")
Thread.Sleep(2000)
'安装服务
If serviceExists = False Then
ApplicationLog.WriteTraceLog($"Begin InstallService {newDataServiceVerDirPath}\{_dsName}...")
Try
WinService.InstallService($"{newDataServiceVerDirPath}\{_dsName}.exe", Nothing)
Catch ex As Exception
ApplicationLog.WriteErrorLog($"InstallService Fail,{ex.Message}")
Return False
End Try
End If
ApplicationLog.WriteTraceLog($"InstallService Success!")
'启动服务
ApplicationLog.WriteTraceLog($"Begin StartDataService...")
If WinService.StartService(_dsName) = False Then
ApplicationLog.WriteErrorLog($"StartDataService Fail!")
Return False
End If
ApplicationLog.WriteTraceLog($"StartDataService Success!")
_lastDsVersion = packetInfo.LastVersion
_uploaded = True
Return True
End Function
#End Region
#Region "自动更新"
''' <summary> 初始化FTP服务类 </summary>
Private _ftpClient As FtpService
''' <summary>Ftp远程升级文件夹路径</summary>
Private ReadOnly _ftpUpdateDirPath As String = $"/uts_Manager/AUTS/Service"
''' <summary>
''' 判断本地与云端版本号是否一致,不一致则代表需要更新数据服务
''' </summary>
''' <param name="localVer">本地数据服务版本号</param>
''' <param name="remoteVer">远端数据服务版本号</param>
''' <returns></returns>
Private Function NeedToUpdateService(localVer As String, remoteVer As String) As Boolean
If String.IsNullOrWhiteSpace(localVer) OrElse String.IsNullOrWhiteSpace(remoteVer) Then
ApplicationLog.WriteTraceLog($"Get Version Fail,LocalVer:{localVer},RemoteVer:{remoteVer}")
Return False
End If
If String.Compare(localVer, remoteVer) = 0 Then
ApplicationLog.WriteTraceLog($"No Need To Update DataService,LocalVer:{_dsVersion},RemoteVer:{remoteVer}")
Return False
End If
Return True
End Function
''' <summary>
''' Ftp下载文件
''' </summary>
''' <param name="ftpFilePath">Ftp文件路径</param>
''' <param name="localFilePath">本地文件路径</param>
''' <returns></returns>
Private Function FtpDownloadFile(ftpFilePath As String, localFilePath As String) As Boolean
ApplicationLog.WriteTraceLog($"soursePath:{ftpFilePath},targetPath:{localFilePath},Begin FtpDownloadFile...")
Try
_ftpClient.FtpDownload(ftpFilePath, localFilePath)
Catch ex As Exception
ApplicationLog.WriteErrorLog("Ftp DownloadFile Fail," & ex.Message)
Return False
End Try
ApplicationLog.WriteTraceLog($"Ftp DownloadFile Success!")
Return True
End Function
''' <summary>
''' 校验数据服务包
''' </summary>
''' <param name="localFilePath">本地文件路径</param>
''' <param name="packetInfo">压缩包信息</param>
''' <returns></returns>
Private Function CheckDataServicePacket(localFilePath As String, packetInfo As UpdatePackageInfo) As Boolean
Try
Dim localMd5 As String = Md5.GetFileMd5(localFilePath)
Dim remoteMd5 As String = packetInfo.BinPackageMd5
If String.Compare(localMd5, remoteMd5, True) <> 0 Then
ApplicationLog.WriteErrorLog($"CheckDataServicePacket Fail!localMd5:{localMd5},remoteMd5:{remoteMd5}")
Return False
End If
Catch ex As Exception
ApplicationLog.WriteErrorLog($"CheckDataServicePacket Error:{ex.Message}")
Return False
End Try
Return True
End Function
#End Region
#Region "服务通讯"
Private _tcpClient As AutsTcpClient
''' <summary> License检测 </summary>
Private _license As License
''' <summary> User </summary>
Private _user As String = "Admin"
''' <summary>
''' 初始化License内容
''' </summary>
Private Function CheckLicense() As Boolean
Try
Dim licensePath As String = UtsRegistry.LicenseFilePath
UTS_Core.DebugLog.ApplicationLog.WriteInfoLog($"Begin CheckLicense,Path:{licensePath}.")
_license = New License(licensePath)
_license.CheckLicense()
UTS_Core.DebugLog.ApplicationLog.WriteInfoLog($"CheckLicense Success.")
Catch ex As Exception
UTS_Core.DebugLog.ApplicationLog.WriteErrorLog($"CheckLicense Error:{ex.Message}.")
Return False
End Try
Return True
End Function
''' <summary>
''' 获取服务版本信息
''' </summary>
Public Function GetServiceLocalVersion() As Boolean
Dim taskParam As New TaskJsonParam(TaskJsonParam.CmdNamesEnum.GetServiceVersion, _user, _usName)
taskParam.ServiceVersion = _usVersion
Return ServiceCommunicator(taskParam)
End Function
''' <summary>
''' 初始化网络套接字
''' 注册表中无端口号时会引发异常
''' </summary>
Private Function InitTcpClient() As Boolean
Static remoteIp As String = "127.0.0.1"
Static remotePort As Integer = -1 '默认55533,实际使用从注册表中获取
Try
If _tcpClient Is Nothing OrElse (_tcpClient.Connected() = False) Then
remotePort = CInt(UtsRegistry.DataServicePort)
_tcpClient = New AutsTcpClient(remoteIp, remotePort)
_tcpClient.Open()
ApplicationLog.WriteTraceLog($"InitTcpClient Success!")
End If
Catch ex As Exception
ResetTcpConnection()
If _serviceHeartBeatFailCount <= 1 Then '避免离线后大量重复数据
ApplicationLog.WriteWarningLog($"InitTcpClient Error:{ex.Message}")
End If
Return False
End Try
Return True
End Function
''' <summary>
''' 重启服务后重置连接服务TCP标志位
''' </summary>
Private Sub ResetTcpConnection()
If _tcpClient IsNot Nothing Then
_tcpClient.Dispose()
_tcpClient = Nothing
End If
End Sub
''' <summary>
''' 与服务通讯,包含发送,接收,处理过程
''' </summary>
''' <param name="taskParam"></param>
Private Function ServiceCommunicator(taskParam As TaskJsonParam) As Boolean
Try
Dim jsonString As String = TaskJsonParam.SerializeToJson(taskParam) & vbCrLf
_tcpClient.WriteJsonString(jsonString) '发送数据
Catch ex As Exception
ApplicationLog.WriteErrorLog($"Send jsonString Error:{ex.Message}")
Return False
End Try
Dim replyString As String = _tcpClient.ReadJsonString()
Try
Dim replyParam As TaskJsonParam = CheckReplyString(replyString, taskParam.CmdName) '接收数据校验
If replyParam.CmdStatus = TaskJsonParam.CmdStatusEnum.Pass.ToString() Then
DealFunction(replyParam)
End If
Catch ex As Exception
ApplicationLog.WriteWarningLog($"CmdName:{taskParam.CmdName} Deal ReplyString Error:{ex.Message}")
Return False
End Try
Return True
End Function
''' <summary>
''' 校验回复字符串
''' </summary>
''' <param name="replyString"></param>
''' <param name="cmdName"></param>
''' <returns></returns>
Private Function CheckReplyString(replyString As String, cmdName As TaskJsonParam.CmdNamesEnum) As TaskJsonParam
If String.IsNullOrWhiteSpace(replyString) Then Return Nothing
Dim replyParam As TaskJsonParam
replyParam = TaskJsonParam.DeserializeFormJson(replyString)
If replyParam.CmdName <> cmdName Then Return Nothing
Return replyParam
End Function
''' <summary>
''' 处理返回值
''' </summary>
''' <param name="replyParam"></param>
Private Sub DealFunction(replyParam As TaskJsonParam)
Select Case replyParam.CmdName
Case TaskJsonParam.CmdNamesEnum.GetServiceVersion
DealServiceVersion(replyParam)
End Select
End Sub
''' <summary>
''' 获取服务版本信息
''' </summary>
''' <param name="replyParam"></param>
Private Sub DealServiceVersion(replyParam As TaskJsonParam)
_dsVersion = replyParam.ServiceVersion
_dsOnline = 1
'更新失败计数
If _uploaded = False Then Return
If String.Compare(_dsVersion, _lastDsVersion) = 0 Then
_uploaded = False
ResetUpgradeFailCount()
ApplicationLog.WriteTraceLog($"Upgrade DataService To {_lastDsVersion} Success!")
Else
_uploaded = False
UpdateUpgradeFailCount()
End If
End Sub
#End Region
End Class

View File

@@ -0,0 +1,241 @@
Imports System.ComponentModel
Imports System.ServiceProcess
Imports System.Configuration.Install
Imports System.Reflection
Public Class WinService
''' <summary>
''' 描述服务的状态
''' </summary>
Enum ServiceStatusEnum
<Description("未知")>
Unknown
<Description("不存在")>
Nonentity
<Description("已存在")>
Exists
<Description("停止中")>
StopPending
<Description("已停止")>
Stopped
<Description("启动中")>
StartPending
<Description("已启动")>
Started
End Enum
''' <summary>
''' 获取枚举描述特性
''' </summary>
''' <param name="enumValue">需要获取特性的枚举值</param>
''' <returns>枚举描述特性</returns>
Public Shared Function GetEnumDescription(enumValue As [Enum]) As String
Dim fi As FieldInfo = enumValue.GetType().GetField(enumValue.ToString())
Dim attr() As DescriptionAttribute =
DirectCast(fi.GetCustomAttributes(GetType(DescriptionAttribute),
False), DescriptionAttribute())
If attr.Length > 0 Then
Return attr(0).Description
Else
Return enumValue.ToString()
End If
End Function
''' <summary>
''' 检测服务是否存在
''' </summary>
''' <param name="serviceName">需要检测的服务名称</param>
''' <returns>服务是否存在</returns>
Public Shared Function ServicesExists(serviceName As String) As Boolean
Dim services() As ServiceController = ServiceController.GetServices
For Each service As ServiceController In services
If service.ServiceName = serviceName Then
Return True
End If
Next
Return False
End Function
''' <summary>
''' 获取服务的状态
''' </summary>
''' <param name="serviceName">服务名称</param>
''' <returns></returns>
Public Shared Function ServicesStatus(serviceName As String) As ServiceStatusEnum
Dim status As ServiceStatusEnum
Try
If ServicesExists(serviceName) Then
status = ServiceStatusEnum.Exists
Try
Dim service As New ServiceController(serviceName)
If service.Status = ServiceControllerStatus.Running Then
status = ServiceStatusEnum.Started
ElseIf service.Status = ServiceControllerStatus.StartPending OrElse
service.Status = ServiceControllerStatus.ContinuePending Then
status = ServiceStatusEnum.StartPending
ElseIf service.Status = ServiceControllerStatus.StopPending OrElse
service.Status = ServiceControllerStatus.PausePending Then
status = ServiceStatusEnum.StopPending
Else
status = ServiceStatusEnum.Stopped
End If
Catch ex As Exception
ApplicationLog.WriteErrorLog($"ServicesStatus Error:{ex.Message}")
End Try
Else
status = ServiceStatusEnum.Nonentity
End If
Catch ex As Exception
status = ServiceStatusEnum.Unknown
ApplicationLog.WriteErrorLog($"Check ServicesStatus Error:{ex.Message}")
End Try
Return status
End Function
''' <summary>
''' 安装服务
''' </summary>
''' <param name="filePath">服务程序所在路径</param>
''' <param name="savedState">服务状态,未知字段</param>
Public Shared Sub InstallService(filePath As String, savedState As IDictionary)
Dim app As AppDomain = AppDomain.CreateDomain("MyDomain")
Try
Dim assName As String = GetType(AssemblyInstaller).Assembly.FullName
Dim fullName As String = GetType(AssemblyInstaller).FullName
Using installer As AssemblyInstaller = CType(app.CreateInstanceAndUnwrap(assName, fullName), AssemblyInstaller)
installer.UseNewContext = True
installer.Path = filePath
installer.Install(savedState)
installer.Commit(savedState)
installer.Dispose()
End Using
AppDomain.Unload(app)
GC.Collect()
Catch ex As Exception
AppDomain.Unload(app)
GC.Collect()
Throw
End Try
End Sub
''' <summary>
''' 卸载服务
''' </summary>
''' <param name="filePath">服务程序所在路径</param>
''' <param name="savedState">服务状态,未知字段</param>
Public Shared Sub UnInstallService(filePath As String, savedState As IDictionary)
Dim app As AppDomain = AppDomain.CreateDomain("MyDomain")
Try
Dim assName As String = GetType(AssemblyInstaller).Assembly.FullName
Dim fullName As String = GetType(AssemblyInstaller).FullName
Using installer As AssemblyInstaller = CType(app.CreateInstanceAndUnwrap(assName, fullName), AssemblyInstaller)
installer.UseNewContext = True
installer.Path = filePath
installer.Uninstall(savedState)
installer.Dispose()
End Using
AppDomain.Unload(app)
GC.Collect()
Catch ex As Exception
AppDomain.Unload(app)
GC.Collect()
Throw
End Try
End Sub
''' <summary> 检测服务---状态 </summary>
Public Shared Function TestingServicesStatus(serviceName As String) As Boolean
Dim pServiceName As ServiceController = New ServiceController(serviceName)
Try
Return Not (pServiceName.Status = ServiceControllerStatus.Stopped)
Catch ex As Exception
Throw New Exception(ex.Message)
End Try
End Function
''' <summary>
''' 开启服务
''' </summary>
''' <param name="serviceName">服务名称</param>
''' <returns>开启服务结果</returns>
Public Shared Function StartService(serviceName As String) As Boolean
Try
Using service As ServiceController = New ServiceController(serviceName)
If service.Status <> ServiceControllerStatus.Running OrElse
service.Status <> ServiceControllerStatus.StartPending OrElse
service.Status <> ServiceControllerStatus.ContinuePending Then
service.Start()
End If
End Using
Catch ex As Exception
ApplicationLog.WriteErrorLog($"StartService Error:{ex.Message}")
Return False
End Try
Return True
End Function
''' <summary>
''' 关闭服务
''' </summary>
''' <param name="serviceName">服务名称</param>
''' <returns>关闭服务结果</returns>
Public Shared Function StopService(serviceName As String) As Boolean
Try
Using service As ServiceController = New ServiceController(serviceName)
If service.Status = ServiceControllerStatus.Running OrElse
service.Status = ServiceControllerStatus.StartPending OrElse
service.Status = ServiceControllerStatus.ContinuePending Then
service.Stop()
End If
End Using
Catch ex As Exception
ApplicationLog.WriteErrorLog($"StopService Error:{ex.Message}")
Return False
End Try
Return True
End Function
''' <summary>
''' 重启服务
''' </summary>
''' <param name="serviceName">服务名称</param>
''' <returns></returns>
Public Shared Function RestartService(serviceName As String) As Boolean
Try
Using service As ServiceController = New ServiceController(serviceName)
If service.Status = ServiceControllerStatus.Running OrElse
service.Status = ServiceControllerStatus.StartPending OrElse
service.Status = ServiceControllerStatus.ContinuePending Then
service.Stop()
While service.Status = ServiceControllerStatus.Running AndAlso
service.Status = ServiceControllerStatus.StopPending
service.Refresh()
Threading.Thread.Sleep(20)
End While
End If
Threading.Thread.Sleep(100)
service.Start()
End Using
Catch ex As Exception
ApplicationLog.WriteErrorLog($"RestartService:{ex.Message}")
Return False
End Try
Return True
End Function
End Class

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FluentFTP" version="33.0.3" targetFramework="net48" />
</packages>