From 8a1d028f3e5c92da5dc61f56e3b793d986412088 Mon Sep 17 00:00:00 2001
From: hucan <951870319@qq.com>
Date: Mon, 19 May 2025 14:06:21 +0800
Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E5=88=9D=E5=A7=8B=E5=8C=96=E4=BB=93?=
 =?UTF-8?q?=E5=BA=93?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
 .gitignore                                |    3 +
 Yjpp36.sln                                |   25 +
 Yjpp36/App.config                         |    6 +
 Yjpp36/Form1.Designer.vb                  |  364 ++++
 Yjpp36/Form1.resx                         |  120 ++
 Yjpp36/Form1.vb                           | 2020 +++++++++++++++++++++
 Yjpp36/My Project/Application.Designer.vb |   38 +
 Yjpp36/My Project/Application.myapp       |   10 +
 Yjpp36/My Project/AssemblyInfo.vb         |   35 +
 Yjpp36/My Project/Resources.Designer.vb   |   63 +
 Yjpp36/My Project/Resources.resx          |  117 ++
 Yjpp36/My Project/Settings.Designer.vb    |   73 +
 Yjpp36/My Project/Settings.settings       |    7 +
 Yjpp36/Yjpp36.vbproj                      |  168 ++
 Yjpp36/Yjpp36.vbproj.user                 |   13 +
 Yjpp36/app.manifest                       |   78 +
 Yjpp36/ct.resx                            |  120 ++
 Yjpp36/ct.vb                              |   76 +
 Yjpp36/dtos/AppVersion.vb                 |    7 +
 Yjpp36/dtos/Config.vb                     |   24 +
 Yjpp36/dtos/KeywordItemReq.vb             |    6 +
 Yjpp36/dtos/KeywordResult.vb              |   10 +
 Yjpp36/dtos/Result.vb                     |   47 +
 Yjpp36/service/CopyService.vb             |   27 +
 Yjpp36/service/FileService.vb             |    3 +
 Yjpp36/service/Logger.vb                  |  143 ++
 Yjpp36/service/StringEncryption.vb        |  157 ++
 Yjpp36/service/Updater.vb                 |   72 +
 28 files changed, 3832 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 Yjpp36.sln
 create mode 100644 Yjpp36/App.config
 create mode 100644 Yjpp36/Form1.Designer.vb
 create mode 100644 Yjpp36/Form1.resx
 create mode 100644 Yjpp36/Form1.vb
 create mode 100644 Yjpp36/My Project/Application.Designer.vb
 create mode 100644 Yjpp36/My Project/Application.myapp
 create mode 100644 Yjpp36/My Project/AssemblyInfo.vb
 create mode 100644 Yjpp36/My Project/Resources.Designer.vb
 create mode 100644 Yjpp36/My Project/Resources.resx
 create mode 100644 Yjpp36/My Project/Settings.Designer.vb
 create mode 100644 Yjpp36/My Project/Settings.settings
 create mode 100644 Yjpp36/Yjpp36.vbproj
 create mode 100644 Yjpp36/Yjpp36.vbproj.user
 create mode 100644 Yjpp36/app.manifest
 create mode 100644 Yjpp36/ct.resx
 create mode 100644 Yjpp36/ct.vb
 create mode 100644 Yjpp36/dtos/AppVersion.vb
 create mode 100644 Yjpp36/dtos/Config.vb
 create mode 100644 Yjpp36/dtos/KeywordItemReq.vb
 create mode 100644 Yjpp36/dtos/KeywordResult.vb
 create mode 100644 Yjpp36/dtos/Result.vb
 create mode 100644 Yjpp36/service/CopyService.vb
 create mode 100644 Yjpp36/service/FileService.vb
 create mode 100644 Yjpp36/service/Logger.vb
 create mode 100644 Yjpp36/service/StringEncryption.vb
 create mode 100644 Yjpp36/service/Updater.vb
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..215a577
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+.vs
+obj
+bin
\ No newline at end of file
diff --git a/Yjpp36.sln b/Yjpp36.sln
new file mode 100644
index 0000000..19e9913
--- /dev/null
+++ b/Yjpp36.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.35731.53
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Yjpp36", "Yjpp36\Yjpp36.vbproj", "{10673D97-6B35-4915-AE47-092FFAB27196}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{10673D97-6B35-4915-AE47-092FFAB27196}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{10673D97-6B35-4915-AE47-092FFAB27196}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{10673D97-6B35-4915-AE47-092FFAB27196}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{10673D97-6B35-4915-AE47-092FFAB27196}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {2BDB7125-C94D-4ABF-A53D-1E93B741D230}
+	EndGlobalSection
+EndGlobal
diff --git a/Yjpp36/App.config b/Yjpp36/App.config
new file mode 100644
index 0000000..b6c2be6
--- /dev/null
+++ b/Yjpp36/App.config
@@ -0,0 +1,6 @@
+
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/Yjpp36/Form1.Designer.vb b/Yjpp36/Form1.Designer.vb
new file mode 100644
index 0000000..5feb115
--- /dev/null
+++ b/Yjpp36/Form1.Designer.vb
@@ -0,0 +1,364 @@
+
+Partial Class Form1
+    Inherits System.Windows.Forms.Form
+
+    'Form 重写 Dispose,以清理组件列表。
+    
+    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
+
+    'Windows 窗体设计器所必需的
+    Private components As System.ComponentModel.IContainer
+
+    '注意: 以下过程是 Windows 窗体设计器所必需的
+    '可以使用 Windows 窗体设计器修改它。  
+    '不要使用代码编辑器修改它。
+    
+    Private Sub InitializeComponent()
+        Me.Button1 = New System.Windows.Forms.Button()
+        Me.Button4 = New System.Windows.Forms.Button()
+        Me.Button2 = New System.Windows.Forms.Button()
+        Me.TabControl1 = New System.Windows.Forms.TabControl()
+        Me.TabPage1 = New System.Windows.Forms.TabPage()
+        Me.TextBox4 = New System.Windows.Forms.TextBox()
+        Me.Label6 = New System.Windows.Forms.Label()
+        Me.Label5 = New System.Windows.Forms.Label()
+        Me.Label4 = New System.Windows.Forms.Label()
+        Me.TextBox3 = New System.Windows.Forms.TextBox()
+        Me.Label3 = New System.Windows.Forms.Label()
+        Me.Button6 = New System.Windows.Forms.Button()
+        Me.ListBox1 = New System.Windows.Forms.ListBox()
+        Me.CheckBox1 = New System.Windows.Forms.CheckBox()
+        Me.Button3 = New System.Windows.Forms.Button()
+        Me.TextBox1 = New System.Windows.Forms.TextBox()
+        Me.Label1 = New System.Windows.Forms.Label()
+        Me.TabPage2 = New System.Windows.Forms.TabPage()
+        Me.lbl_taskLimit = New System.Windows.Forms.Label()
+        Me.Label2 = New System.Windows.Forms.Label()
+        Me.Button5 = New System.Windows.Forms.Button()
+        Me.TextBox2 = New System.Windows.Forms.TextBox()
+        Me.tab_group = New System.Windows.Forms.TabPage()
+        Me.lbl_appLimit = New System.Windows.Forms.Label()
+        Me.lbl_name = New System.Windows.Forms.Label()
+        Me.txt_groupItems = New System.Windows.Forms.TextBox()
+        Me.TabControl1.SuspendLayout()
+        Me.TabPage1.SuspendLayout()
+        Me.TabPage2.SuspendLayout()
+        Me.tab_group.SuspendLayout()
+        Me.SuspendLayout()
+        '
+        'Button1
+        '
+        Me.Button1.Location = New System.Drawing.Point(6, 18)
+        Me.Button1.Name = "Button1"
+        Me.Button1.Size = New System.Drawing.Size(144, 32)
+        Me.Button1.TabIndex = 0
+        Me.Button1.Text = "停止启动+删除文件"
+        Me.Button1.UseVisualStyleBackColor = True
+        '
+        'Button4
+        '
+        Me.Button4.Location = New System.Drawing.Point(264, 5)
+        Me.Button4.Name = "Button4"
+        Me.Button4.Size = New System.Drawing.Size(93, 23)
+        Me.Button4.TabIndex = 3
+        Me.Button4.Text = "继续运行"
+        Me.Button4.UseVisualStyleBackColor = True
+        '
+        'Button2
+        '
+        Me.Button2.Location = New System.Drawing.Point(6, 56)
+        Me.Button2.Name = "Button2"
+        Me.Button2.Size = New System.Drawing.Size(144, 32)
+        Me.Button2.TabIndex = 4
+        Me.Button2.Text = "输出所有的进程"
+        Me.Button2.UseVisualStyleBackColor = True
+        '
+        'TabControl1
+        '
+        Me.TabControl1.Controls.Add(Me.TabPage1)
+        Me.TabControl1.Controls.Add(Me.TabPage2)
+        Me.TabControl1.Controls.Add(Me.tab_group)
+        Me.TabControl1.Location = New System.Drawing.Point(12, 12)
+        Me.TabControl1.Name = "TabControl1"
+        Me.TabControl1.SelectedIndex = 0
+        Me.TabControl1.Size = New System.Drawing.Size(352, 232)
+        Me.TabControl1.TabIndex = 5
+        '
+        'TabPage1
+        '
+        Me.TabPage1.Controls.Add(Me.TextBox4)
+        Me.TabPage1.Controls.Add(Me.Label6)
+        Me.TabPage1.Controls.Add(Me.Label5)
+        Me.TabPage1.Controls.Add(Me.Label4)
+        Me.TabPage1.Controls.Add(Me.TextBox3)
+        Me.TabPage1.Controls.Add(Me.Label3)
+        Me.TabPage1.Controls.Add(Me.Button6)
+        Me.TabPage1.Controls.Add(Me.ListBox1)
+        Me.TabPage1.Controls.Add(Me.CheckBox1)
+        Me.TabPage1.Controls.Add(Me.Button3)
+        Me.TabPage1.Controls.Add(Me.TextBox1)
+        Me.TabPage1.Controls.Add(Me.Label1)
+        Me.TabPage1.Controls.Add(Me.Button1)
+        Me.TabPage1.Controls.Add(Me.Button2)
+        Me.TabPage1.Location = New System.Drawing.Point(4, 22)
+        Me.TabPage1.Name = "TabPage1"
+        Me.TabPage1.Padding = New System.Windows.Forms.Padding(3)
+        Me.TabPage1.Size = New System.Drawing.Size(344, 206)
+        Me.TabPage1.TabIndex = 0
+        Me.TabPage1.Text = "功能区"
+        Me.TabPage1.UseVisualStyleBackColor = True
+        '
+        'TextBox4
+        '
+        Me.TextBox4.Enabled = False
+        Me.TextBox4.Location = New System.Drawing.Point(167, 28)
+        Me.TextBox4.Name = "TextBox4"
+        Me.TextBox4.Size = New System.Drawing.Size(162, 21)
+        Me.TextBox4.TabIndex = 15
+        Me.TextBox4.TextAlign = System.Windows.Forms.HorizontalAlignment.Center
+        '
+        'Label6
+        '
+        Me.Label6.AutoSize = True
+        Me.Label6.Location = New System.Drawing.Point(166, 11)
+        Me.Label6.Name = "Label6"
+        Me.Label6.Size = New System.Drawing.Size(77, 12)
+        Me.Label6.TabIndex = 14
+        Me.Label6.Text = "当前机器码:"
+        '
+        'Label5
+        '
+        Me.Label5.AutoSize = True
+        Me.Label5.Location = New System.Drawing.Point(165, 113)
+        Me.Label5.Name = "Label5"
+        Me.Label5.Size = New System.Drawing.Size(173, 12)
+        Me.Label5.TabIndex = 13
+        Me.Label5.Text = "注:心跳时间不能超过十分钟。"
+        '
+        'Label4
+        '
+        Me.Label4.AutoSize = True
+        Me.Label4.Location = New System.Drawing.Point(313, 87)
+        Me.Label4.Name = "Label4"
+        Me.Label4.Size = New System.Drawing.Size(17, 12)
+        Me.Label4.TabIndex = 12
+        Me.Label4.Text = "秒"
+        '
+        'TextBox3
+        '
+        Me.TextBox3.Enabled = False
+        Me.TextBox3.Location = New System.Drawing.Point(262, 82)
+        Me.TextBox3.Name = "TextBox3"
+        Me.TextBox3.Size = New System.Drawing.Size(48, 21)
+        Me.TextBox3.TabIndex = 11
+        Me.TextBox3.TextAlign = System.Windows.Forms.HorizontalAlignment.Center
+        '
+        'Label3
+        '
+        Me.Label3.AutoSize = True
+        Me.Label3.Location = New System.Drawing.Point(202, 88)
+        Me.Label3.Name = "Label3"
+        Me.Label3.Size = New System.Drawing.Size(65, 12)
+        Me.Label3.TabIndex = 10
+        Me.Label3.Text = "心跳时间:"
+        '
+        'Button6
+        '
+        Me.Button6.Location = New System.Drawing.Point(211, 177)
+        Me.Button6.Name = "Button6"
+        Me.Button6.Size = New System.Drawing.Size(118, 23)
+        Me.Button6.TabIndex = 9
+        Me.Button6.Text = "清除进程"
+        Me.Button6.UseVisualStyleBackColor = True
+        '
+        'ListBox1
+        '
+        Me.ListBox1.FormattingEnabled = True
+        Me.ListBox1.ItemHeight = 12
+        Me.ListBox1.Location = New System.Drawing.Point(6, 112)
+        Me.ListBox1.Name = "ListBox1"
+        Me.ListBox1.Size = New System.Drawing.Size(144, 88)
+        Me.ListBox1.TabIndex = 6
+        '
+        'CheckBox1
+        '
+        Me.CheckBox1.AutoSize = True
+        Me.CheckBox1.Location = New System.Drawing.Point(6, 94)
+        Me.CheckBox1.Name = "CheckBox1"
+        Me.CheckBox1.Size = New System.Drawing.Size(96, 16)
+        Me.CheckBox1.TabIndex = 8
+        Me.CheckBox1.Text = "调试进程模式"
+        Me.CheckBox1.UseVisualStyleBackColor = True
+        '
+        'Button3
+        '
+        Me.Button3.Location = New System.Drawing.Point(211, 136)
+        Me.Button3.Name = "Button3"
+        Me.Button3.Size = New System.Drawing.Size(118, 23)
+        Me.Button3.TabIndex = 7
+        Me.Button3.Text = "设置"
+        Me.Button3.UseVisualStyleBackColor = True
+        '
+        'TextBox1
+        '
+        Me.TextBox1.Location = New System.Drawing.Point(262, 55)
+        Me.TextBox1.Name = "TextBox1"
+        Me.TextBox1.Size = New System.Drawing.Size(48, 21)
+        Me.TextBox1.TabIndex = 6
+        Me.TextBox1.TextAlign = System.Windows.Forms.HorizontalAlignment.Center
+        '
+        'Label1
+        '
+        Me.Label1.AutoSize = True
+        Me.Label1.Location = New System.Drawing.Point(190, 61)
+        Me.Label1.Name = "Label1"
+        Me.Label1.Size = New System.Drawing.Size(77, 12)
+        Me.Label1.TabIndex = 5
+        Me.Label1.Text = "当前机器号:"
+        '
+        'TabPage2
+        '
+        Me.TabPage2.Controls.Add(Me.lbl_taskLimit)
+        Me.TabPage2.Controls.Add(Me.Label2)
+        Me.TabPage2.Controls.Add(Me.Button5)
+        Me.TabPage2.Controls.Add(Me.TextBox2)
+        Me.TabPage2.Location = New System.Drawing.Point(4, 22)
+        Me.TabPage2.Name = "TabPage2"
+        Me.TabPage2.Padding = New System.Windows.Forms.Padding(3)
+        Me.TabPage2.Size = New System.Drawing.Size(344, 206)
+        Me.TabPage2.TabIndex = 1
+        Me.TabPage2.Text = "添加数据"
+        Me.TabPage2.UseVisualStyleBackColor = True
+        '
+        'lbl_taskLimit
+        '
+        Me.lbl_taskLimit.AutoSize = True
+        Me.lbl_taskLimit.Location = New System.Drawing.Point(6, 178)
+        Me.lbl_taskLimit.Name = "lbl_taskLimit"
+        Me.lbl_taskLimit.Size = New System.Drawing.Size(0, 12)
+        Me.lbl_taskLimit.TabIndex = 3
+        '
+        'Label2
+        '
+        Me.Label2.Location = New System.Drawing.Point(6, 178)
+        Me.Label2.Name = "Label2"
+        Me.Label2.Size = New System.Drawing.Size(204, 18)
+        Me.Label2.TabIndex = 2
+        Me.Label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
+        '
+        'Button5
+        '
+        Me.Button5.Location = New System.Drawing.Point(216, 171)
+        Me.Button5.Name = "Button5"
+        Me.Button5.Size = New System.Drawing.Size(122, 28)
+        Me.Button5.TabIndex = 1
+        Me.Button5.Text = "新增进程"
+        Me.Button5.UseVisualStyleBackColor = True
+        '
+        'TextBox2
+        '
+        Me.TextBox2.Location = New System.Drawing.Point(6, 6)
+        Me.TextBox2.Multiline = True
+        Me.TextBox2.Name = "TextBox2"
+        Me.TextBox2.ScrollBars = System.Windows.Forms.ScrollBars.Vertical
+        Me.TextBox2.Size = New System.Drawing.Size(332, 159)
+        Me.TextBox2.TabIndex = 0
+        '
+        'tab_group
+        '
+        Me.tab_group.Controls.Add(Me.lbl_appLimit)
+        Me.tab_group.Controls.Add(Me.lbl_name)
+        Me.tab_group.Controls.Add(Me.txt_groupItems)
+        Me.tab_group.Location = New System.Drawing.Point(4, 22)
+        Me.tab_group.Name = "tab_group"
+        Me.tab_group.Size = New System.Drawing.Size(344, 206)
+        Me.tab_group.TabIndex = 2
+        Me.tab_group.Text = "组策略限制"
+        Me.tab_group.UseVisualStyleBackColor = True
+        '
+        'lbl_appLimit
+        '
+        Me.lbl_appLimit.AutoSize = True
+        Me.lbl_appLimit.Location = New System.Drawing.Point(77, 2)
+        Me.lbl_appLimit.Name = "lbl_appLimit"
+        Me.lbl_appLimit.Size = New System.Drawing.Size(0, 12)
+        Me.lbl_appLimit.TabIndex = 4
+        '
+        'lbl_name
+        '
+        Me.lbl_name.AutoSize = True
+        Me.lbl_name.Dock = System.Windows.Forms.DockStyle.Top
+        Me.lbl_name.Location = New System.Drawing.Point(0, 0)
+        Me.lbl_name.Name = "lbl_name"
+        Me.lbl_name.Size = New System.Drawing.Size(71, 12)
+        Me.lbl_name.TabIndex = 1
+        Me.lbl_name.Text = "允许程序名:"
+        '
+        'txt_groupItems
+        '
+        Me.txt_groupItems.Dock = System.Windows.Forms.DockStyle.Bottom
+        Me.txt_groupItems.Location = New System.Drawing.Point(0, 26)
+        Me.txt_groupItems.Multiline = True
+        Me.txt_groupItems.Name = "txt_groupItems"
+        Me.txt_groupItems.ScrollBars = System.Windows.Forms.ScrollBars.Vertical
+        Me.txt_groupItems.Size = New System.Drawing.Size(344, 180)
+        Me.txt_groupItems.TabIndex = 0
+        '
+        'Form1
+        '
+        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 12.0!)
+        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
+        Me.ClientSize = New System.Drawing.Size(370, 249)
+        Me.Controls.Add(Me.Button4)
+        Me.Controls.Add(Me.TabControl1)
+        Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
+        Me.MaximizeBox = False
+        Me.Name = "Form1"
+        Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
+        Me.Text = "管理端"
+        Me.TabControl1.ResumeLayout(False)
+        Me.TabPage1.ResumeLayout(False)
+        Me.TabPage1.PerformLayout()
+        Me.TabPage2.ResumeLayout(False)
+        Me.TabPage2.PerformLayout()
+        Me.tab_group.ResumeLayout(False)
+        Me.tab_group.PerformLayout()
+        Me.ResumeLayout(False)
+
+    End Sub
+
+    Friend WithEvents Button1 As Button
+    Friend WithEvents Button4 As Button
+    Friend WithEvents Button2 As Button
+    Friend WithEvents TabControl1 As TabControl
+    Friend WithEvents TabPage1 As TabPage
+    Friend WithEvents TabPage2 As TabPage
+    Friend WithEvents Button3 As Button
+    Friend WithEvents TextBox1 As TextBox
+    Friend WithEvents Label1 As Label
+    Friend WithEvents Button5 As Button
+    Friend WithEvents TextBox2 As TextBox
+    Friend WithEvents Label2 As Label
+    Friend WithEvents CheckBox1 As CheckBox
+    Friend WithEvents Button6 As Button
+    Friend WithEvents ListBox1 As ListBox
+    Friend WithEvents TextBox3 As TextBox
+    Friend WithEvents Label3 As Label
+    Friend WithEvents Label4 As Label
+    Friend WithEvents Label5 As Label
+    Friend WithEvents TextBox4 As TextBox
+    Friend WithEvents Label6 As Label
+    Friend WithEvents tab_group As TabPage
+    Friend WithEvents lbl_name As Label
+    Friend WithEvents txt_groupItems As TextBox
+    Friend WithEvents lbl_appLimit As Label
+    Friend WithEvents lbl_taskLimit As Label
+End Class
diff --git a/Yjpp36/Form1.resx b/Yjpp36/Form1.resx
new file mode 100644
index 0000000..29dcb1b
--- /dev/null
+++ b/Yjpp36/Form1.resx
@@ -0,0 +1,120 @@
+
+
+  
+  
+    
+    
+      
+        
+          
+            
+              
+                
+              
+              
+              
+              
+              
+            
+          
+          
+            
+              
+              
+            
+          
+          
+            
+              
+                
+                
+              
+              
+              
+              
+              
+            
+          
+          
+            
+              
+                
+              
+              
+            
+          
+        
+      
+    
+  
+  
+    text/microsoft-resx
+  
+  
+    2.0
+  
+  
+    System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+  
+  
+    System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+  
+
\ No newline at end of file
diff --git a/Yjpp36/Form1.vb b/Yjpp36/Form1.vb
new file mode 100644
index 0000000..3414a47
--- /dev/null
+++ b/Yjpp36/Form1.vb
@@ -0,0 +1,2020 @@
+Imports System.IO
+Imports System.Net
+Imports System.Runtime.InteropServices
+Imports System.Security.AccessControl
+Imports System.Security.Principal
+Imports Microsoft.Win32
+Imports System.Text
+Imports System.Threading
+Imports System.Net.NetworkInformation
+Imports System.Net.Http
+Imports System.Web.Script.Serialization
+Imports System.Reflection
+
+Public Class Form1
+    Dim 是否断网 As Boolean = False
+    Dim 全局变量_BIOS识别码 As String = ""
+    Dim 全局变量_异常密码 As String = "009988"
+    'api接口地址 ' 
+    Dim ApiEndPoint As String = "http://api.systemcd.org/api/v1"
+    Dim 全局变量_id As String = ""
+    Dim 全局变量_心跳时间 As String = ""
+    Dim 全局变量_关键字心跳时间 As String = ""
+    Dim 全局变量_进程限制 As Integer = 2
+    Dim 全局变量_应用限制 As Integer = 2
+    Dim 全局变量_关键字采集 As Integer = 2 '关键字采集 1开启 2-关闭 默认关闭'
+    Dim 全局变量_拦截记录间隔 As Double = 1 '进程拦截记录间隔(小时)'
+    Dim 全局变量_采集的文本 As List(Of KeywordItemReq) = New List(Of KeywordItemReq) '已采集的违规文本'
+    Dim 全局变量_程序版本 As String = ""
+    '忽略的特殊字符'
+    Dim ignoreChars As New HashSet(Of Char)({" ", vbCrLf, ",", "。", ":", "【", "】", "?", ";", ",", ".", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "_", "+", "=", "`", "~", "[", "]", "{", "}", "\", "|", ";", ":", "’", "‘", "'", """", "<", ">", "/", "?"})
+
+    Dim 全局变量_已拦截进程 As Dictionary(Of String, DateTime) = New Dictionary(Of String, Date)
+    Public 全局变量_关键字 As KeywordItem = New KeywordItem
+
+    'http请求对象'
+    Dim client As New HttpClient()
+    '序列化对象'
+    Dim serializer As New JavaScriptSerializer()
+
+    Private Const HWND_BROADCAST As Integer = &HFFFF
+    Private Const WM_SETTINGCHANGE As Integer = &H1A
+    Private Const SMTO_NORMAL As UInteger = &H0
+
+    Private promptLoopTask As Task = Nothing
+    Private promptLoopStarted As Boolean = False
+    Private promptLoopLock As New Object() ' 用于线程同步
+    Private keywordLoopLock As New Object() '关键词task线程同步'
+
+    '允许进程列表'
+    Private allowedProcesses As New HashSet(Of String)(StringComparer.OrdinalIgnoreCase)
+    '组策略允许列表'
+    Private allGroupApplication As New HashSet(Of String)(StringComparer.OrdinalIgnoreCase)
+
+    '用于存储定时任务的 Task
+    Private monitorTask As Task
+    '关键词定时同步 Task'
+    Private keywordMonitorTask As Task
+    '用于控制定时任务的取消'
+    Private monitorCancellationTokenSource As New CancellationTokenSource()
+    '关键字控制定时任务取消'
+    Private monitorKeywordCancellationTokenSource As New CancellationTokenSource()
+
+    '剪切板'
+    Private Const WM_CLIPBOARDUPDATE As Integer = &H31D
+    '增加剪切板监听'
+    
+    Private Shared Function AddClipboardFormatListener(hWnd As IntPtr) As Boolean
+    End Function
+
+    '移除剪切板监听'
+    
+    Private Shared Function RemoveClipboardFormatListener(hWnd As IntPtr) As Boolean
+    End Function
+
+    
+    Private Shared Function MoveFileEx(
+        lpExistingFileName As String,
+        lpNewFileName As String,
+        dwFlags As Integer) As Boolean
+    End Function
+
+    
+    Private Shared Function SendMessageTimeout(
+        hWnd As IntPtr,
+        Msg As UInteger,
+        wParam As IntPtr,
+        lParam As String,
+        fuFlags As UInteger,
+        uTimeout As UInteger,
+        ByRef lpdwResult As IntPtr
+    ) As IntPtr
+    End Function
+
+    
+    Private Shared Function SendNotifyMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As String) As Boolean
+    End Function
+
+    
+    Private Shared Function RegisterHotKey(
+        hWnd As IntPtr,
+        id As Integer,
+        fsModifiers As UInteger,
+        vk As UInteger
+    ) As Boolean
+    End Function
+
+    
+    Private Shared Function UnregisterHotKey(
+        hWnd As IntPtr,
+        id As Integer
+    ) As Boolean
+    End Function
+
+    
+    Private Shared Function SetNamedSecurityInfo(
+        pObjectName As String,
+        objectType As Integer,
+        securityInfo As Integer,
+        psidOwner As IntPtr,
+        psidGroup As IntPtr,
+        pDacl As IntPtr,
+        pSacl As IntPtr
+    ) As Integer
+    End Function
+
+    Private Const SE_FILE_OBJECT As Integer = 1
+    Private Const OWNER_SECURITY_INFORMATION As Integer = &H1
+    Private Const WM_HOTKEY As Integer = &H312
+    Private Const MOD_CONTROL As Integer = &H2
+    Private Const MOD_ALT As Integer = &H1
+    Private Const HOTKEY_ID As Integer = 1
+    ' 检测当前是否以管理员身份运行
+    Private Function IsAdministrator() As Boolean
+        Dim identity = WindowsIdentity.GetCurrent()
+        Dim principal = New WindowsPrincipal(identity)
+        Return principal.IsInRole(WindowsBuiltInRole.Administrator)
+    End Function
+    Private Sub EnsureElevated()
+        If Not IsAdministrator() Then
+            Dim psi As New ProcessStartInfo(Application.ExecutablePath) With {
+                .Verb = "runas",
+                .UseShellExecute = True
+            }
+            Try
+                Process.Start(psi)
+            Catch ex As Exception
+                MessageBox.Show("需要管理员权限才能继续。", "权限不足", MessageBoxButtons.OK, MessageBoxIcon.Warning)
+            End Try
+            Application.Exit()
+        End If
+    End Sub
+    Async Function GetSmbiosUuid() As Task(Of String)
+        Dim result As String = String.Empty
+
+        Try
+            Dim adapters As NetworkInterface() = NetworkInterface.GetAllNetworkInterfaces()
+
+            If adapters.Length = 0 Then
+                Console.WriteLine("未找到任何网络接口。")
+                Return String.Empty
+            End If
+            For Each adapter As NetworkInterface In adapters
+                ' 过滤掉 Loopback 和 Tunnel 接口,只关注 Ethernet 接口
+                If adapter.NetworkInterfaceType = NetworkInterfaceType.Ethernet Then
+                    Dim physicalAddress As PhysicalAddress = adapter.GetPhysicalAddress()
+                    Dim macBytes As Byte() = physicalAddress.GetAddressBytes()
+                    result = String.Join(":", macBytes.Select(Function(b) b.ToString("X2")))
+
+                    Exit For
+                End If
+            Next
+
+        Catch ex As Exception
+            ' 读取失败时可以日志记录或抛出
+            Console.Error.WriteLine("读取 SMBIOS UUID 时发生异常: " & ex.Message)
+        End Try
+
+        Return result
+    End Function
+    Private Async Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
+        Dim title As String = $"管理端{全局变量_程序版本}"
+        If IsNetworkAvailable() = True Then
+            是否断网 = True
+        Else
+            title = $"管理端{全局变量_程序版本} - 无网络"
+            是否断网 = False
+        End If
+
+        Me.Text = title
+        '打开时先判断是否有网络
+        Await Task.WhenAll(AddStartupEntry())
+
+        '首先第一步就是获取CPU识别号。
+        Await Task.Run(Async Function()
+                           全局变量_BIOS识别码 = Await GetSmbiosUuid()
+                           TextBox4.BeginInvoke(Sub()
+                                                    TextBox4.Text = 全局变量_BIOS识别码
+                                                End Sub)
+                       End Function)
+
+
+        Try
+            Dim initResult As Boolean = Await InitSetting()
+
+            If initResult = False Then
+                Return
+            End If
+
+            ' 隐藏当前窗体并继续后续异步初始化
+            If Not 全局变量_id = "" Then
+                Me.Hide()
+            End If
+
+            If Not Me.Visible Then
+                If 是否断网 = True Then
+                    Await Task.WhenAll(
+                                GetRemoteTextAndPopulateAllowedProcesses())
+
+                    Await Task.Run(Async Function()
+                                       Await 日志输出(全局变量_id, "1", 全局变量_BIOS识别码) '打开软件
+                                   End Function)
+                Else
+                    Dim folder As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Vls")
+                    Dim filePath1 As String = Path.Combine(folder, "list")
+
+                    ' 检查文件是否存在
+                    If File.Exists(filePath1) Then
+                        ' 逐行读取并加入 HashSet
+                        For Each rawLine As String In File.ReadLines(filePath1)
+                            Dim line As String = rawLine.Trim()
+                            If Not String.IsNullOrEmpty(line) Then
+                                allowedProcesses.Add(line)
+
+                                TextBox2.BeginInvoke(Sub()
+                                                         TextBox2.AppendText(line & vbCrLf)
+                                                     End Sub)
+                            End If
+                        Next
+
+                        Button5.BeginInvoke(Sub()
+                                                Button5.Enabled = False
+                                            End Sub)
+                        Button3.BeginInvoke(Sub()
+                                                Button3.Enabled = False
+                                            End Sub)
+
+                        StartMonitorLoop()
+                    Else
+                        MessageBox.Show("进程列表不存在,此软件运行不会生效。确定之后将退出。", "Err", MessageBoxButtons.OK, MessageBoxIcon.Error)
+                    End If
+
+                    If 全局变量_关键字采集 = 1 Then
+                        StartKeywordMonitorLoop()
+                    End If
+
+                End If
+
+                StartPromptLoopOnce()
+            Else
+                Me.Hide()
+            End If
+        Catch ex As Exception
+            MessageBox.Show("读取文件时发生错误: " & ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
+        End Try
+
+    End Sub
+
+    Protected Overrides Sub WndProc(ByRef m As Message)
+        MyBase.WndProc(m)
+        If m.Msg = WM_HOTKEY AndAlso m.WParam.ToInt32() = HOTKEY_ID Then
+            Dim 断网_tmp As Boolean = IsNetworkAvailable()
+            If 断网_tmp = False Then
+                MessageBox.Show("当前已断网,请输入超级密码进行登陆!", "Err", MessageBoxButtons.OK, MessageBoxIcon.Error)
+            End If
+            Using dlg As New PasswordDialog("请输入打开密码:", "权限请求")
+                If dlg.ShowDialog(Me) = DialogResult.OK Then
+                    If 断网_tmp = True Then
+                        是否断网 = True
+                        Dim PasswordCode As String = 获取密码() ' 假设这是一个字符串
+                        Dim input As String = dlg.PasswordText ' 保留为字符串类型
+                        If input = PasswordCode Then
+                            Me.Show()
+                        End If
+                    Else
+                        Me.Text = $"管理端{全局变量_程序版本} - 无网络"
+                        是否断网 = False
+                        Dim input As String = dlg.PasswordText ' 保留为字符串类型
+                        If input = 全局变量_异常密码 Then
+                            Me.Show()
+                        End If
+                    End If
+                End If
+            End Using
+        End If
+
+        Select Case m.Msg
+            Case WM_CLIPBOARDUPDATE
+                ' 获取剪贴板中的文本内容 
+                If 全局变量_关键字采集 = 1 AndAlso Clipboard.ContainsText() Then
+                    Dim clipboardText As String = Clipboard.GetText()
+                    If Not clipboardText = "" Then
+                        Task.Run(Async Function()
+                                     Await JudgeKeywords(clipboardText)
+                                 End Function)
+                    End If
+                End If
+        End Select
+    End Sub
+    Public Function 获取密码() As String
+        Dim result As String = ""
+
+        Try
+            ' 设置请求的URL
+            Dim url As String = $"{ApiEndPoint}/mm-machine/getPassword" ' 请替换为你实际的接口地址
+            '使用TLS12安全协议连接
+            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
+            ' 创建 HttpWebRequest 对象
+            Dim request As HttpWebRequest = CType(WebRequest.Create(url), HttpWebRequest)
+
+            ' 设置请求方法为 GET
+            request.Method = "GET"
+            request.Proxy = Nothing
+            ' 发送请求并获取响应
+            Dim response As WebResponse = request.GetResponse()
+
+            ' 读取响应流并获取内容
+            Using reader As New StreamReader(response.GetResponseStream())
+                result = reader.ReadToEnd()
+            End Using
+
+        Catch ex As Exception
+            result = 全局变量_异常密码
+        End Try
+
+        Return result
+    End Function
+    Private Async Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
+        Dim result As DialogResult = MessageBox.Show("确定要退出吗?", "确认退出", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
+
+        ' 如果用户选择“否”,则取消关闭操作
+        If result = DialogResult.No Then
+            e.Cancel = True
+        Else
+            If IsNetworkAvailable() = True Then
+                '如果有网络,那么执行日志输出错误,避免出错
+                Await Task.Run(Async Function()
+                                   Await 日志输出(全局变量_id, "4", 全局变量_BIOS识别码) '退出软件
+                               End Function)
+            End If
+
+            UnregisterHotKey(Me.Handle, HOTKEY_ID)
+            End
+        End If
+
+        RemoveClipboardFormatListener(Me.Handle)
+    End Sub
+
+    ''' 
+    ''' 定时任务
+    ''' 
+    ''' 
+    Private Async Function MonitorLoopAsync(cc As Int64, cancellationToken As CancellationToken) As Task
+        Do
+            'Logger.Info($"循环中2 {cc}")
+            Dim isNetworkAvailableLocal As Boolean = IsNetworkAvailable()
+            Dim limitText As String = ""
+
+            If 全局变量_进程限制 = 1 Then
+                limitText = "已应用"
+            Else
+                limitText = "未应用"
+            End If
+
+            lbl_taskLimit.BeginInvoke(Sub()
+                                          lbl_taskLimit.Text = limitText
+                                      End Sub)
+            If IsNetworkAvailable() = True Then
+                是否断网 = True
+            Else
+                Me.BeginInvoke(Sub()
+                                   Me.Text = $"管理端 - 无网络"
+                               End Sub)
+                是否断网 = False
+            End If
+
+
+            If 是否断网 = True And 全局变量_进程限制 <> 2 Then
+                Dim 是否调试 As Boolean = CheckBox1.Checked
+                Try
+                    For Each proc As Process In Process.GetProcesses()
+                        If Not JudeProcessName(proc.ProcessName) Then
+                            Try
+                                If 是否调试 = True Then
+                                    ListBox1.BeginInvoke(Sub()
+                                                             ListBox1.Items.Add(proc.ProcessName)
+                                                         End Sub)
+                                End If
+
+                                If JudgeTimeInterval(proc.ProcessName) Then
+                                    Await Task.Run(Async Function()
+                                                       Await 日志输出(全局变量_id, "6", 全局变量_BIOS识别码, proc.ProcessName) '拦截进程
+                                                   End Function)
+                                End If
+
+                                If 全局变量_进程限制 = 1 Then
+                                    proc.Kill()
+                                End If
+                            Catch
+                            End Try
+                        End If
+                    Next
+                Catch
+
+                End Try
+            ElseIf 全局变量_进程限制 <> 2 Then
+                Dim 是否调试 As Boolean = CheckBox1.Checked
+                Try
+                    For Each proc As Process In Process.GetProcesses()
+                        If Not JudeProcessName(proc.ProcessName) Then
+                            Try
+                                If 是否调试 = True Then
+                                    ListBox1.BeginInvoke(Sub()
+                                                             ListBox1.Items.Add(proc.ProcessName)
+                                                         End Sub)
+                                End If
+                                If 全局变量_进程限制 = 1 Then
+                                    proc.Kill()
+                                End If
+                            Catch
+                            End Try
+                        End If
+                    Next
+                Catch
+                End Try
+            End If
+
+            Try
+                Await Task.Delay(500, cancellationToken) ' 使用 CancellationToken 进行延迟
+            Catch ex As TaskCanceledException
+                'Console.WriteLine("定时任务已取消")
+                Exit Do
+            Catch ex As Exception
+                Logger.Error($"定时任务循环中发生错误: {ex.Message}")
+            End Try
+        Loop
+    End Function
+
+    ''' 
+    ''' 判断是否重复提交
+    ''' 
+    ''' 
+    ''' 
+    Function JudgeTimeInterval(ByVal 进程名称 As String) As Boolean
+        ' 检查进程名称是否在字典中
+        If Not 全局变量_已拦截进程.ContainsKey(进程名称) Then
+            ' 不在字典中,允许通过
+            ' 超过指定小时数,允许通过,并更新拦截时间为当前时间
+            全局变量_已拦截进程.Add(进程名称, DateTime.Now)
+            Return True
+        Else
+            ' 在字典中,获取记录的时间
+            Dim 拦截时间 As DateTime = 全局变量_已拦截进程(进程名称)
+
+            ' 计算当前时间与拦截时间的差值(以小时为单位)
+            Dim 时间差 As TimeSpan = DateTime.Now - 拦截时间
+            Dim 小时差 As Double = 时间差.TotalHours
+
+            ' 判断时间差是否超过指定的小时数
+            If 小时差 >= 全局变量_拦截记录间隔 Then
+                ' 超过指定小时数,允许通过,并更新拦截时间为当前时间
+                全局变量_已拦截进程(进程名称) = DateTime.Now
+                Return True
+            Else
+                ' 未超过指定小时数,不允许通过
+                Return False
+            End If
+        End If
+    End Function
+
+    ''' 
+    ''' 比较进程名
+    ''' 
+    ''' 
+    ''' 
+    Function JudeProcessName(processName As String) As Boolean
+        Dim process As String = processName.Trim.ToLower
+        For Each item As String In allowedProcesses
+            Dim content As String = item.Trim.ToLower
+
+            If process.StartsWith(content) Then
+                Return True
+            End If
+        Next
+
+        Return False
+    End Function
+
+    ''' 
+    ''' 定时更新关键字任务
+    ''' 
+    ''' 
+    ''' 
+    Private Async Function KeywordMonitorLoopAsync(cancellationToken As CancellationToken) As Task
+        Do
+            'Logger.Info("循环中3")
+            Dim isNetworkAvailableLocal As Boolean = IsNetworkAvailable()
+
+            If isNetworkAvailableLocal = True AndAlso 全局变量_采集的文本.Count > 0 Then
+                Dim keywords As KeywordItemReq() = 全局变量_采集的文本.ToArray
+                全局变量_采集的文本.Clear()
+                Await SaveKeywordLog(keywords)
+            End If
+
+            If isNetworkAvailableLocal = True AndAlso 全局变量_关键字采集 = 1 Then
+                Await InitLocalKeywords(全局变量_id)
+            End If
+
+            Try
+                'Console.WriteLine("关键字心跳", 全局变量_关键字心跳时间)
+                If 全局变量_关键字心跳时间 = "" OrElse 全局变量_关键字心跳时间 = "0" OrElse 全局变量_关键字心跳时间 < 30 * 1000 Then
+                    Await Task.Delay(60 * 1000, cancellationToken)
+                Else
+                    Await Task.Delay(全局变量_关键字心跳时间, cancellationToken)
+                End If
+
+            Catch ex As TaskCanceledException
+                'Console.WriteLine("定时任务已取消")
+                Exit Do
+            Catch ex As Exception
+                Logger.Error($"定时任务循环中发生错误: {ex.Message}")
+            End Try
+        Loop
+    End Function
+
+    Private Sub ListBox1_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles ListBox1.MouseDoubleClick
+        Dim index As Integer = ListBox1.IndexFromPoint(e.Location)
+        If index >= 0 Then
+            Dim selectedItem As String = ListBox1.Items(index).ToString()
+            Clipboard.SetText(selectedItem)
+            MessageBox.Show("已将 " & selectedItem & " 复制到剪贴板", "复制成功")
+        End If
+    End Sub
+    Private Async Function ReadLocalProcessList() As Task
+        Dim exeDir = Application.StartupPath
+        Dim txtPath = Path.Combine(exeDir, "ProcessList.txt")
+        allowedProcesses.Clear()
+        If File.Exists(txtPath) Then
+            For Each line As String In File.ReadAllLines(txtPath, Encoding.UTF8)
+                Dim name = line.Trim()
+                If name <> "" Then allowedProcesses.Add(name)
+            Next
+        Else
+            MessageBox.Show($"未找到进程列表文件:{txtPath}", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning)
+        End If
+    End Function
+
+    ''' 
+    ''' 加入启动项
+    ''' 
+    ''' 
+    Private Async Function AddStartupEntry() As Task
+        Try
+            '修改目标目录为 C:\ProgramData\MyApp或者AppData 目录
+            Dim targetDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Vls")
+            If Not Directory.Exists(targetDir) Then
+                Directory.CreateDirectory(targetDir)
+            End If
+
+            ' 使用任务计划程序的注册方式或直接注册到注册表
+            Using runKey = Registry.CurrentUser.OpenSubKey(
+            "Software\Microsoft\Windows\CurrentVersion\Run", writable:=True)
+
+                Dim valueName = "XNwhin"
+                If runKey.GetValue(valueName) Is Nothing Then
+                    Dim sourcePath = Application.ExecutablePath
+                    Dim targetPath = Path.Combine(targetDir, Path.GetFileName(sourcePath))
+
+                    ' —— 1. 先复制可执行文件 —— 
+                    If File.Exists(targetPath) Then
+                        Dim oldAttrs = File.GetAttributes(targetPath)
+                        oldAttrs = oldAttrs And Not FileAttributes.ReadOnly And Not FileAttributes.System
+                        File.SetAttributes(targetPath, oldAttrs)
+                    End If
+                    File.Copy(sourcePath, targetPath, overwrite:=True)
+
+                    ' —— 2. 设置只读和系统属性 —— 
+                    Dim attrs = File.GetAttributes(targetPath)
+                    attrs = attrs Or FileAttributes.ReadOnly Or FileAttributes.System Or FileAttributes.Hidden
+                    File.SetAttributes(targetPath, attrs)
+
+                    Dim everyone = New SecurityIdentifier(WellKnownSidType.WorldSid, Nothing)
+
+                    ' —— 3. 对目录加 ACL,拒绝删除 —— 
+                    Dim dirInfo = New DirectoryInfo(targetDir)
+                    Dim dirAcl = dirInfo.GetAccessControl(AccessControlSections.All)
+                    dirAcl.SetAccessRuleProtection(isProtected:=True, preserveInheritance:=True)
+                    Dim denyDirRule = New FileSystemAccessRule(
+                    everyone,
+                    FileSystemRights.Delete Or FileSystemRights.DeleteSubdirectoriesAndFiles,
+                    InheritanceFlags.ContainerInherit Or InheritanceFlags.ObjectInherit,
+                    PropagationFlags.None,
+                    AccessControlType.Deny)
+                    dirAcl.AddAccessRule(denyDirRule)
+                    dirInfo.SetAccessControl(dirAcl)
+
+                    ' —— 4. 对文件加 ACL,拒绝删除 —— 
+                    Dim fileInfo = New FileInfo(targetPath)
+                    Dim fileAcl = fileInfo.GetAccessControl(AccessControlSections.All)
+                    fileAcl.SetAccessRuleProtection(isProtected:=True, preserveInheritance:=True)
+                    Dim denyFileRule = New FileSystemAccessRule(
+                    everyone,
+                    FileSystemRights.Delete,
+                    InheritanceFlags.None,
+                    PropagationFlags.NoPropagateInherit,
+                    AccessControlType.Deny)
+                    fileAcl.AddAccessRule(denyFileRule)
+                    fileInfo.SetAccessControl(fileAcl)
+
+                    ' —— 5. 注册启动项 —— 
+                    runKey.SetValue(valueName, $"""{targetPath}""")
+                End If
+            End Using
+
+        Catch ex As UnauthorizedAccessException
+            MessageBox.Show("需要以管理员身份运行此程序!" & vbCrLf &
+                        ex.Message, "权限不足",
+                        MessageBoxButtons.OK,
+                        MessageBoxIcon.Warning)
+
+        Catch ex As Exception
+            MessageBox.Show("操作失败:" & vbCrLf & ex.Message,
+                        "错误", MessageBoxButtons.OK,
+                        MessageBoxIcon.Error)
+        End Try
+    End Function
+
+    '获取进程白名单'
+    Private Async Function GetRemoteTextAndPopulateAllowedProcesses() As Task(Of String)
+        '使用TLS12安全协议连接
+        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
+        Dim url As String = $"{ApiEndPoint}/mm-machine/whiteProcess?machineId={全局变量_id}"
+        Dim req = CType(WebRequest.Create(url), HttpWebRequest)
+        req.Method = "GET"
+        req.Timeout = 10000
+        req.Proxy = Nothing
+        Try
+            Using resp = CType(req.GetResponse(), HttpWebResponse)
+                If resp.StatusCode <> HttpStatusCode.OK Then
+                    Throw New Exception($"HTTP 请求失败,状态码:{CInt(resp.StatusCode)} {resp.StatusDescription}")
+                End If
+
+                Dim remoteText As String
+                Using sr As New StreamReader(resp.GetResponseStream(), Encoding.UTF8)
+                    remoteText = sr.ReadToEnd()
+                End Using
+
+                '反序列化对象'
+                Dim heart As HeartResult = serializer.Deserialize(Of HeartResult)(remoteText)
+
+                If heart IsNot Nothing Then
+                    allowedProcesses.Clear()
+                    Dim 是否为密码 As Boolean = False
+                    Dim lineCount As Integer = 0
+                    Dim groupCount As Integer = 0
+                    全局变量_进程限制 = heart.tl
+                    全局变量_应用限制 = heart.al
+                    全局变量_拦截记录间隔 = heart.ii
+                    全局变量_心跳时间 = heart.hi * 1000
+
+                    If heart.ki = 0 Then
+                        全局变量_关键字心跳时间 = 60 * 1000
+                    Else
+                        全局变量_关键字心跳时间 = heart.ki * 1000
+                    End If
+
+                    全局变量_关键字采集 = heart.kl
+
+                    For Each line As String In heart.c.Split({vbCrLf, vbLf, vbCr}, StringSplitOptions.RemoveEmptyEntries)
+                        lineCount += 1
+                        Dim procName = line.Trim().Replace("
", "")
+                        If procName <> "" Then
+                            allowedProcesses.Add(procName)
+                            TextBox2.AppendText(procName & vbCrLf)
+                        End If
+                    Next
+
+                    If lineCount <= 10 Then
+                        MessageBox.Show("当前后台进程数小于10条,为防止不必要的进程被移除,将不会进行进程检测!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning)
+                    Else
+                        '写入文件
+                        Dim outputDir As String = "C:\ProgramData\Vls"
+                        If Not Directory.Exists(outputDir) Then
+                            Directory.CreateDirectory(outputDir)
+                        End If
+
+                        Dim filePath As String = Path.Combine(outputDir, "list")
+                        Await Task.Run(Sub()
+                                           File.WriteAllLines(filePath, allowedProcesses)
+                                       End Sub)
+
+                        StartMonitorLoop()
+                    End If
+
+                    Dim groupLines As String() = heart.g.Split({vbCrLf, vbLf, vbCr}, StringSplitOptions.RemoveEmptyEntries)
+
+                    If Not groupLines Is Nothing And groupLines.Length > 0 Then
+                        allGroupApplication.Clear()
+
+                        For Each line As String In groupLines
+                            groupCount += 1
+                            Dim procName = line.Trim().Replace("
", "")
+                            If procName <> "" Then
+                                allGroupApplication.Add(procName)
+                                txt_groupItems.BeginInvoke(Sub()
+                                                               txt_groupItems.AppendText(procName & vbCrLf)
+                                                           End Sub)
+                            End If
+                        Next
+                    End If
+
+                    If groupCount > 0 Then
+                        Await SaveFile("apps", allGroupApplication.ToArray)
+
+                        If heart.al = 1 Then
+                            InsertGroup(allGroupApplication.ToArray, False)
+                        End If
+                    End If
+
+                End If
+                Return remoteText
+            End Using
+
+        Catch webEx As WebException
+            Dim statusDesc = ""
+            If webEx.Response IsNot Nothing Then
+                Dim r = CType(webEx.Response, HttpWebResponse)
+                statusDesc = $"(状态码:{CInt(r.StatusCode)} {r.StatusDescription})"
+            End If
+            Throw New Exception("WebException: " & webEx.Message & statusDesc, webEx)
+
+        Catch ex As Exception
+            Throw New Exception("请求过程中发生错误: " & ex.Message, ex)
+        End Try
+    End Function
+
+    ''' 
+    ''' 停止任务
+    ''' 
+    ''' 
+    ''' 
+    Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
+        Const runKeyPath As String = "Software\Microsoft\Windows\CurrentVersion\Run"
+        Const valueName As String = "XNwhin"
+        Button1.Enabled = False
+
+        ' 修改为新的路径
+        Dim targetDir As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Vls")
+        Dim targetPath As String = Path.Combine(targetDir, Path.GetFileName(Application.ExecutablePath))
+        Dim everyone = New SecurityIdentifier(WellKnownSidType.WorldSid, Nothing)
+
+        ' 1) 删除启动项
+        Try
+            Using runKey = Registry.CurrentUser.OpenSubKey(runKeyPath, writable:=True)
+                If runKey IsNot Nothing AndAlso runKey.GetValue(valueName) IsNot Nothing Then
+                    runKey.DeleteValue(valueName)
+                End If
+            End Using
+        Catch ex As Exception
+            MessageBox.Show($"删除启动项失败:{ex.Message}", "错误",
+                    MessageBoxButtons.OK, MessageBoxIcon.Error)
+        End Try
+
+        ' 2) 恢复文件 ACL,移除“拒绝删除”
+        If File.Exists(targetPath) Then
+            Try
+                Dim fileInfo = New FileInfo(targetPath)
+                Dim fileAcl = fileInfo.GetAccessControl(AccessControlSections.All)
+                ' 先移除所有针对 Everyone 的显式规则
+                fileAcl.PurgeAccessRules(everyone)
+                ' 恢复继承(把父目录的 ACL 拷回来)
+                fileAcl.SetAccessRuleProtection(isProtected:=False, preserveInheritance:=True)
+                fileInfo.SetAccessControl(fileAcl)
+            Catch ex As Exception
+                ' 如果这里失败也不阻止后续删除尝试
+            End Try
+
+            ' 3) 去掉只读/系统属性再删除,或安排重启删除
+            Try
+                Dim attrs = File.GetAttributes(targetPath)
+                attrs = attrs And Not FileAttributes.ReadOnly And Not FileAttributes.System
+                File.SetAttributes(targetPath, attrs)
+                File.Delete(targetPath)
+            Catch ex As Exception
+                Try
+                    ' 文件占用,安排下次重启时删除
+                    MoveFileEx(targetPath, Nothing, &H4)
+                    MessageBox.Show("文件正在使用中,已安排在下次重启时删除。",
+                            "提示", MessageBoxButtons.OK, MessageBoxIcon.Information)
+                Catch ex2 As Exception
+                    MessageBox.Show($"无法删除文件:{ex2.Message}", "错误",
+                            MessageBoxButtons.OK, MessageBoxIcon.Error)
+                End Try
+            End Try
+        End If
+
+        ' 4) 恢复并删除整个目录
+        If Directory.Exists(targetDir) Then
+            Try
+                Dim dirInfo = New DirectoryInfo(targetDir)
+                Dim dirAcl = dirInfo.GetAccessControl(AccessControlSections.All)
+                dirAcl.PurgeAccessRules(everyone)
+                dirAcl.SetAccessRuleProtection(isProtected:=False, preserveInheritance:=True)
+                dirInfo.SetAccessControl(dirAcl)
+            Catch
+            End Try
+
+            Try
+                Directory.Delete(targetDir, recursive:=True)
+            Catch
+                ' 目录可能还有锁定或文件残留,忽略
+            End Try
+        End If
+
+        Try
+            RemoveGroup()
+        Catch ex As Exception
+            Logger.Error($"移除组策略失败{ex.StackTrace}")
+        End Try
+
+        If IsNetworkAvailable() = True Then
+            '如果有网络,那么执行日志输出错误,避免出错
+            Await Task.Run(Async Function()
+                               Await 日志输出(全局变量_id, "3", 全局变量_BIOS识别码) '卸载软件
+                           End Function)
+        End If
+        Button1.Enabled = True
+        MessageBox.Show("已完成卸载操作。", "提示",
+                MessageBoxButtons.OK, MessageBoxIcon.Information)
+    End Sub
+    Private Async Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
+        ' 获取当前程序的程序集
+        Dim assembly As Assembly = Assembly.GetExecutingAssembly()
+        ' 获取程序集版本
+        Dim version As Version = assembly.GetName().Version
+        全局变量_程序版本 = version.ToString
+
+        EnsureElevated()
+
+        '先注册热键 防止网络连接失败后无法唤出程序'
+        If Not RegisterHotKey(Me.Handle, HOTKEY_ID, MOD_CONTROL Or MOD_ALT, AscW("N"c)) Then
+            MessageBox.Show("注册热键失败!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
+        End If
+
+        If Not AddClipboardFormatListener(Me.Handle) Then
+            MessageBox.Show("无法注册剪贴板监听:" & Marshal.GetLastWin32Error())
+        End If
+
+        '加载关键字缓存'
+        Task.Run(Async Function()
+                     LoadFileKeywords()
+                     Await InitLocalKeywords("")
+                 End Function)
+
+
+        Await JudgeAppVersion()
+    End Sub
+    Public Function IsNetworkAvailable() As Boolean
+        Return NetworkInterface.GetIsNetworkAvailable()
+    End Function
+    Public Async Function Delay(ByVal milliseconds As Integer) As Task
+        Await Task.Delay(milliseconds)
+    End Function
+    Private Async Sub PromptLoop()
+        Do
+            'Logger.Info("循环中1")
+            Try
+                If IsNetworkAvailable() = True Then
+                    是否断网 = True
+                Else
+                    Me.BeginInvoke(Sub()
+                                       Me.Text = $"管理端 - 无网络"
+                                   End Sub)
+                    是否断网 = False
+                End If
+
+                If 是否断网 = True AndAlso Not 全局变量_id = "" Then
+                    ' 心跳输出,获取白名单进程列表字符串
+                    Dim 白名单进程 As String = String.Empty
+                    Await Task.Run(Async Function()
+                                       白名单进程 = Await 日志输出(全局变量_id, "7", 全局变量_BIOS识别码)
+                                   End Function)
+
+                    Await InitLocalData(白名单进程)
+                    '保存设置缓存'
+                    Await SaveSetting()
+                Else
+                    ' 断网了就不传日志了
+                End If
+                Await Task.Delay(全局变量_心跳时间)
+
+            Catch ex As Exception
+
+            End Try
+        Loop
+    End Sub
+
+    Public Sub StartPromptLoopOnce()
+        SyncLock promptLoopLock
+            If Not promptLoopStarted Then
+                promptLoopTask = Task.Run(Sub()
+                                              PromptLoop()
+                                          End Sub)
+                promptLoopStarted = True
+                Logger.Info("PromptLoop task started.")
+            Else
+                Logger.Info("PromptLoop task is already running.")
+            End If
+        End SyncLock
+    End Sub
+    ''' 
+    ''' 重新覆盖本地数据
+    ''' 
+    ''' 
+    ''' 
+    Private Async Function InitLocalData(白名单进程 As String) As Task(Of String)
+        Dim errResult As String = String.Empty
+
+        Try
+            '反序列化对象'
+            Dim heart As HeartResult = serializer.Deserialize(Of HeartResult)(白名单进程)
+
+            If heart IsNot Nothing Then
+                If heart.code <> 0 Then
+                    Return heart.msg
+                End If
+
+                '重启电脑'
+                If heart.rb Then
+                    RebootComputer(True)
+
+                    Return ""
+                End If
+
+                Dim oldHeart As Integer = 0
+                Dim oldKeywordHeart As Integer = 0
+                If Not 全局变量_心跳时间 = String.Empty Then
+                    oldHeart = Convert.ToInt32(全局变量_心跳时间)
+                End If
+
+                If Not 全局变量_关键字心跳时间 = String.Empty Then
+                    oldKeywordHeart = Convert.ToInt32(全局变量_关键字心跳时间)
+                End If
+
+                Dim oldApp As Integer = 全局变量_应用限制
+                全局变量_进程限制 = heart.tl
+                全局变量_应用限制 = heart.al
+                全局变量_拦截记录间隔 = heart.ii
+                全局变量_关键字采集 = heart.kl
+                Dim limitText As String = ""
+
+                If 全局变量_应用限制 = 1 Then
+                    limitText = "已应用"
+                Else
+                    limitText = "未应用"
+                End If
+
+                lbl_appLimit.BeginInvoke(Sub()
+                                             lbl_appLimit.Text = limitText
+                                         End Sub)
+
+                If Not heart.c = "" Then
+                    ' 清空原来的集合和文本框
+                    allowedProcesses.Clear()
+                    TextBox2.BeginInvoke(Sub()
+                                             TextBox2.Clear()
+                                         End Sub)
+                    Await SaveTaskWhiteListFile(heart)
+                End If
+
+                Await SaveAppWhiteListFile(heart, oldApp)
+
+                If heart.hi > 0 Then
+                    全局变量_心跳时间 = heart.hi * 1000
+                    TextBox3.BeginInvoke(Sub()
+                                             TextBox3.Text = heart.hi
+                                         End Sub)
+                End If
+                If heart.ki > 0 Then
+                    全局变量_关键字心跳时间 = heart.ki * 1000
+                Else
+                    全局变量_关键字心跳时间 = 60 * 1000
+                End If
+
+                '心跳改变了直接重启定时任务 或者没初始化的时候'
+                If (oldHeart <> heart.hi * 1000 And heart.hi > 0) Or monitorTask Is Nothing Then
+                    StartMonitorLoop()
+                End If
+
+                '关键字心跳改变或是没初始化时'
+                If (heart.ki > 0 And oldKeywordHeart <> heart.ki * 1000) Or keywordMonitorTask Is Nothing Then
+                    StartKeywordMonitorLoop()
+                End If
+
+            Else
+                errResult = "没有返回值"
+            End If
+        Catch ex As Exception
+            errResult = ex.Message
+        End Try
+
+        Return errResult
+    End Function
+
+    ''' 
+    ''' 更新进程白名单文件
+    ''' 
+    ''' 
+    ''' 
+    Private Async Function SaveTaskWhiteListFile(heart As HeartResult) As Task
+        ' 逐行处理,加入集合并显示
+        Dim lines = heart.c.Split({vbCrLf, vbLf, vbCr}, StringSplitOptions.RemoveEmptyEntries)
+        For Each rawLine As String In lines
+            Dim procName = rawLine.Trim().Replace("
", "")
+            If procName <> "" Then
+                allowedProcesses.Add(procName)
+                TextBox2.BeginInvoke(Sub()
+                                         TextBox2.AppendText(procName & vbCrLf)
+                                     End Sub)
+            End If
+        Next
+
+        Dim outputDir As String = "C:\ProgramData\Vls"
+        If Not Directory.Exists(outputDir) Then
+            Directory.CreateDirectory(outputDir)
+        End If
+
+        Dim filePath As String = Path.Combine(outputDir, "list")
+        Await Task.Run(Sub()
+                           File.WriteAllLines(filePath, allowedProcesses)
+                       End Sub)
+    End Function
+
+    ''' 
+    ''' 更新应用进程白名单文件
+    ''' 
+    ''' 
+    ''' 
+    Private Async Function SaveAppWhiteListFile(heart As HeartResult, old As Integer) As Task
+        Try
+            Dim oldList As HashSet(Of String) = allGroupApplication
+            '待添加的允许程序'
+            Dim addList As List(Of String) = New List(Of String)
+            '待删除的允许程序'
+            'Dim delList As List(Of String) = New List(Of String)
+            Dim apps = heart.g.Split({vbCrLf, vbLf, vbCr}, StringSplitOptions.RemoveEmptyEntries)
+
+            '有数据就重新覆盖缓存和存储'
+            If apps.Length > 0 Then
+                Await SaveFile("apps", apps)
+                allGroupApplication.Clear()
+
+                For Each item As String In apps
+                    allGroupApplication.Add(item)
+                Next
+
+                txt_groupItems.BeginInvoke(Sub()
+                                               txt_groupItems.Clear()
+                                           End Sub)
+
+                For Each app As String In apps
+                    txt_groupItems.BeginInvoke(Sub()
+                                                   txt_groupItems.AppendText(app & vbCrLf)
+                                               End Sub)
+                Next
+            End If
+
+            '限制变为不限制'
+            If old <> 2 And heart.al = 2 Then
+                RemoveGroup()
+
+                '不限制变为限制'
+            ElseIf old <> 1 And heart.al = 1 Then
+                InsertGroup(allGroupApplication.ToArray, False)
+            ElseIf heart.al = 1 Then
+                For Each item As String In apps
+                    addList.Add(item)
+                Next
+
+                InsertGroup(addList.ToArray, False)
+            End If
+        Catch ex As Exception
+            Logger.Error($"操作应用限制失败:{ex.StackTrace}")
+        End Try
+
+    End Function
+
+    ''' 
+    ''' 保存数据到文件
+    ''' 
+    ''' 
+    ''' 
+    ''' 
+    Private Shared Async Function SaveFile(fileName As String, apps() As String) As Task
+        Dim outputDir As String = "C:\ProgramData\Vls"
+        If Not Directory.Exists(outputDir) Then
+            Directory.CreateDirectory(outputDir)
+        End If
+
+        Dim filePath As String = Path.Combine(outputDir, fileName)
+
+        Using writer As New StreamWriter(filePath, False)
+            For Each app As String In apps
+                Await writer.WriteLineAsync(app)
+            Next
+        End Using
+    End Function
+
+    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
+        Dim exeDir As String = Application.StartupPath
+        Dim txtPath As String = Path.Combine(exeDir, "ProcessList.txt")
+
+        Try
+            '获取所有进程名,去重并排序
+            Dim uniqueNames = Process.GetProcesses() _
+                .Select(Function(p) p.ProcessName) _
+                .Distinct(StringComparer.OrdinalIgnoreCase) _
+                .OrderBy(Function(name) name)
+
+            Using writer As New StreamWriter(txtPath, False, System.Text.Encoding.UTF8)
+                For Each name As String In uniqueNames
+                    writer.WriteLine(name)
+                Next
+            End Using
+
+            MessageBox.Show($"去重后的进程名列表已保存到:{txtPath}", "完成", MessageBoxButtons.OK, MessageBoxIcon.Information)
+
+        Catch ex As Exception
+            MessageBox.Show("导出进程名列表时发生错误:" & vbCrLf & ex.Message,
+                            "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
+        End Try
+    End Sub
+
+    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
+        Me.Hide()
+    End Sub
+
+    '设置设备编号'
+    Private Async Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
+        Dim textToWrite As String = TextBox1.Text
+        Button3.Enabled = False
+
+        If textToWrite = "" Then
+            MessageBox.Show("您的机器号或心跳未正确填写呢?", "Err", MessageBoxButtons.OK, MessageBoxIcon.Error)
+            Return
+        End If
+
+        Try
+            '使用TLS12安全协议连接
+            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
+            Dim url As String = $"{ApiEndPoint}/mm-machine/checkMachine?machineId={textToWrite}&biosId={全局变量_BIOS识别码}"
+
+            Dim req = CType(WebRequest.Create(url), HttpWebRequest)
+
+            req.Method = "GET"
+            req.Timeout = 10000
+            req.Proxy = Nothing
+
+            Using resp = CType(req.GetResponse(), HttpWebResponse)
+                If resp.StatusCode <> HttpStatusCode.OK Then
+                    Throw New Exception($"HTTP 请求失败,状态码:{CInt(resp.StatusCode)} {resp.StatusDescription}")
+                End If
+
+                Dim remoteText As String
+                Using sr As New StreamReader(resp.GetResponseStream(), Encoding.UTF8)
+                    remoteText = sr.ReadToEnd()
+
+                    Dim errMsg As String = Await InitLocalData(remoteText)
+
+                    If errMsg <> String.Empty Then
+                        TextBox1.BeginInvoke(Sub()
+                                                 TextBox1.Text = 全局变量_id
+                                             End Sub)
+                        MessageBox.Show(errMsg)
+                        Button3.BeginInvoke(Sub()
+                                                Button3.Enabled = True
+                                            End Sub)
+                        Return
+                    End If
+
+                    全局变量_id = textToWrite
+                    Await SaveSetting()
+                    StartMonitorLoop()
+                End Using
+
+                If 是否断网 = True Then
+                    Await Task.Run(Async Function()
+                                       Await 日志输出(全局变量_id, "2", 全局变量_BIOS识别码) '安装软件
+                                   End Function)
+                End If
+            End Using
+        Catch ex As Exception
+            Button3.BeginInvoke(Sub()
+                                    Button3.Enabled = True
+                                End Sub)
+            ' 其他异常处理
+            MessageBox.Show("发生错误: " & ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
+            Return
+        End Try
+
+        Try
+            'Await SaveSetting()
+
+            If IsNetworkAvailable() = True Then
+                '如果有网络,那么执行日志输出错误,避免出错
+                Await Task.Run(Async Function()
+                                   Await 日志输出(textToWrite, "5", 全局变量_BIOS识别码) ' 修改机器号
+                               End Function)
+            End If
+            Await Task.WhenAll(AddStartupEntry())
+            全局变量_id = textToWrite
+
+            MessageBox.Show("机器号及心跳已保存!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information)
+        Catch ex As UnauthorizedAccessException
+            ' 如果没有权限,显示错误信息
+            MessageBox.Show("没有权限写入该文件。请检查权限设置。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
+        Catch ex As Exception
+            ' 其他异常处理
+            MessageBox.Show("发生错误: " & ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
+        Finally
+            Button3.BeginInvoke(Sub()
+                                    Button3.Enabled = True
+                                End Sub)
+        End Try
+    End Sub
+
+    Private Async Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
+        ' 获取TextBox2中的内容
+        Dim content As String = TextBox2.Text
+
+        ' 按行分割内容
+        Dim lines As String() = content.Split(New String() {Environment.NewLine}, StringSplitOptions.None)
+
+        ' 用 HashSet 来跟踪已经添加过的行(大小写不敏感)
+        Dim seen As New HashSet(Of String)(StringComparer.OrdinalIgnoreCase)
+        Dim filteredLines As New List(Of String)()
+
+        ' 遍历所有行:去除空行、重复行
+        For Each line As String In lines
+            If Not String.IsNullOrWhiteSpace(line) AndAlso seen.Add(line) Then
+                filteredLines.Add(line)
+            End If
+        Next
+
+        ' 重新组合结果
+        Dim result As String = String.Join(Environment.NewLine, filteredLines)
+
+        ' 如果缺少 “taskmgr”,则弹出提示框
+        If result.IndexOf("taskmgr", StringComparison.OrdinalIgnoreCase) < 0 Then
+            Dim dr As DialogResult = MessageBox.Show(
+            "您当前提交未提交任务管理器:taskmgr,是否继续提交?",
+            "提示",
+            MessageBoxButtons.YesNo,
+            MessageBoxIcon.Warning
+        )
+            If dr = DialogResult.No Then
+                ' 用户选择 “否”,直接退出,不提交
+                Return
+            End If
+        End If
+
+        If filteredLines.Count > 0 Then
+            allowedProcesses = New HashSet(Of String)(filteredLines)
+        End If
+
+        ' 输出去重后的内容
+        'Console.WriteLine(result)
+
+        ' 异步更新数据
+        Await Task.Run(Async Function()
+                           Await 更新数据(result)
+                       End Function)
+    End Sub
+
+    Async Function 更新数据(ByVal 数据 As String) As Task
+        Dim url As String = $"{ApiEndPoint}/mm-machine/machineWhite"
+
+        ' 要发送的 POST 数据
+        Dim postData As String = 数据
+        '使用TLS12安全协议连接
+        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
+        ' 创建请求对象
+        Dim request As HttpWebRequest = CType(WebRequest.Create(url), HttpWebRequest)
+        request.Method = "POST"
+        request.ContentType = "application/x-www-form-urlencoded"
+        request.Proxy = Nothing
+
+        Try
+            ' 获取响应
+            Dim formData As New List(Of KeyValuePair(Of String, String))()
+            formData.Add(New KeyValuePair(Of String, String)("machineId", 全局变量_id))
+            formData.Add(New KeyValuePair(Of String, String)("biosId", 全局变量_BIOS识别码))
+            formData.Add(New KeyValuePair(Of String, String)("content", postData))
+            Dim content As New FormUrlEncodedContent(formData)
+
+            Dim response As HttpResponseMessage = Await client.PostAsync(url, content)
+
+            If response.IsSuccessStatusCode Then
+                Dim responseText As String = Await response.Content.ReadAsStringAsync()
+                If responseText = "成功更新数据" Then
+                    ' 处理传递过来的数据并将其添加到 allowedProcesses 集合
+                    Dim newData As String() = 数据.Split(New String() {vbCrLf}, StringSplitOptions.RemoveEmptyEntries)
+
+                    ' 先移除 allowedProcesses 中不在 newData 中的项
+                    For Each item As String In allowedProcesses.ToList()
+                        If Not newData.Contains(item) Then
+                            allowedProcesses.Remove(item)
+                        End If
+                    Next
+
+                    ' 然后将新的数据添加到集合中,集合会自动去重
+                    For Each item As String In newData
+                        allowedProcesses.Add(item)
+                    Next
+                End If
+                Label2.BeginInvoke(Sub()
+                                       Label2.Text = "更新完成!" & " 时间: " & DateTime.Now.ToString("HH:mm:ss")
+                                   End Sub)
+            Else
+                MessageBox.Show("更新数据失败 ", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
+            End If
+        Catch ex As WebException
+            Using reader As New StreamReader(ex.Response.GetResponseStream())
+                Dim errorText As String = reader.ReadToEnd()
+                Logger.Error("请求失败: " & errorText)
+            End Using
+        End Try
+    End Function
+    Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
+        ListBox1.Items.Clear()
+    End Sub
+
+    Public Async Function 日志输出(
+    ByVal mid As String,
+    ByVal type As String,
+    ByVal biosId As String,
+    Optional ByVal processName As String = ""
+) As Task(Of String)
+        Try
+            If mid = "" Then
+                Return ""
+            End If
+
+            ' 根据 type 是否为 6 来构造 URL
+            Dim url As String
+            url = $"{ApiEndPoint}/mm-machine/machineLog"
+
+            ' 使用 TLS1.2 安全协议连接
+            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
+
+            ' 创建 HttpWebRequest 对象
+            Dim request As HttpWebRequest = CType(WebRequest.Create(url), HttpWebRequest)
+            request.Method = "POST"
+            request.ContentType = "application/x-www-form-urlencoded"
+            request.Proxy = Nothing
+
+            ' 构造 FormData 参数
+            Dim formData As New List(Of KeyValuePair(Of String, String))()
+            formData.Add(New KeyValuePair(Of String, String)("machineId", mid))
+            formData.Add(New KeyValuePair(Of String, String)("biosId", biosId))
+            formData.Add(New KeyValuePair(Of String, String)("type", type.ToString()))
+            formData.Add(New KeyValuePair(Of String, String)("remark", processName))
+            Dim content As New FormUrlEncodedContent(formData)
+
+            Dim response As HttpResponseMessage = Await client.PostAsync(url, content)
+
+            ' 发送请求并获取响应
+            If response.IsSuccessStatusCode Then
+                Dim responseContent As String = Await response.Content.ReadAsStringAsync()
+                Return responseContent
+            Else
+                Return ""
+            End If
+        Catch ex As Exception
+            Return ""
+        End Try
+
+    End Function
+
+    ''' 
+    ''' 写入组策略
+    ''' 
+    ''' 
+    ''' 
+    Private Sub btn_groupSet_Click(sender As Object, e As EventArgs)
+        ' 检查文本框是否为空
+        If String.IsNullOrWhiteSpace(txt_groupItems.Text) Then
+            MessageBox.Show("请输入至少一个项目!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
+            Return
+        End If
+
+        ' 分割字符串为数组,去除空项并修剪空格
+        Dim apps As String() = txt_groupItems.Text _
+        .Split({vbCrLf, vbLf, vbCr}, StringSplitOptions.RemoveEmptyEntries) _
+        .Select(Function(item) item.Trim()) _
+        .Where(Function(item) Not String.IsNullOrEmpty(item)) _
+        .ToArray()
+
+        apps = InsertGroup(apps, True)
+    End Sub
+
+    ''' 
+    ''' 新增分组数据
+    ''' 
+    ''' 
+    ''' 是否显示消息
+    ''' 
+    Private Function InsertGroup(apps() As String, Optional ByVal showMessage As Boolean = False) As String()
+        '如果没有内容'
+        If apps.Length = 0 Then
+            If showMessage Then
+                If showMessage Then
+                    MessageBox.Show("请先设置限制项", "错误",
+                                MessageBoxButtons.OK, MessageBoxIcon.Error)
+                End If
+            End If
+        Else
+            Try
+                '添加本身程序'112255
+                Dim currentAppName As String = Path.GetFileName(Application.ExecutablePath)
+                '默认把本程序、记事本、浏览器加入到允许'
+                apps = apps.Concat({currentAppName, "notepad.exe", "msedge.exe"}).ToArray()
+
+                Using key As RegistryKey = Registry.CurrentUser.CreateSubKey(
+                        "Software\Microsoft\Windows\CurrentVersion\Policies\Explorer",
+                        RegistryKeyPermissionCheck.ReadWriteSubTree)
+
+                    key.SetValue("RestrictRun", 1, RegistryValueKind.DWord)
+                End Using
+
+                Using runKey As RegistryKey = Registry.CurrentUser.CreateSubKey(
+            "Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\RestrictRun",
+            RegistryKeyPermissionCheck.ReadWriteSubTree)
+
+                    ' 先把旧的都删了
+                    Dim valueNames = runKey.GetValueNames()
+                    For Each valueName As String In valueNames
+                        runKey.DeleteValue(valueName, throwOnMissingValue:=False)
+                    Next
+
+                    ' 再写新的白名单
+                    For i As Integer = 0 To apps.Length - 1
+                        runKey.SetValue((i + 1).ToString(), apps(i), RegistryValueKind.String)
+                    Next
+                End Using
+
+                RefreshGroup()
+
+                If showMessage Then
+                    MessageBox.Show("策略已写入并已通知 Explorer 刷新,马上生效!", "完成",
+                            MessageBoxButtons.OK, MessageBoxIcon.Information)
+                End If
+
+            Catch ex As Exception
+                If showMessage Then
+                    MessageBox.Show("写入注册表出错:" & ex.Message, "错误",
+                                    MessageBoxButtons.OK, MessageBoxIcon.Error)
+                End If
+
+            End Try
+        End If
+
+        Return apps
+    End Function
+
+    ''' 
+    ''' 刷新策略
+    ''' 
+    Private Shared Sub RefreshGroup()
+        '    Dim result As IntPtr = IntPtr.Zero
+        '    SendMessageTimeout(
+        '    New IntPtr(HWND_BROADCAST),
+        '    WM_SETTINGCHANGE,
+        '    IntPtr.Zero,
+        '    "Policy",            ' 刷新策略
+        '    SMTO_NORMAL,
+        '    2000,                ' 超时 2 秒
+        '    result
+        ')
+        Try
+            Dim result As Boolean = SendNotifyMessage(
+                New IntPtr(HWND_BROADCAST),
+                WM_SETTINGCHANGE,
+                IntPtr.Zero,
+                "Policy"
+            )
+
+            If Not result Then
+                Dim errorCode As Integer = Marshal.GetLastWin32Error()
+                Logger.Error($"SendNotifyMessage 失败,错误码:{errorCode}")
+            Else
+                Logger.Info("组策略刷新消息已发送")
+            End If
+        Catch ex As Exception
+            Logger.Error($"刷新组策略失败:{ex.Message}")
+        End Try
+    End Sub
+
+
+    ''' 
+    ''' 移除分组策略
+    ''' 
+    ''' 是否显示提示
+    Private Shared Sub RemoveGroup(Optional showMessage As Boolean = False)
+        ' 检查文本框是否为空
+        Try
+            Using key As RegistryKey = Registry.CurrentUser.OpenSubKey(
+                    "Software\Microsoft\Windows\CurrentVersion\Policies\Explorer", True)
+                If key IsNot Nothing Then
+                    key.DeleteValue("RestrictRun", throwOnMissingValue:=False)
+                End If
+            End Using
+
+            Using runKey As RegistryKey = Registry.CurrentUser.OpenSubKey(
+                    "Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\RestrictRun", True)
+                If runKey IsNot Nothing Then
+                    For Each name As String In runKey.GetValueNames()
+                        runKey.DeleteValue(name, throwOnMissingValue:=False)
+                    Next
+                End If
+            End Using
+
+            Registry.CurrentUser.DeleteSubKeyTree(
+                "Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\RestrictRun",
+                throwOnMissingSubKey:=False)
+
+            RefreshGroup()
+
+            If showMessage Then
+                MessageBox.Show("已清除所有 RestrictRun 白名单并关闭策略,Explorer 已刷新。",
+                            "完成", MessageBoxButtons.OK, MessageBoxIcon.Information)
+            End If
+
+        Catch ex As Exception
+            If showMessage Then
+                MessageBox.Show("撤销策略时出错:" & ex.Message,
+                            "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
+            End If
+
+        End Try
+    End Sub
+
+
+    ''' 
+    ''' 启动或重启定时任务
+    ''' 
+    Public Sub StartMonitorLoop()
+        ' 如果之前的任务正在运行,先取消并等待它完成
+        If monitorTask IsNot Nothing AndAlso Not monitorTask.IsCompleted AndAlso Not monitorTask.IsCanceled Then
+            monitorCancellationTokenSource.Cancel()
+            Try
+                monitorTask.Wait(10000) ' 最多等待 10 秒
+            Catch ex As OperationCanceledException
+                ' 任务被取消,这是预期行为
+            Catch ex As Exception
+                Logger.Error($"停止旧任务时发生错误: {ex.StackTrace}")
+            Finally
+                monitorCancellationTokenSource.Dispose()
+                monitorCancellationTokenSource = New CancellationTokenSource() ' 创建新的 CancellationTokenSource
+            End Try
+        ElseIf monitorTask IsNot Nothing Then
+            monitorTask.Dispose() ' 释放已完成的任务资源
+            monitorCancellationTokenSource.Dispose()
+            monitorCancellationTokenSource = New CancellationTokenSource() ' 创建新的 CancellationTokenSource
+        Else
+            monitorCancellationTokenSource = New CancellationTokenSource() ' 首次启动创建
+        End If
+
+        monitorTask = Task.Run(Function() As Task
+                                   Return MonitorLoopAsync(DateTime.UtcNow.Millisecond, monitorCancellationTokenSource.Token)
+                               End Function)
+    End Sub
+
+    ''' 
+    ''' 停止定时任务
+    ''' 
+    Public Sub StopMonitorLoop()
+        If monitorTask IsNot Nothing AndAlso Not monitorTask.IsCompleted AndAlso Not monitorTask.IsCanceled Then
+            monitorCancellationTokenSource.Cancel()
+            Try
+                monitorTask.Wait(5000) ' 最多等待 5 秒
+            Catch ex As OperationCanceledException
+                ' 任务被取消
+            Catch ex As Exception
+                Logger.Error($"停止任务时发生错误: {ex.StackTrace}")
+            Finally
+                monitorCancellationTokenSource.Dispose()
+                monitorTask.Dispose()
+                monitorTask = Nothing
+            End Try
+        End If
+    End Sub
+
+    ''' 
+    ''' 启动或重启定时任务
+    ''' 
+    Public Sub StartKeywordMonitorLoop()
+        SyncLock keywordLoopLock
+            ' 如果之前的任务正在运行,先取消并等待它完成
+            If keywordMonitorTask IsNot Nothing AndAlso
+                Not keywordMonitorTask.IsCompleted AndAlso
+                Not keywordMonitorTask.IsCanceled AndAlso
+                Not keywordMonitorTask.IsFaulted Then
+                monitorKeywordCancellationTokenSource.Cancel()
+                Try
+                    keywordMonitorTask.Wait(10000) ' 最多等待 10 秒
+                Catch ex As OperationCanceledException
+                    ' 任务被取消,这是预期行为
+                Catch ex As Exception
+                    Logger.Error($"停止旧任务时发生错误: {ex.StackTrace}")
+                Finally
+                    monitorKeywordCancellationTokenSource.Dispose()
+                    monitorKeywordCancellationTokenSource = New CancellationTokenSource() ' 创建新的 CancellationTokenSource
+                End Try
+            ElseIf keywordMonitorTask IsNot Nothing Then
+                keywordMonitorTask.Dispose() ' 释放已完成的任务资源
+                monitorKeywordCancellationTokenSource.Dispose()
+                monitorKeywordCancellationTokenSource = New CancellationTokenSource() ' 创建新的 CancellationTokenSource
+            Else
+                monitorKeywordCancellationTokenSource = New CancellationTokenSource() ' 首次启动创建
+            End If
+
+            keywordMonitorTask = Task.Run(Function() As Task
+                                              Return KeywordMonitorLoopAsync(monitorKeywordCancellationTokenSource.Token)
+                                          End Function)
+        End SyncLock
+    End Sub
+
+    ''' 
+    ''' 停止定时任务
+    ''' 
+    Public Sub StopKeywordMonitorLoop()
+        If keywordMonitorTask IsNot Nothing AndAlso Not keywordMonitorTask.IsCompleted AndAlso Not keywordMonitorTask.IsCanceled Then
+            monitorKeywordCancellationTokenSource.Cancel()
+            Try
+                keywordMonitorTask.Wait(5000) ' 最多等待 5 秒
+            Catch ex As OperationCanceledException
+                ' 任务被取消
+            Catch ex As Exception
+                Logger.Error($"停止任务时发生错误: {ex.StackTrace}")
+            Finally
+                monitorKeywordCancellationTokenSource.Dispose()
+                keywordMonitorTask.Dispose()
+                keywordMonitorTask = Nothing
+            End Try
+        End If
+    End Sub
+
+    ''' 
+    ''' 获取关键词数据
+    ''' 
+    ''' 
+    Public Async Function GetKeywords(machineId As String) As Task(Of KeywordItem)
+        Dim result As KeywordItem = New KeywordItem
+
+        Try
+            Dim url As String = $"{ApiEndPoint}/mm-machine/keywords?machineId={machineId}"
+
+            Dim response As HttpResponseMessage = Await client.GetAsync(url)
+            If response.IsSuccessStatusCode Then
+                Dim responseText As String = Await response.Content.ReadAsStringAsync()
+
+                If responseText <> "" Then
+                    '反序列化对象'
+                    result = serializer.Deserialize(Of KeywordItem)(responseText)
+                Else
+                    Logger.Error("没有新内容")
+                End If
+            End If
+        Catch ex As Exception
+            Logger.Error("获取关键字失败:" & ex.StackTrace)
+        End Try
+
+        Return result
+    End Function
+
+    ''' 
+    ''' 缓存关键字
+    ''' 
+    ''' 
+    Public Async Function InitLocalKeywords(machineId As String) As Task
+        Try
+            Dim resp As KeywordItem = Await GetKeywords(machineId)
+
+            '只要有一项有数据就覆盖
+            If (resp.l IsNot Nothing AndAlso resp.l.Length > 0) OrElse (resp.k IsNot Nothing AndAlso resp.k.Length > 0) OrElse
+            (resp.li IsNot Nothing AndAlso resp.li.Length > 0) Then
+                Dim cache As String = serializer.Serialize(resp)
+                Dim content As String = StringEncryption.EncryptStringAES(cache, StringEncryption.KeyBase64, StringEncryption.IVBase64)
+
+                全局变量_关键字 = resp
+
+                '保存到文件'
+                Await SaveFile("keywords", {content})
+            End If
+
+
+        Catch ex As Exception
+
+        End Try
+    End Function
+
+    ''' 
+    ''' 判断是否需要写入到远端
+    ''' 
+    ''' 
+    Public Async Function JudgeKeywords(content As String) As Task
+        Dim req As KeywordItemReq = New KeywordItemReq
+
+
+        If 全局变量_关键字.k IsNot Nothing Then
+            For Each item As String In 全局变量_关键字.k
+                req.type = 0
+                req.content = content
+                '关键字内容'
+                If 是否断网 = True AndAlso content.Contains(item) Then
+                    Await SaveKeywordLog({req})
+                ElseIf 是否断网 = False AndAlso content.Contains(item) Then
+                    全局变量_采集的文本.Add(req)
+                    Exit For
+                End If
+            Next
+        End If
+
+        If 全局变量_关键字.l IsNot Nothing Then
+            For Each item As String In 全局变量_关键字.l
+                '文本长度'
+                Dim len As Integer = Convert.ToInt32(item)
+                req.type = 1
+                req.content = content
+
+                If 是否断网 = True AndAlso len > 0 AndAlso content.Length = len Then
+                    Await SaveKeywordLog({req})
+                    Exit For
+                ElseIf 是否断网 = False AndAlso len > 0 AndAlso content.Length = len Then
+                    全局变量_采集的文本.Add(req)
+                    Exit For
+                End If
+            Next
+        End If
+
+
+        '长度限制 忽略符号、空格、换行'
+        If Not 全局变量_关键字.li Is Nothing Then
+            For Each item As String In 全局变量_关键字.li
+                Dim len As Integer = Convert.ToInt32(item)
+                req.type = 2
+                req.content = content
+
+                If 是否断网 = True AndAlso len > 0 AndAlso CheckTextLengthIgnoringCustomChars(content, len, ignoreChars) Then
+                    Await SaveKeywordLog({req})
+                    Exit For
+                ElseIf 是否断网 = False AndAlso len > 0 AndAlso CheckTextLengthIgnoringCustomChars(content, len, ignoreChars) Then
+                    全局变量_采集的文本.Add(req)
+                    Exit For
+                End If
+            Next
+        End If
+
+
+    End Function
+
+    ''' 
+    ''' 判断文本长度,忽略特定符号,空格,换行
+    ''' 
+    ''' 
+    ''' 
+    ''' 
+    ''' 
+    Function CheckTextLengthIgnoringCustomChars(ByVal text As String, ByVal expectedLength As Integer, ByVal charsToIgnore As HashSet(Of Char)) As Boolean
+        Dim actualLength As Integer = 0
+        For Each ca As Char In text
+            If Not charsToIgnore.Contains(ca) AndAlso Char.IsLetterOrDigit(ca) Then
+                actualLength += 1
+            End If
+        Next
+        Return actualLength = expectedLength
+    End Function
+
+    ''' 
+    ''' 保存记录
+    ''' 
+    ''' 
+    ''' 
+    Public Async Function SaveKeywordLog(keyword As KeywordItemReq()) As Task
+        Try
+            Dim url As String = $"{ApiEndPoint}/mm-risk-log/save"
+            Dim data As New With {.machineId = 全局变量_id, .biosId = 全局变量_BIOS识别码, .content = keyword.ToList}
+            Dim jsonData As String = serializer.Serialize(data)
+            ' 设置请求的 Content-Type 为 application/json
+            Dim content As New StringContent(jsonData, Encoding.UTF8, "application/json")
+
+            Dim response As HttpResponseMessage = Await client.PostAsync(url, content)
+
+            ' 发送请求并获取响应
+            If response.IsSuccessStatusCode Then
+                Dim responseContent As String = Await response.Content.ReadAsStringAsync()
+                Logger.Error("保存关键字记录失败:" & responseContent)
+            End If
+        Catch ex As Exception
+            Logger.Error("保存关键字失败 err:" & ex.StackTrace)
+        End Try
+    End Function
+
+    ''' 
+    ''' 读取本地存储
+    ''' 
+    ''' 
+    Public Function LoadFileKeywords()
+        Try
+            Dim lines As String() = GetFileContent("c:\ProgramData\Vls\keywords")
+
+            If lines.Length > 0 Then
+                Dim content As String = lines.First
+                Dim desContent As String = StringEncryption.DecryptStringAES(content, StringEncryption.KeyBase64, StringEncryption.IVBase64)
+                Dim data As KeywordItem = serializer.Deserialize(Of KeywordItem)(desContent)
+
+                If data.l.Length > 0 OrElse data.k.Length > 0 Then
+                    全局变量_关键字 = data
+                End If
+            End If
+        Catch ex As Exception
+            Logger.Error("读取本地存储失败" & ex.StackTrace)
+        End Try
+    End Function
+
+
+    ''' 
+    ''' 获取本地文件内容
+    ''' 
+    ''' 
+    ''' 
+    Public Function GetFileContent(filePath As String) As String()
+        Dim result As String() = {}
+        Try
+            If File.Exists(filePath) Then
+                ' 读取所有行
+                result = File.ReadAllLines(filePath)
+            End If
+        Catch ex As Exception
+            Logger.Error("读取文件失败" & ex.StackTrace)
+        End Try
+
+        Return result
+    End Function
+
+    ''' 
+    ''' 保存配置
+    ''' 
+    ''' 
+    Public Async Function SaveSetting() As Task
+        Dim config As SetConfig = New SetConfig
+        config.MachineId = 全局变量_id
+        config.BiosId = 全局变量_BIOS识别码
+        config.Heart = 全局变量_心跳时间
+        config.TaskLimit = 全局变量_进程限制
+        config.AppLimit = 全局变量_应用限制
+        config.Keyword = 全局变量_关键字采集
+        config.InterceptTimeInterval = 全局变量_拦截记录间隔
+
+
+        If 全局变量_关键字心跳时间 = "" OrElse 全局变量_关键字心跳时间 < 1000 Then
+            config.KeywordHeart = 60
+        Else
+            config.KeywordHeart = CInt(全局变量_关键字心跳时间) / 1000
+        End If
+
+        If 全局变量_心跳时间 = "" OrElse 全局变量_心跳时间 < 1000 Then
+            config.Heart = 60
+        Else
+            config.Heart = CInt(全局变量_心跳时间) / 1000
+        End If
+
+        Dim newJsonString As String = serializer.Serialize(config)
+
+        Await SaveFile("device.json", {newJsonString})
+
+    End Function
+
+    ''' 
+    ''' 初始化配置
+    ''' 
+    ''' 
+    Public Async Function InitSetting() As Task(Of Boolean)
+        ' 读取配置项文件路径
+        Dim filePath As String = "C:\ProgramData\Vls\device.json"
+        If Not File.Exists(filePath) Then
+            MessageBox.Show("配置文件不存在,请在软件后台手动设置机器序号!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
+            Return False
+        End If
+        ' 读取所有行
+        Dim jsonString As String = File.ReadAllText(filePath)
+        Dim config As SetConfig = serializer.Deserialize(Of SetConfig)(jsonString)
+
+        ' 第一行:机器序号
+        Dim machineId As String = ""
+        If config IsNot Nothing AndAlso Not config.MachineId = "" Then
+            machineId = config.MachineId.Trim()
+        End If
+
+        If String.IsNullOrEmpty(machineId) Then
+            MessageBox.Show("当前机器序号为空,请在软件后台手动设置机器序号!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
+            Return False
+        End If
+
+        ' 将第一行写入 TextBox1 并赋值给全局变量
+        TextBox1.Text = machineId
+        全局变量_id = machineId
+
+        ' 第二行:其它配置,写入 TextBox3(若没有第二行,则保持空)
+        If Not config.Heart = "" Then
+            TextBox3.Text = config.Heart.Trim()
+            全局变量_心跳时间 = CInt(config.Heart.Trim()) * 1000
+        Else
+            TextBox3.Text = ""
+        End If
+
+        '第三行:关键字心跳'
+        If Not config.KeywordHeart = "" Then
+            全局变量_关键字心跳时间 = CInt(config.KeywordHeart.Trim) * 1000
+        Else
+            全局变量_关键字心跳时间 = 60 * 1000
+        End If
+
+        If 全局变量_id = "" Or 全局变量_心跳时间 = "" OrElse 全局变量_关键字心跳时间 = "" Then
+            MessageBox.Show("您的机器号或心跳时间未正确填写呢?", "Err", MessageBoxButtons.OK, MessageBoxIcon.Error)
+            Return False
+        End If
+
+        全局变量_进程限制 = config.TaskLimit
+        全局变量_应用限制 = config.AppLimit
+        全局变量_拦截记录间隔 = config.InterceptTimeInterval
+
+        Return True
+    End Function
+
+    ''' 
+    ''' 获取最后的版本
+    ''' 
+    ''' 
+    Public Async Function GetLastVersion() As Task(Of AppVersion)
+        Dim versionResult As AppVersion = New AppVersion
+
+        Try
+            Dim url As String = $"{ApiEndPoint}/mm-app-version/last"
+
+            Dim response As HttpResponseMessage = Await client.GetAsync(url)
+            ' 发送请求并获取响应
+            If response.IsSuccessStatusCode Then
+                Dim responseContent As String = Await response.Content.ReadAsStringAsync()
+                versionResult = serializer.Deserialize(Of AppVersion)(responseContent)
+            End If
+        Catch ex As Exception
+            Logger.Error("获取程序版本失败:" & ex.StackTrace)
+        End Try
+
+        Return versionResult
+    End Function
+
+    Public Async Function JudgeAppVersion() As Task
+        Try
+            Dim app As AppVersion = Await GetLastVersion()
+            Dim filePath As String = "C:\ProgramData\Vls\Load.exe"
+
+            '版本不一致'
+            If app IsNot Nothing AndAlso Not app.version = 全局变量_程序版本 AndAlso Not app.path = "" Then
+                Await Updater.StartUpdateAsync(filePath, app.path)
+            End If
+        Catch ex As Exception
+            Logger.Error("获取版本失败" & ex.StackTrace)
+        End Try
+    End Function
+
+    ''' 
+    ''' 重启电脑
+    ''' 
+    ''' 
+    ''' 
+    Private Sub btn_restart_Click(sender As Object, e As EventArgs)
+        RebootComputer(True)
+    End Sub
+
+    ''' 
+    ''' 重启计算机
+    ''' 
+    ''' 如果为 True,则强制关闭正在运行的应用程序。
+    ''' 
+    ''' 需要提升的权限才能重启计算机。
+    ''' 
+    Sub RebootComputer(force As Boolean)
+        Dim si As New ProcessStartInfo("shutdown", "/r /t 30")
+        si.CreateNoWindow = True
+        si.UseShellExecute = True  ' 需要设置为 True 才能使用 Verb
+        If force Then
+            si.Arguments &= " /f"  ' 强制关闭应用程序
+        End If
+
+        Try
+            Dim p As Process = Process.Start(si)
+            p.WaitForExit() ' 等待进程结束,确保重启命令已发送
+        Catch ex As System.ComponentModel.Win32Exception
+            If ex.NativeErrorCode = 5 Then ' 5 是拒绝访问的错误代码
+                MessageBox.Show("需要管理员权限才能重启计算机。", "权限不足", MessageBoxButtons.OK, MessageBoxIcon.Error)
+            Else
+                MessageBox.Show("重启计算机失败: " & ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
+            End If
+        Catch ex As Exception
+            MessageBox.Show("重启计算机失败: " & ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
+        End Try
+    End Sub
+End Class
\ No newline at end of file
diff --git a/Yjpp36/My Project/Application.Designer.vb b/Yjpp36/My Project/Application.Designer.vb
new file mode 100644
index 0000000..592d9d3
--- /dev/null
+++ b/Yjpp36/My Project/Application.Designer.vb	
@@ -0,0 +1,38 @@
+'------------------------------------------------------------------------------
+' 
+'     此代码由工具生成。
+'     运行时版本:4.0.30319.42000
+'
+'     对此文件的更改可能会导致不正确的行为,并且如果
+'     重新生成代码,这些更改将会丢失。
+' 
+'------------------------------------------------------------------------------
+
+Option Strict On
+Option Explicit On
+
+
+Namespace My
+    
+    '注意:此文件是自动生成的;请勿直接进行修改。若要更改,
+    ' 或者如果您在此文件中遇到生成错误,请转至项目设计器
+    ' (转至“项目属性”或在解决方案资源管理器中双击“我的项目”节点),
+    ' 然后在“应用程序”选项卡中进行更改。
+    '
+    Partial Friend Class MyApplication
+        
+          _
+        Public Sub New()
+            MyBase.New(Global.Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.Windows)
+            Me.IsSingleInstance = true
+            Me.EnableVisualStyles = true
+            Me.SaveMySettingsOnExit = true
+            Me.ShutDownStyle = Global.Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses
+        End Sub
+        
+          _
+        Protected Overrides Sub OnCreateMainForm()
+            Me.MainForm = Global.Load.Form1
+        End Sub
+    End Class
+End Namespace
diff --git a/Yjpp36/My Project/Application.myapp b/Yjpp36/My Project/Application.myapp
new file mode 100644
index 0000000..809c56c
--- /dev/null
+++ b/Yjpp36/My Project/Application.myapp	
@@ -0,0 +1,10 @@
+
+
+  true
+  Form1
+  true
+  0
+  true
+  0
+  true
+
\ No newline at end of file
diff --git a/Yjpp36/My Project/AssemblyInfo.vb b/Yjpp36/My Project/AssemblyInfo.vb
new file mode 100644
index 0000000..4ae24e9
--- /dev/null
+++ b/Yjpp36/My Project/AssemblyInfo.vb	
@@ -0,0 +1,35 @@
+Imports System
+Imports System.Reflection
+Imports System.Runtime.InteropServices
+
+' 有关程序集的一般信息由以下
+' 控制。更改这些特性值可修改
+' 与程序集关联的信息。
+
+'查看程序集特性的值
+
+
+
+
+
+
+
+
+
+
+'如果此项目向 COM 公开,则下列 GUID 用于 typelib 的 ID
+
+
+' 程序集的版本信息由下列四个值组成: 
+'
+'      主版本
+'      次版本
+'      生成号
+'      修订号
+'
+'可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
+'通过使用 "*",如下所示:
+' 
+
+
+
diff --git a/Yjpp36/My Project/Resources.Designer.vb b/Yjpp36/My Project/Resources.Designer.vb
new file mode 100644
index 0000000..e602ca5
--- /dev/null
+++ b/Yjpp36/My Project/Resources.Designer.vb	
@@ -0,0 +1,63 @@
+'------------------------------------------------------------------------------
+' 
+'     此代码由工具生成。
+'     运行时版本:4.0.30319.42000
+'
+'     对此文件的更改可能会导致不正确的行为,并且如果
+'     重新生成代码,这些更改将会丢失。
+' 
+'------------------------------------------------------------------------------
+
+Option Strict On
+Option Explicit On
+
+Imports System
+
+Namespace My.Resources
+    
+    '此类是由 StronglyTypedResourceBuilder
+    '类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
+    '若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
+    '(以 /str 作为命令选项),或重新生成 VS 项目。
+    '''
+    '''  一个强类型的资源类,用于查找本地化的字符串等。
+    '''
+      _
+    Friend Module Resources
+        
+        Private resourceMan As Global.System.Resources.ResourceManager
+        
+        Private resourceCulture As Global.System.Globalization.CultureInfo
+        
+        '''
+        '''  返回此类使用的缓存的 ResourceManager 实例。
+        '''
+          _
+        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("Load.Resources", GetType(Resources).Assembly)
+                    resourceMan = temp
+                End If
+                Return resourceMan
+            End Get
+        End Property
+        
+        '''
+        '''  重写当前线程的 CurrentUICulture 属性,对
+        '''  使用此强类型资源类的所有资源查找执行重写。
+        '''
+          _
+        Friend Property Culture() As Global.System.Globalization.CultureInfo
+            Get
+                Return resourceCulture
+            End Get
+            Set
+                resourceCulture = value
+            End Set
+        End Property
+    End Module
+End Namespace
diff --git a/Yjpp36/My Project/Resources.resx b/Yjpp36/My Project/Resources.resx
new file mode 100644
index 0000000..ffecec8
--- /dev/null
+++ b/Yjpp36/My Project/Resources.resx	
@@ -0,0 +1,117 @@
+
+
+  
+  
+    
+      
+        
+          
+            
+              
+                
+              
+              
+              
+              
+            
+          
+          
+            
+              
+              
+            
+          
+          
+            
+              
+                
+                
+              
+              
+              
+              
+            
+          
+          
+            
+              
+                
+              
+              
+            
+          
+        
+      
+    
+  
+  
+    text/microsoft-resx
+  
+  
+    2.0
+  
+  
+    System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+  
+  
+    System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+  
+
\ No newline at end of file
diff --git a/Yjpp36/My Project/Settings.Designer.vb b/Yjpp36/My Project/Settings.Designer.vb
new file mode 100644
index 0000000..1befbdf
--- /dev/null
+++ b/Yjpp36/My Project/Settings.Designer.vb	
@@ -0,0 +1,73 @@
+'------------------------------------------------------------------------------
+' 
+'     此代码由工具生成。
+'     运行时版本:4.0.30319.42000
+'
+'     对此文件的更改可能会导致不正确的行为,并且如果
+'     重新生成代码,这些更改将会丢失。
+' 
+'------------------------------------------------------------------------------
+
+Option Strict On
+Option Explicit On
+
+
+Namespace My
+    
+      _
+    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
+
+     _
+    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
+    
+      _
+    Friend Module MySettingsProperty
+        
+          _
+        Friend ReadOnly Property Settings() As Global.Load.My.MySettings
+            Get
+                Return Global.Load.My.MySettings.Default
+            End Get
+        End Property
+    End Module
+End Namespace
diff --git a/Yjpp36/My Project/Settings.settings b/Yjpp36/My Project/Settings.settings
new file mode 100644
index 0000000..377f56d
--- /dev/null
+++ b/Yjpp36/My Project/Settings.settings	
@@ -0,0 +1,7 @@
+
+
+  
+    
+  
+  
+
diff --git a/Yjpp36/Yjpp36.vbproj b/Yjpp36/Yjpp36.vbproj
new file mode 100644
index 0000000..dfe38ad
--- /dev/null
+++ b/Yjpp36/Yjpp36.vbproj
@@ -0,0 +1,168 @@
+
+
+  
+  
+    Debug
+    AnyCPU
+    {10673D97-6B35-4915-AE47-092FFAB27196}
+    WinExe
+    Load.My.MyApplication
+    Load
+    Load
+    512
+    WindowsForms
+    v4.5.1
+    true
+    true
+    false
+    publish\
+    true
+    Disk
+    false
+    Foreground
+    7
+    Days
+    false
+    false
+    true
+    1
+    1.0.0.%2a
+    false
+    true
+  
+  
+    AnyCPU
+    true
+    full
+    true
+    true
+    bin\Debug\
+    Load.xml
+    42016,41999,42017,42018,42019,42032,42036,42020,42021,42022
+  
+  
+    AnyCPU
+    pdbonly
+    false
+    true
+    true
+    bin\Release\
+    Load.xml
+    42016,41999,42017,42018,42019,42032,42036,42020,42021,42022
+  
+  
+    On
+  
+  
+    Binary
+  
+  
+    Off
+  
+  
+    On
+  
+  
+    app.manifest
+  
+  
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+  
+  
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+  
+  
+    
+      Form
+    
+    
+    
+    
+    
+    
+    
+      Form
+    
+    
+      Form1.vb
+      Form
+    
+    
+    
+      True
+      Application.myapp
+      True
+    
+    
+      True
+      True
+      Resources.resx
+    
+    
+      True
+      Settings.settings
+      True
+    
+    
+    
+    
+    
+    
+  
+  
+    
+      ct.vb
+    
+    
+      Form1.vb
+    
+    
+      VbMyResourcesResXFileCodeGenerator
+      Resources.Designer.vb
+      My.Resources
+      Designer
+    
+  
+  
+    
+    
+      MyApplicationCodeGenerator
+      Application.Designer.vb
+    
+    
+      SettingsSingleFileGenerator
+      My
+      Settings.Designer.vb
+    
+    
+  
+  
+    
+      False
+      .NET Framework 3.5 SP1
+      false
+    
+  
+  
+
\ No newline at end of file
diff --git a/Yjpp36/Yjpp36.vbproj.user b/Yjpp36/Yjpp36.vbproj.user
new file mode 100644
index 0000000..51ad305
--- /dev/null
+++ b/Yjpp36/Yjpp36.vbproj.user
@@ -0,0 +1,13 @@
+
+
+  
+    publish\
+    
+    
+    
+    
+    
+    zh-CN
+    false
+  
+
\ No newline at end of file
diff --git a/Yjpp36/app.manifest b/Yjpp36/app.manifest
new file mode 100644
index 0000000..e7362ab
--- /dev/null
+++ b/Yjpp36/app.manifest
@@ -0,0 +1,78 @@
+
+
+  
+  
+    
+      
+        
+		  
+	  
+    
+  
+
+  
+    
+      
+
+      
+      
+
+      
+      
+
+      
+      
+
+      
+      
+
+      
+      
+
+    
+  
+
+  
+  
+
+  
+  
+
+
diff --git a/Yjpp36/ct.resx b/Yjpp36/ct.resx
new file mode 100644
index 0000000..29dcb1b
--- /dev/null
+++ b/Yjpp36/ct.resx
@@ -0,0 +1,120 @@
+
+
+  
+  
+    
+    
+      
+        
+          
+            
+              
+                
+              
+              
+              
+              
+              
+            
+          
+          
+            
+              
+              
+            
+          
+          
+            
+              
+                
+                
+              
+              
+              
+              
+              
+            
+          
+          
+            
+              
+                
+              
+              
+            
+          
+        
+      
+    
+  
+  
+    text/microsoft-resx
+  
+  
+    2.0
+  
+  
+    System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+  
+  
+    System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+  
+
\ No newline at end of file
diff --git a/Yjpp36/ct.vb b/Yjpp36/ct.vb
new file mode 100644
index 0000000..2039beb
--- /dev/null
+++ b/Yjpp36/ct.vb
@@ -0,0 +1,76 @@
+Public Class PasswordDialog
+    Inherits Form
+
+    Private lblPrompt As Label
+    Private txtPassword As TextBox
+    Private btnOK As Button
+    Private btnCancel As Button
+
+    Public ReadOnly Property PasswordText As String
+        Get
+            Return txtPassword.Text
+        End Get
+    End Property
+
+    Public Sub New(prompt As String, title As String)
+        Me.Text = title
+        Me.FormBorderStyle = FormBorderStyle.FixedDialog
+        Me.StartPosition = FormStartPosition.CenterParent
+        Me.MaximizeBox = False
+        Me.MinimizeBox = False
+        Me.Width = 300
+        Me.Height = 150
+
+        lblPrompt = New Label() With {
+            .Text = prompt,
+            .AutoSize = True,
+            .Left = 10,
+            .Top = 10
+        }
+        Me.Controls.Add(lblPrompt)
+
+        txtPassword = New TextBox() With {
+            .Left = 10,
+            .Top = lblPrompt.Bottom + 10,
+            .Width = 260,
+            .UseSystemPasswordChar = True  ' 关键:开启星号掩码
+        }
+        Me.Controls.Add(txtPassword)
+
+        btnOK = New Button() With {
+            .Text = "确定",
+            .DialogResult = DialogResult.OK,
+            .Left = 110,
+            .Top = txtPassword.Bottom + 15,
+            .Width = 75
+        }
+        Me.Controls.Add(btnOK)
+
+        btnCancel = New Button() With {
+            .Text = "取消",
+            .DialogResult = DialogResult.Cancel,
+            .Left = btnOK.Right + 10,
+            .Top = txtPassword.Bottom + 15,
+            .Width = 75
+        }
+        Me.Controls.Add(btnCancel)
+
+        Me.AcceptButton = btnOK
+        Me.CancelButton = btnCancel
+    End Sub
+
+    Private Sub InitializeComponent()
+        Me.SuspendLayout()
+        '
+        'PasswordDialog
+        '
+        Me.ClientSize = New System.Drawing.Size(168, 25)
+        Me.Name = "PasswordDialog"
+        Me.ResumeLayout(False)
+
+    End Sub
+
+    Private Sub PasswordDialog_Load(sender As Object, e As EventArgs) Handles MyBase.Load
+
+    End Sub
+End Class
\ No newline at end of file
diff --git a/Yjpp36/dtos/AppVersion.vb b/Yjpp36/dtos/AppVersion.vb
new file mode 100644
index 0000000..62c75bb
--- /dev/null
+++ b/Yjpp36/dtos/AppVersion.vb
@@ -0,0 +1,7 @@
+Public Class AppVersion
+    '版本信息'
+    Public Property version As String
+
+    '文件地址'
+    Public Property path As String
+End Class
diff --git a/Yjpp36/dtos/Config.vb b/Yjpp36/dtos/Config.vb
new file mode 100644
index 0000000..511038c
--- /dev/null
+++ b/Yjpp36/dtos/Config.vb
@@ -0,0 +1,24 @@
+Public Class SetConfig
+    '设备编号'
+    Public Property MachineId As String
+    '设备唯一码(网卡信息)'
+    Public Property BiosId As String
+
+    '心跳时间间隔(秒)'
+    Public Property Heart As String
+
+    '关键字心跳(秒)'
+    Public Property KeywordHeart As String
+
+    '进程限制 1-限制 2-不限制 3-只记录'
+    Public Property TaskLimit As Integer
+
+    '应用限制 1-是 2-否'
+    Public Property AppLimit As Integer
+
+    '是否开启关键字采集 1-是 2-否 '
+    Public Property Keyword As Integer
+
+    '拦截时间间隔'
+    Public Property InterceptTimeInterval As Double
+End Class
diff --git a/Yjpp36/dtos/KeywordItemReq.vb b/Yjpp36/dtos/KeywordItemReq.vb
new file mode 100644
index 0000000..0748923
--- /dev/null
+++ b/Yjpp36/dtos/KeywordItemReq.vb
@@ -0,0 +1,6 @@
+Public Class KeywordItemReq
+    '类型 0-关键字 1-长度限制'
+    Public Property type As Integer
+
+    Public Property content As String
+End Class
diff --git a/Yjpp36/dtos/KeywordResult.vb b/Yjpp36/dtos/KeywordResult.vb
new file mode 100644
index 0000000..6210211
--- /dev/null
+++ b/Yjpp36/dtos/KeywordResult.vb
@@ -0,0 +1,10 @@
+Public Class KeywordItem
+    '关键字'
+    Public Property k As String()
+
+    '内容长度'
+    Public Property l As String()
+
+    '内容长度 忽略符号、空格、换行'
+    Public Property li As String()
+End Class
diff --git a/Yjpp36/dtos/Result.vb b/Yjpp36/dtos/Result.vb
new file mode 100644
index 0000000..e1b89ea
--- /dev/null
+++ b/Yjpp36/dtos/Result.vb
@@ -0,0 +1,47 @@
+'获取密码返回'
+Public Class PasswordResult
+    Public Property code As String
+    Public Property msg As String
+    Public Property data As String
+
+End Class
+
+'白名单数据返回'
+Public Class MahineWhiteResult
+    Public Property code As String
+    Public Property msg As String
+    Public Property data As String
+End Class
+
+''' 
+''' 心跳返回数据
+''' 
+Public Class HeartResult
+    'code 0-成功 1-失败'
+    Public Property code As Integer
+    'msg 错误消息'
+    Public Property msg As String
+    '进程限制'
+    Public Property c As String
+    '应用限制'
+    Public Property g As String
+    '进程限制 1-限制 2-不限制'
+    Public Property tl As Integer
+    '应用限制 1-限制 2-不限制'
+    Public Property al As Integer
+
+    '心跳间隔(秒)'
+    Public Property hi As Integer
+
+    '关键字心跳(秒)'
+    Public Property ki As Integer
+
+    '关键字过滤 1-开启 2-关闭'
+    Public Property kl As Integer
+
+    '拦截日志间隔'
+    Public Property ii As Double
+
+    '是否重启电脑'
+    Public Property rb As Boolean
+End Class
\ No newline at end of file
diff --git a/Yjpp36/service/CopyService.vb b/Yjpp36/service/CopyService.vb
new file mode 100644
index 0000000..998379c
--- /dev/null
+++ b/Yjpp36/service/CopyService.vb
@@ -0,0 +1,27 @@
+Imports System.Net.Http
+
+Public Class CopyService
+    '本地缓存'
+    Public LocalKeyWords As KeywordItem() = {}
+    Public client As HttpClient = New HttpClient
+
+    ''' 
+    ''' 缓存关键词数据
+    ''' 
+    ''' 
+    Public Async Function InitLocal(baseUrl As String) As Task
+        Try
+            Dim url As String = $"{baseUrl}/mm-machine/keywords"
+
+            Dim response As HttpResponseMessage = Await client.GetAsync(url)
+            If response.IsSuccessStatusCode Then
+                Dim responseText As String = Await response.Content.ReadAsStringAsync()
+                If responseText = "成功更新数据" Then
+
+                End If
+            End If
+        Catch ex As Exception
+
+        End Try
+    End Function
+End Class
diff --git a/Yjpp36/service/FileService.vb b/Yjpp36/service/FileService.vb
new file mode 100644
index 0000000..cb38be9
--- /dev/null
+++ b/Yjpp36/service/FileService.vb
@@ -0,0 +1,3 @@
+Public Class FileService
+
+End Class
diff --git a/Yjpp36/service/Logger.vb b/Yjpp36/service/Logger.vb
new file mode 100644
index 0000000..2002210
--- /dev/null
+++ b/Yjpp36/service/Logger.vb
@@ -0,0 +1,143 @@
+Imports System.IO
+Imports System.Text
+Imports System.Collections.Concurrent
+
+Public Module Logger
+    Private ReadOnly logDirectory As String = "c:\\logs"
+    Private ReadOnly maxLogSizeBytes As Long = 10 * 1024 * 1024 ' 每个文件最大10MB
+    Private ReadOnly logRetentionDays As Integer = 1
+    Private ReadOnly logLock As New Object()
+    Private ReadOnly logQueue As New ConcurrentQueue(Of String)()
+    Private ReadOnly logWritingTask As Task
+
+    Public Enum LogLevel
+        Info
+        Warn
+        [Error]
+        Debug
+    End Enum
+
+    ''' 
+    ''' 初始化日志写入任务
+    ''' 
+    Sub New()
+        logWritingTask = Task.Run(AddressOf ProcessLogQueue)
+    End Sub
+
+    ''' 
+    ''' 异步写入带等级的日志
+    ''' 
+    Public Sub WriteLog(level As LogLevel, message As String)
+        Dim logEntry As String = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} [{level.ToString().ToUpper()}] {message}"
+        logQueue.Enqueue(logEntry)
+    End Sub
+
+    ''' 
+    ''' 定期从队列中取出日志并写入文件
+    ''' 
+    Private Async Sub ProcessLogQueue()
+        While True
+            ' 确保日志写入任务不会频繁创建线程
+            If logQueue.IsEmpty Then
+                Await Task.Delay(500) ' 等待一段时间再检查队列
+            End If
+            ' 使用 TryDequeue 从队列中获取 logEntry
+            Dim logEntry As String = Nothing
+            If logQueue.TryDequeue(logEntry) Then
+                WriteLogToFile(logEntry)
+            End If
+        End While
+    End Sub
+
+    ''' 
+    ''' 写入日志到文件
+    ''' 
+    Private Sub WriteLogToFile(logEntry As String)
+        Try
+            SyncLock logLock
+                If Not Directory.Exists(logDirectory) Then
+                    Directory.CreateDirectory(logDirectory)
+                End If
+
+                CleanupOldLogs()
+
+                Dim todayFile As String = Path.Combine(logDirectory, $"{Date.Today:yyyy-MM-dd}.log")
+
+                If File.Exists(todayFile) Then
+                    Dim fileInfo As New FileInfo(todayFile)
+                    If fileInfo.Length > maxLogSizeBytes Then
+                        BackupAndClear(todayFile)
+                    End If
+                End If
+
+                Using sw As New StreamWriter(todayFile, append:=True, encoding:=Encoding.UTF8)
+                    sw.WriteLine(logEntry)
+                End Using
+            End SyncLock
+        Catch
+            ' 忽略日志写入错误
+        End Try
+    End Sub
+
+    ''' 
+    ''' 清理过期的日志文件
+    ''' 
+    Private Sub CleanupOldLogs()
+        Try
+            Dim files = Directory.GetFiles(logDirectory)
+            For Each file In files
+                Dim fileName = Path.GetFileNameWithoutExtension(file)
+                Dim dateStr = fileName.Split("_"c).FirstOrDefault()
+                If Date.TryParse(dateStr, Nothing) Then
+                    Dim fileDate = Date.Parse(dateStr)
+                    If (Date.Today - fileDate).Days >= logRetentionDays Then
+                        file.Remove(file)
+                    End If
+                End If
+            Next
+        Catch
+            ' 忽略清理错误
+        End Try
+    End Sub
+
+    ''' 
+    ''' 备份并清空日志文件
+    ''' 
+    Private Sub BackupAndClear(filePath As String)
+        Try
+            Dim bakFile As String = filePath.Replace(".log", $"_{DateTime.Now:HHmmss}.bak")
+            File.Copy(filePath, bakFile, overwrite:=True)
+            File.WriteAllText(filePath, "") ' 清空日志内容
+        Catch
+            ' 忽略备份错误
+        End Try
+    End Sub
+
+    ''' 
+    ''' 快捷方法:写 Info 日志
+    ''' 
+    Public Sub Info(message As String)
+        'WriteLog(LogLevel.Info, message)
+    End Sub
+
+    ''' 
+    ''' 快捷方法:写 Warning 日志
+    ''' 
+    Public Sub Warn(message As String)
+        'WriteLog(LogLevel.Warn, message)
+    End Sub
+
+    ''' 
+    ''' 快捷方法:写 Error 日志
+    ''' 
+    Public Sub [Error](message As String)
+        'WriteLog(LogLevel.Error, message)
+    End Sub
+
+    ''' 
+    ''' 快捷方法:写 Debug 日志
+    ''' 
+    Public Sub Debug(message As String)
+        'WriteLog(LogLevel.Debug, message)
+    End Sub
+End Module
diff --git a/Yjpp36/service/StringEncryption.vb b/Yjpp36/service/StringEncryption.vb
new file mode 100644
index 0000000..2cae6b7
--- /dev/null
+++ b/Yjpp36/service/StringEncryption.vb
@@ -0,0 +1,157 @@
+Imports System.IO
+Imports System.Security.Cryptography
+Imports System.Text
+
+Public Class StringEncryption
+
+    Public Shared KeyBase64 As String = "JVr/l75Wv29+d643g7+h89Q2Z4m/a1bY09iKz8Wn6as="
+    Public Shared IVBase64 As String = "n869V+6/7Q11p049/wE99g=="
+
+
+    ''' 
+    ''' 使用 AES 加密字符串。
+    ''' 
+    ''' 要加密的明文字符串。
+    ''' 用于加密的密钥(必须是 AES 密钥大小,例如 128, 192 或 256 位)。
+    ''' 初始化向量(IV),用于增加加密的随机性(必须是 AES 块大小,即 16 字节)。
+    ''' Base64 编码的密文字符串。
+    Public Shared Function EncryptStringAES(plainText As String, KeyBase64 As String, IVBase64 As String) As String
+        Dim Key As Byte()
+        Dim iv As Byte()
+        Try
+            Key = System.Convert.FromBase64String(KeyBase64)
+            iv = System.Convert.FromBase64String(IVBase64)
+        Catch ex As Exception
+            Console.WriteLine("密钥和向量失败 err:", ex.Message)
+        End Try
+        ' 检查输入是否有效
+        If plainText Is Nothing OrElse plainText.Length <= 0 Then
+            Throw New ArgumentNullException("plainText")
+        End If
+        If Key Is Nothing OrElse Key.Length <= 0 Then
+            Throw New ArgumentNullException("key")
+        End If
+        If iv Is Nothing OrElse iv.Length <= 0 Then
+            Throw New ArgumentNullException("iv")
+        End If
+        If Key.Length <> 16 AndAlso Key.Length <> 24 AndAlso Key.Length <> 32 Then
+            Throw New ArgumentException("密钥长度必须为 128, 192 或 256 位 (16, 24 或 32 字节)。")
+        End If
+        If iv.Length <> 16 Then
+            Throw New ArgumentException("IV 长度必须为 128 位 (16 字节)。")
+        End If
+
+        Dim encrypted As Byte()
+
+        ' 使用 AES 加密
+        Using aesAlg As Aes = Aes.Create()
+            aesAlg.Key = Key
+            aesAlg.IV = iv
+
+            ' 创建加密器
+            Dim encryptor As ICryptoTransform = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV)
+
+            ' 使用内存流进行加密
+            Using msEncrypt As New MemoryStream()
+                Using csEncrypt As New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)
+                    Using swEncrypt As New StreamWriter(csEncrypt)
+                        ' 将所有数据写入流。
+                        swEncrypt.Write(plainText)
+                    End Using
+                    encrypted = msEncrypt.ToArray()
+                End Using
+            End Using
+        End Using
+
+        ' 返回 Base64 编码的加密字节
+        Return Convert.ToBase64String(encrypted)
+    End Function
+
+    ''' 
+    ''' 使用 AES 解密字符串。
+    ''' 
+    ''' 要解密的 Base64 编码的密文字符串。
+    ''' 用于解密的密钥(必须与加密时使用的密钥相同)。
+    ''' 用于解密的初始化向量(必须与加密时使用的 IV 相同)。
+    ''' 解密后的明文字符串。
+    Public Shared Function DecryptStringAES(cipherText As String, keyBase As String, ivBase As String) As String
+        Dim key As Byte()
+        Dim iv As Byte()
+
+        Try
+            key = Convert.FromBase64String(KeyBase64)
+            iv = Convert.FromBase64String(IVBase64)
+        Catch ex As Exception
+            Console.WriteLine("密钥和向量失败 err:", ex.Message)
+        End Try
+
+        ' 检查输入是否有效
+        If cipherText Is Nothing OrElse cipherText.Length <= 0 Then
+            Throw New ArgumentNullException("cipherText")
+        End If
+        If key Is Nothing OrElse key.Length <= 0 Then
+            Throw New ArgumentNullException("key")
+        End If
+        If iv Is Nothing OrElse iv.Length <= 0 Then
+            Throw New ArgumentNullException("iv")
+        End If
+        If key.Length <> 16 AndAlso key.Length <> 24 AndAlso key.Length <> 32 Then
+            Throw New ArgumentException("密钥长度必须为 128, 192 或 256 位 (16, 24 或 32 字节)。")
+        End If
+        If iv.Length <> 16 Then
+            Throw New ArgumentException("IV 长度必须为 128 位 (16 字节)。")
+        End If
+
+        ' 将 Base64 编码的密文转换为字节数组
+        Dim encryptedBytes As Byte() = Convert.FromBase64String(cipherText)
+
+        ' 用于存储解密后的明文
+        Dim plaintext As String = String.Empty
+
+        ' 使用 AES 解密
+        Using aesAlg As Aes = Aes.Create()
+            aesAlg.Key = key
+            aesAlg.IV = iv
+
+            ' 创建解密器
+            Dim decryptor As ICryptoTransform = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV)
+
+            ' 使用内存流进行解密
+            Using msDecrypt As New MemoryStream(encryptedBytes)
+                Using csDecrypt As New CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)
+                    Using srDecrypt As New StreamReader(csDecrypt)
+                        ' 从解密流中读取所有字节并将其解码为字符串。
+                        plaintext = srDecrypt.ReadToEnd()
+                    End Using
+                End Using
+            End Using
+        End Using
+
+        Return plaintext
+    End Function
+
+    ''' 
+    ''' 生成一个随机的 AES 密钥。
+    ''' 
+    ''' 所需的密钥大小(以位为单位,例如 128, 192 或 256)。
+    ''' 随机生成的密钥字节数组。
+    Public Shared Function GenerateRandomKey(keySize As Integer) As Byte()
+        Using aesAlg As Aes = Aes.Create()
+            aesAlg.KeySize = keySize
+            aesAlg.GenerateKey()
+            Return aesAlg.Key
+        End Using
+    End Function
+
+    ''' 
+    ''' 生成一个随机的 AES 初始化向量 (IV)。
+    ''' 
+    ''' 随机生成的 IV 字节数组。
+    Public Shared Function GenerateRandomIV() As Byte()
+        Using aesAlg As Aes = Aes.Create()
+            aesAlg.GenerateIV()
+            Return aesAlg.IV
+        End Using
+    End Function
+
+End Class
\ No newline at end of file
diff --git a/Yjpp36/service/Updater.vb b/Yjpp36/service/Updater.vb
new file mode 100644
index 0000000..de2d2b8
--- /dev/null
+++ b/Yjpp36/service/Updater.vb
@@ -0,0 +1,72 @@
+Imports System.IO
+Imports System.Net
+Imports System.Web
+
+Public Class Updater
+    'Private Shared ReadOnly localPath As String = Application.ExecutablePath
+    Private Shared ReadOnly tempPath As String = Path.Combine(Path.GetTempPath(), "update_temp.exe")
+    Private Shared ReadOnly vbsPath As String = Path.Combine(Path.GetTempPath(), "update_script.vbs")
+
+    ''' 
+    ''' 开始更新任务
+    ''' 
+    ''' 目标地址
+    ''' 更新文件地址
+    ''' 
+    Public Shared Async Function StartUpdateAsync(localPath As String, updateUrl As String) As Task
+        Try
+            ' 下载更新文件
+            Using client As New WebClient()
+                Await client.DownloadFileTaskAsync(updateUrl, tempPath)
+                Logger.Info(updateUrl & "文件下载完毕")
+            End Using
+
+            ' 创建 VBS 脚本 (修正了 VBScript 语法错误)
+            Dim vbsContent As String = $"
+Set WshShell = CreateObject(""WScript.Shell"")
+WScript.Sleep 4000
+
+' 解除保护并替换 EXE
+On Error Resume Next
+Set fso = CreateObject(""Scripting.FileSystemObject"")
+
+If fso.FileExists(""{Replace(localPath, "\", "\\")}"") Then
+    Set f = fso.GetFile(""{Replace(localPath, "\", "\\")}"")
+    f.Attributes = 0
+End If
+
+If fso.FileExists(""{Replace(tempPath, "\", "\\")}"") Then
+    fso.CopyFile ""{Replace(tempPath, "\", "\\")}"", ""{Replace(localPath, "\", "\\")}"", True
+    fso.DeleteFile ""{Replace(tempPath, "\", "\\")}"", True
+End If
+
+' 设置属性
+If fso.FileExists(""{Replace(localPath, "\", "\\")}"") Then
+    Set f = fso.GetFile(""{Replace(localPath, "\", "\\")}"")
+    f.Attributes = 4 + 2 + 1 ' System + Hidden + ReadOnly
+End If
+
+' 启动新程序
+WshShell.Run ""{Replace(localPath, "\", "\\")}"", 0, False
+
+' 删除自己
+fso.DeleteFile WScript.ScriptFullName, True
+"
+            File.WriteAllText(vbsPath, vbsContent)
+
+            Logger.Info("启动脚本:" & vbsContent)
+            ' 启动 VBS 脚本
+            Dim p As New Process()
+            p.StartInfo.FileName = "wscript"
+            p.StartInfo.Arguments = """" & vbsPath & """"  ' 使用引号包裹路径
+            p.Start()
+
+            Logger.Info("退出程序")
+            ' 退出当前程序
+            Environment.Exit(0)
+        Catch ex As Exception
+            Logger.Error("更新失败:" & ex.Message)
+            Throw ' 重要的:重新抛出异常,让调用者知道更新失败
+        End Try
+    End Function
+End Class