From 12acdf14fcddae8d16e00b7b981559da67ce60ea Mon Sep 17 00:00:00 2001
From: Chr <haoran.cheng@skonda.com.cn>
Date: 星期五, 23 八月 2024 08:53:20 +0800
Subject: [PATCH] 完善消息通知程序;

---
 PdmAlert/Settings/UpdaterSetting.xml          |    0 
 PdmAlert/PdmAlert.iss                         |   62 ++
 PdmAlert/log4net.config                       |   35 +
 PdmAlert/Encryptor.cs                         |    3 
 PdmAlert/ReleaseSettings/UpdaterSetting.xml   |    0 
 PdmAlert/Settings/ToolSetting.xml             |    0 
 PdmAlert/PdmAlert.csproj                      |   47 ++
 PdmAlert/lib/log4net.dll                      |    0 
 PdmAlert/Properties/AssemblyInfo.cs           |    4 
 PdmAlert/lib/websocket-sharp.dll              |    0 
 PdmAlert/.vs/PdmAlert/v17/DocumentLayout.json |  248 ++++++----
 PdmAlert/LoginWindow.xaml.cs                  |   44 +
 PdmAlert/DockApp.cs                           |   35 +
 PdmAlert/Entity/MsgData.cs                    |    8 
 PdmAlert/MainWindow.xaml.cs                   |  328 ++++++++++++--
 PdmAlert/LoginWindow.xaml                     |    7 
 PdmAlert/ToolSetting.cs                       |   88 +++
 PdmAlert/Util.cs                              |  179 +++++++
 PdmAlert/Icon.ico                             |    0 
 PdmAlert/App.xaml.cs                          |  119 ++++
 PdmAlert/MainWindow.xaml                      |  119 +++-
 /dev/null                                     |    0 
 PdmAlert/lib/Fleck.dll                        |    0 
 PdmAlert/LoginUser.cs                         |   18 
 PdmAlert/ReleaseSettings/ToolSetting.xml      |    0 
 25 files changed, 1,120 insertions(+), 224 deletions(-)

diff --git a/PdmAlert/.vs/PdmAlert/v17/DocumentLayout.json b/PdmAlert/.vs/PdmAlert/v17/DocumentLayout.json
index fb64986..fc4749f 100644
--- a/PdmAlert/.vs/PdmAlert/v17/DocumentLayout.json
+++ b/PdmAlert/.vs/PdmAlert/v17/DocumentLayout.json
@@ -3,44 +3,49 @@
   "WorkspaceRootPath": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\",
   "Documents": [
     {
-      "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|c:\\main\\workspace\\visualstudio\\pdmswplugin2\\pdmalert\\loginuser.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:loginuser.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+      "AbsoluteMoniker": "D:0:0:{00000000-0000-0000-0000-000000000000}|\u003CSolution\u003E|PdmAlert||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|"
     },
     {
-      "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\loginwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:loginwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+      "AbsoluteMoniker": "D:0:0:{EDC73C56-D0C5-4AC9-B296-3253915EF933}|..\\..\\CommonUpdater\\VersionControl\\VersionControl.csproj|c:\\main\\workspace\\visualstudio\\commonupdater\\versioncontrol\\util.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
-      "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\mainwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "AbsoluteMoniker": "D:0:0:{11C62041-5E6E-4230-A5E8-4246C033BA67}|..\\..\\CommonUpdater\\AutoUpdater\\AutoUpdater.csproj|c:\\main\\workspace\\visualstudio\\commonupdater\\autoupdater\\settings\\updatersetting.xml||{FA3CD31E-987B-443A-9B81-186104E8DAC1}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|c:\\main\\workspace\\visualstudio\\pdmswplugin2\\pdmalert\\settings\\updatersetting.xml||{FA3CD31E-987B-443A-9B81-186104E8DAC1}",
+      "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:settings\\updatersetting.xml||{FA3CD31E-987B-443A-9B81-186104E8DAC1}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{11C62041-5E6E-4230-A5E8-4246C033BA67}|..\\..\\CommonUpdater\\AutoUpdater\\AutoUpdater.csproj|c:\\main\\workspace\\visualstudio\\commonupdater\\autoupdater\\mainwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{11C62041-5E6E-4230-A5E8-4246C033BA67}|..\\..\\CommonUpdater\\AutoUpdater\\AutoUpdater.csproj|c:\\main\\workspace\\visualstudio\\commonupdater\\autoupdater\\util.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|c:\\main\\workspace\\visualstudio\\pdmswplugin2\\pdmalert\\mainwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
       "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:mainwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
-      "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\app.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|c:\\main\\workspace\\visualstudio\\pdmswplugin2\\pdmalert\\app.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
       "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:app.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{EDC73C56-D0C5-4AC9-B296-3253915EF933}|..\\..\\CommonUpdater\\VersionControl\\VersionControl.csproj|c:\\main\\workspace\\visualstudio\\commonupdater\\versioncontrol\\versionutil.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|c:\\main\\workspace\\visualstudio\\pdmswplugin2\\pdmalert\\loginwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:loginwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|c:\\main\\workspace\\visualstudio\\pdmswplugin2\\pdmalert\\mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}",
+      "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}"
     },
     {
       "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|c:\\main\\workspace\\visualstudio\\pdmswplugin2\\pdmalert\\loginwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}",
       "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:loginwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}"
     },
     {
-      "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\util.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:util.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}",
-      "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\entity\\msgdata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:entity\\msgdata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\dockapp.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:dockapp.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\encryptor.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:encryptor.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+      "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|c:\\main\\workspace\\visualstudio\\pdmswplugin2\\pdmalert\\||{B270807C-D8C6-49EB-8EBE-8E8D566637A1}|1e78f8db-6c07-4d61-a18f-7514010abd56"
     }
   ],
   "DocumentGroupContainers": [
@@ -50,130 +55,159 @@
       "DocumentGroups": [
         {
           "DockedWidth": 200,
-          "SelectedChildIndex": 7,
+          "SelectedChildIndex": 0,
           "Children": [
             {
               "$type": "Document",
+              "DocumentIndex": 0,
+              "Title": "PdmAlert",
+              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\PdmAlert.csproj",
+              "RelativeDocumentMoniker": "PdmAlert.csproj",
+              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\PdmAlert.csproj",
+              "RelativeToolTip": "PdmAlert.csproj",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001001|",
+              "WhenOpened": "2024-08-22T13:00:12.272Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 1,
+              "Title": "Util.cs",
+              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\VersionControl\\Util.cs",
+              "RelativeDocumentMoniker": "..\\..\\CommonUpdater\\VersionControl\\Util.cs",
+              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\VersionControl\\Util.cs",
+              "RelativeToolTip": "..\\..\\CommonUpdater\\VersionControl\\Util.cs",
+              "ViewState": "AQIAAIMBAAAAAAAAAAAgwKcBAAANAAAA",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2024-08-22T12:56:26.502Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 2,
+              "Title": "UpdaterSetting.xml",
+              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\AutoUpdater\\Settings\\UpdaterSetting.xml",
+              "RelativeDocumentMoniker": "..\\..\\CommonUpdater\\AutoUpdater\\Settings\\UpdaterSetting.xml",
+              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\AutoUpdater\\Settings\\UpdaterSetting.xml",
+              "RelativeToolTip": "..\\..\\CommonUpdater\\AutoUpdater\\Settings\\UpdaterSetting.xml",
+              "ViewState": "AQIAAAAAAAAAAAAAAAAAAA8AAAARAAAA",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003576|",
+              "WhenOpened": "2024-08-22T12:57:06.965Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 3,
+              "Title": "UpdaterSetting.xml",
+              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\Settings\\UpdaterSetting.xml",
+              "RelativeDocumentMoniker": "Settings\\UpdaterSetting.xml",
+              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\Settings\\UpdaterSetting.xml",
+              "RelativeToolTip": "Settings\\UpdaterSetting.xml",
+              "ViewState": "AQIAAAAAAAAAAAAAAAAAAAcAAAARAAAA",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003576|",
+              "WhenOpened": "2024-08-22T11:46:07.203Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
               "DocumentIndex": 4,
+              "Title": "MainWindow.xaml.cs",
+              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\AutoUpdater\\MainWindow.xaml.cs",
+              "RelativeDocumentMoniker": "..\\..\\CommonUpdater\\AutoUpdater\\MainWindow.xaml.cs",
+              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\AutoUpdater\\MainWindow.xaml.cs",
+              "RelativeToolTip": "..\\..\\CommonUpdater\\AutoUpdater\\MainWindow.xaml.cs",
+              "ViewState": "AQIAAKsAAAAAAAAAAAD4v7sAAAA8AAAA",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2024-08-22T11:42:13.882Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 11,
               "Title": "LoginWindow.xaml",
               "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\LoginWindow.xaml",
               "RelativeDocumentMoniker": "LoginWindow.xaml",
               "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\LoginWindow.xaml",
               "RelativeToolTip": "LoginWindow.xaml",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|",
-              "WhenOpened": "2024-08-20T10:32:06.895Z",
+              "WhenOpened": "2024-08-22T11:41:42.779Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 9,
+              "Title": "LoginWindow.xaml.cs",
+              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\LoginWindow.xaml.cs",
+              "RelativeDocumentMoniker": "LoginWindow.xaml.cs",
+              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\LoginWindow.xaml.cs",
+              "RelativeToolTip": "LoginWindow.xaml.cs",
+              "ViewState": "AQIAAAAAAAAAAAAAAAAAAAkAAAASAAAA",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2024-08-22T11:38:26.763Z",
               "EditorCaption": ""
             },
             {
               "$type": "Document",
               "DocumentIndex": 5,
               "Title": "Util.cs",
-              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\Util.cs",
-              "RelativeDocumentMoniker": "Util.cs",
-              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\Util.cs",
-              "RelativeToolTip": "Util.cs",
-              "ViewState": "AQIAAKgBAAAAAAAAAAAowLMBAAARAAAA",
+              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\AutoUpdater\\Util.cs",
+              "RelativeDocumentMoniker": "..\\..\\CommonUpdater\\AutoUpdater\\Util.cs",
+              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\AutoUpdater\\Util.cs",
+              "RelativeToolTip": "..\\..\\CommonUpdater\\AutoUpdater\\Util.cs",
+              "ViewState": "AQIAAGoAAAAAAAAAAAAkwKAAAAAFAAAA",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2024-08-20T10:17:23.879Z"
+              "WhenOpened": "2024-08-22T11:14:30.598Z",
+              "EditorCaption": ""
             },
             {
               "$type": "Document",
-              "DocumentIndex": 7,
-              "Title": "MsgData.cs",
-              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\Entity\\MsgData.cs",
-              "RelativeDocumentMoniker": "Entity\\MsgData.cs",
-              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\Entity\\MsgData.cs",
-              "RelativeToolTip": "Entity\\MsgData.cs",
-              "ViewState": "AQIAAAAAAAAAAAAAAAAAAAgAAAAAAAAA",
+              "DocumentIndex": 8,
+              "Title": "VersionUtil.cs",
+              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\VersionControl\\VersionUtil.cs",
+              "RelativeDocumentMoniker": "..\\..\\CommonUpdater\\VersionControl\\VersionUtil.cs",
+              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\VersionControl\\VersionUtil.cs",
+              "RelativeToolTip": "..\\..\\CommonUpdater\\VersionControl\\VersionUtil.cs",
+              "ViewState": "AQIAAGwAAAAAAAAAAAAAAAgAAAAjAAAA",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2024-08-20T09:14:07.015Z"
+              "WhenOpened": "2024-08-22T10:35:18.104Z",
+              "EditorCaption": ""
             },
             {
               "$type": "Document",
               "DocumentIndex": 6,
+              "Title": "MainWindow.xaml.cs",
+              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\MainWindow.xaml.cs",
+              "RelativeDocumentMoniker": "MainWindow.xaml.cs",
+              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\MainWindow.xaml.cs",
+              "RelativeToolTip": "MainWindow.xaml.cs",
+              "ViewState": "AQIAAMMAAAAAAAAAAAAnwNcAAAAJAAAA",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2024-08-22T10:31:21.777Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 10,
               "Title": "MainWindow.xaml",
               "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\MainWindow.xaml",
               "RelativeDocumentMoniker": "MainWindow.xaml",
               "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\MainWindow.xaml",
               "RelativeToolTip": "MainWindow.xaml",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|",
-              "WhenOpened": "2024-08-20T09:08:54.87Z",
+              "WhenOpened": "2024-08-22T10:31:19.726Z",
               "EditorCaption": ""
             },
             {
               "$type": "Document",
-              "DocumentIndex": 2,
-              "Title": "MainWindow.xaml.cs",
-              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\MainWindow.xaml.cs",
-              "RelativeDocumentMoniker": "MainWindow.xaml.cs",
-              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\MainWindow.xaml.cs",
-              "RelativeToolTip": "MainWindow.xaml.cs",
-              "ViewState": "AQIAAGIAAAAAAAAAAAAnwJEAAAAsAAAA",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2024-08-20T09:03:17.694Z",
-              "EditorCaption": ""
-            },
-            {
-              "$type": "Document",
-              "DocumentIndex": 8,
-              "Title": "DockApp.cs",
-              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\DockApp.cs",
-              "RelativeDocumentMoniker": "DockApp.cs",
-              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\DockApp.cs",
-              "RelativeToolTip": "DockApp.cs",
-              "ViewState": "AQIAABkAAAAAAAAAAAAkwA4AAAArAAAA",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2024-08-20T06:58:33.822Z"
-            },
-            {
-              "$type": "Document",
-              "DocumentIndex": 9,
-              "Title": "Encryptor.cs",
-              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\Encryptor.cs",
-              "RelativeDocumentMoniker": "Encryptor.cs",
-              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\Encryptor.cs",
-              "RelativeToolTip": "Encryptor.cs",
-              "ViewState": "AQIAACIAAAAAAAAAAAAawBIAAAAuAAAA",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2024-08-20T06:23:54.361Z"
-            },
-            {
-              "$type": "Document",
-              "DocumentIndex": 0,
-              "Title": "LoginUser.cs",
-              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\LoginUser.cs",
-              "RelativeDocumentMoniker": "LoginUser.cs",
-              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\LoginUser.cs",
-              "RelativeToolTip": "LoginUser.cs",
-              "ViewState": "AQIAAEYAAAAAAAAAAAAywFgAAAANAAAA",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2024-08-20T03:50:43.52Z",
-              "EditorCaption": ""
-            },
-            {
-              "$type": "Document",
-              "DocumentIndex": 1,
-              "Title": "LoginWindow.xaml.cs",
-              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\LoginWindow.xaml.cs",
-              "RelativeDocumentMoniker": "LoginWindow.xaml.cs",
-              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\LoginWindow.xaml.cs",
-              "RelativeToolTip": "LoginWindow.xaml.cs",
-              "ViewState": "AQIAAAYAAAAAAAAAAAAAABAAAAAfAAAA",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2024-08-20T03:46:25.163Z",
-              "EditorCaption": ""
-            },
-            {
-              "$type": "Document",
-              "DocumentIndex": 3,
+              "DocumentIndex": 7,
               "Title": "App.xaml.cs",
               "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\App.xaml.cs",
               "RelativeDocumentMoniker": "App.xaml.cs",
               "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\App.xaml.cs",
               "RelativeToolTip": "App.xaml.cs",
-              "ViewState": "AQIAAAgAAAAAAAAAAAAIwBgAAAAjAAAA",
+              "ViewState": "AQIAAGwAAAAAAAAAAAAywHIAAAANAAAA",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2024-08-20T03:42:24.667Z",
+              "WhenOpened": "2024-08-22T10:29:45.832Z",
               "EditorCaption": ""
             }
           ]
diff --git a/PdmAlert/App.xaml.cs b/PdmAlert/App.xaml.cs
index 9740dfb..dc28055 100644
--- a/PdmAlert/App.xaml.cs
+++ b/PdmAlert/App.xaml.cs
@@ -1,4 +1,11 @@
-锘縰sing System.Windows;
+锘縰sing CommonUpdater.VersionControl;
+using log4net;
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using System.Threading.Tasks;
+using System.Windows;
 
 namespace PdmAlert
 {
@@ -7,22 +14,104 @@
     /// </summary>
     public partial class App : Application
     {
+        public static readonly string AppId = "PdmMsgAlert";
+        public static readonly string Version = "0.0.0.1";
+
         DockApp dockApp;
         LoginWindow loginWindow;
+        private static System.Threading.Mutex mutex;
+
+        private static ILog Logger = LogManager.GetLogger("MsgAlert");
+
         protected override void OnStartup(StartupEventArgs e)
         {
-            base.OnStartup(e);
-            this.ShutdownMode = ShutdownMode.OnExplicitShutdown;
-            if (LoginUser.TryAutoLogin())
+            mutex = new System.Threading.Mutex(true, "MsgAlert_OnlyRunOne");
+            if (mutex.WaitOne(0, false))
             {
+                base.OnStartup(e);
+                this.ShutdownMode = ShutdownMode.OnLastWindowClose;
+                // 鍐欏叆鐗堟湰锛屽氨绠楀紓甯镐簡涔熶笉鎶ラ敊
+                try
+                {
+                    VersionUtil.SetPluginVersion(AppId, Version);
+                }
+                catch (Exception ex)
+                {
+                    Logger.Error("Write App Version Failed.", ex);
+                }
 
-                dockApp = new DockApp();
-                dockApp.Run();
+
+                Task.Run(() => CheckUpdate());
+
+
+                if (LoginUser.TryAutoLogin())
+                {
+                    InitDockApp();
+                }
+                else
+                {
+                    loginWindow = new LoginWindow();
+                    loginWindow.Show();
+                }
             }
             else
             {
-                loginWindow = new LoginWindow();
-                loginWindow.Show();
+                MessageBox.Show("璇峰嬁澶氭杩愯绋嬪簭锛�", "鎻愮ず");
+                this.Shutdown();
+            }
+        }
+
+        public void CheckUpdate()
+        {
+            try
+            {
+                VersionUtil.UpdateAutoUpdater(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
+            }
+            catch (Exception ex)
+            {
+                Logger.Error("Updater AutoUpdater.exe Failed!", ex);
+                Dispatcher.Invoke(() =>
+                {
+                    MessageBox.Show("鏇存柊绋嬪簭寮傚父", "閿欒", MessageBoxButton.OK, MessageBoxImage.Error);
+                });
+                // 鏇存柊绋嬪簭娌℃湁鏇存柊锛屽氨涓嶆鏌ユ洿鏂颁簡鍚�
+                return;
+            }
+
+            try
+            {
+                var update = VersionUtil.CheckSingleAppUpdate(AppId, Version);
+                if (update != null)
+                {
+                    Dispatcher.Invoke(() =>
+                    {
+                        var res = MessageBox.Show("妫�鏌ュ埌杞欢鏇存柊锛屾槸鍚︾幇鍦ㄦ洿鏂帮紵", "鎻愮ず", MessageBoxButton.YesNo, MessageBoxImage.Question);
+                        if (res == MessageBoxResult.Yes)
+                        {
+                            string updaterPath = "AutoUpdater\\AutoUpdater.exe";
+                            string exePath = new DirectoryInfo(Assembly.GetExecutingAssembly().Location).Parent.FullName;
+                            string exeFileName = $"{exePath}\\{updaterPath}";
+                            int mainProcessId = Process.GetCurrentProcess().Id;
+                            Process updaterProcess = new Process
+                            {
+                                StartInfo = new ProcessStartInfo
+                                {
+                                    FileName = exeFileName,
+                                    Arguments = $"{mainProcessId}"
+                                }
+                            };
+                            updaterProcess.Start();
+                        }
+                    });
+                }
+            }
+            catch (Exception ex)
+            {
+                Logger.Error($"Check Updater Failed.", ex);
+                Dispatcher.Invoke(() =>
+                {
+                    MessageBox.Show("妫�鏌ユ洿鏂板け璐ワ紒", "閿欒", MessageBoxButton.OK, MessageBoxImage.Error);
+                });
             }
         }
 
@@ -30,5 +119,19 @@
         {
 
         }
+
+        public void InitDockApp()
+        {
+            dockApp = new DockApp();
+            dockApp.Run();
+        }
+
+        public void SwithUser()
+        {
+            LoginUser.RemoveCacheBin();
+            LoginWindow loginWindow = new LoginWindow();
+            loginWindow.Show();
+            if (dockApp != null) dockApp.Stop();
+        }
     }
 }
diff --git a/PdmAlert/DockApp.cs b/PdmAlert/DockApp.cs
index 4e78dbc..12392d2 100644
--- a/PdmAlert/DockApp.cs
+++ b/PdmAlert/DockApp.cs
@@ -6,22 +6,22 @@
 {
     public class DockApp
     {
-        private Window showWindow;
+        private MainWindow showWindow;
         private NotifyIcon icon;
 
         public DockApp()
         {
             icon = new NotifyIcon();
             icon.BalloonTipText = "鍚姩涓�...";
-            icon.Text = "PDM娑堟伅閫氱煡绋嬪簭";
+            icon.Text = "娑堟伅閫氱煡绋嬪簭";
             icon.Icon = new System.Drawing.Icon("./Icon/Icon.ico");
             icon.Visible = true;
 
             MenuItem mainItem = new MenuItem("鏄剧ず涓荤晫闈�");
-            mainItem.Click += ExitItem_Click;
+            mainItem.Click += Icon_DoubleClick;
 
             MenuItem switchUserItem = new MenuItem("鍒囨崲鐢ㄦ埛");
-            switchUserItem.Click += ExitItem_Click;
+            switchUserItem.Click += SwitchUser_Click;
 
             MenuItem exitItem = new MenuItem("鍏抽棴");
             exitItem.Click += ExitItem_Click;
@@ -43,13 +43,9 @@
             else
             {
                 showWindow = new MainWindow();
+                showWindow.Closed += MainWindow_Closed;
                 showWindow.Show();
             }
-        }
-
-        private void Icon_DoubleClick(object sender, EventArgs e)
-        {
-            RefreshWindow();
         }
 
         public void Run()
@@ -57,9 +53,23 @@
             RefreshWindow();
         }
 
-        private void MainWindow_Closed(object sender, EventArgs e)
+        public void Stop()
         {
+            if (showWindow != null) showWindow.DoDispose();
+            showWindow.Close();
             showWindow = null;
+            icon.Visible = false;
+            icon.Dispose();
+        }
+
+        private void Icon_DoubleClick(object sender, EventArgs e)
+        {
+            RefreshWindow();
+        }
+
+        private void SwitchUser_Click(object sender, EventArgs e)
+        {
+            ((App)System.Windows.Application.Current).SwithUser();
         }
 
         private void ExitItem_Click(object sender, EventArgs e)
@@ -72,5 +82,10 @@
             icon.Dispose();
             System.Windows.Application.Current.Shutdown(0);
         }
+
+        private void MainWindow_Closed(object sender, EventArgs e)
+        {
+            showWindow = null;
+        }
     }
 }
diff --git a/PdmAlert/Encryptor.cs b/PdmAlert/Encryptor.cs
index 88768ab..445f84c 100644
--- a/PdmAlert/Encryptor.cs
+++ b/PdmAlert/Encryptor.cs
@@ -5,6 +5,9 @@
 
 namespace PdmAlert
 {
+    /// <summary>
+    /// 瀛楃鍔犺В瀵�
+    /// </summary>
     public class Encryptor
     {
         private readonly byte[] key;
diff --git a/PdmAlert/Entity/MsgData.cs b/PdmAlert/Entity/MsgData.cs
index c428e94..b369d9a 100644
--- a/PdmAlert/Entity/MsgData.cs
+++ b/PdmAlert/Entity/MsgData.cs
@@ -2,7 +2,11 @@
 {
     public class MsgData
     {
-        public string title { get; set; }
-        public string content { get; set; }
+        public string id { get; set; }
+        public string anntId { get; set; }
+        public string titile { get; set; }
+        public string msgContent { get; set; }
+        public string sender { get; set; }
+        public string sendTime { get; set; } = "sdadadads";
     }
 }
diff --git a/PdmAlert/Icon.ico b/PdmAlert/Icon.ico
new file mode 100644
index 0000000..39f1d01
--- /dev/null
+++ b/PdmAlert/Icon.ico
Binary files differ
diff --git a/PdmAlert/LoginUser.cs b/PdmAlert/LoginUser.cs
index f397804..4e2b8bb 100644
--- a/PdmAlert/LoginUser.cs
+++ b/PdmAlert/LoginUser.cs
@@ -11,8 +11,8 @@
     {
         public static LoginUser CurrentUser { get; private set; }
 
-        private static readonly Encryptor encryptor = new Encryptor("12345678123456781234567812345678",
-            "1234567812345678");
+        private static readonly Encryptor encryptor = new Encryptor("aB3dE5fG7hI9jjK1lMnOpQrS2tUvWxYz",
+            "8Wq9RsT4vYx6ZuB1");
 
         public string id { get; set; }
         public string realName { get; set; }
@@ -38,17 +38,16 @@
                     RemoveCacheBin();
                     return false;
                 }
-
             }
             return false;
         }
 
         public static bool Login(string username, string password, bool rememberMe)
         {
-
+            ToolSetting setting = ToolSetting.Instance;
             using (HttpClient client = new HttpClient
             {
-                BaseAddress = new Uri("http://localhost:8888/pdm-web/"),
+                BaseAddress = new Uri($"http://{setting.Ip}:{setting.Port}/{setting.BaseUrl}/"),
             })
             {
                 try
@@ -59,7 +58,6 @@
                         password = password,
                         appId = "sockettool",
                         pluginVersion = "0.0.0.1"
-
                     }, "openApi/wpf/login");
                     CurrentUser = res.HandleResult();
                     CurrentUser.password = password;
@@ -74,12 +72,16 @@
                 catch (Exception ex)
                 {
                     RemoveCacheBin();
+                    throw ex;
                 }
             }
-            return false;
         }
 
-
+        /// <summary>
+        /// 鎶婃槑鏂囧瘑鐮佸姞瀵嗗悗浠ヤ簩杩涘埗瀛樺叆bin鏂囦欢涓�
+        /// TODO 浣跨敤鏈哄櫒鐮佸姞瀵�
+        /// </summary>
+        /// <param name="content"></param>
         public static void SaveStrToBin(string content)
         {
             string filePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().FullName), "bin");
diff --git a/PdmAlert/LoginWindow.xaml b/PdmAlert/LoginWindow.xaml
index d6f4081..09d2c78 100644
--- a/PdmAlert/LoginWindow.xaml
+++ b/PdmAlert/LoginWindow.xaml
@@ -4,15 +4,16 @@
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:local="clr-namespace:PdmAlert"
+        WindowStartupLocation="CenterScreen"
         mc:Ignorable="d"
-        Title="LoginWindow" Height="450" Width="800">
+        Title="{Binding windowTitle}" Height="250" Width="400">
     <AdornerDecorator>
         <Border x:Name="mainBorder">
             <Grid Height="200" VerticalAlignment="Top" Margin="20">
                 <Grid.RowDefinitions>
                     <RowDefinition Height="30"/>
                     <RowDefinition Height="30"/>
-                    <RowDefinition Height="30"/>
+                    <RowDefinition Height="Auto"/>
                     <RowDefinition Height="50"/>
                 </Grid.RowDefinitions>
 
@@ -24,7 +25,7 @@
                 <TextBox x:Name="usernameTextBlock" VerticalAlignment="Stretch" VerticalContentAlignment="Center" Grid.Row="0" Grid.Column="1"/>
                 <Label Content="瀵嗙爜" VerticalContentAlignment="Center" Grid.Row="1" Grid.Column="0"/>
                 <PasswordBox x:Name="passwordTextBlock" VerticalAlignment="Stretch" VerticalContentAlignment="Center" Grid.Row="1" Grid.Column="1"/>
-                <CheckBox Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" x:Name="rememberMeInput">鑷姩鐧诲綍</CheckBox>
+                <CheckBox Margin="0,10,0,5" VerticalContentAlignment="Center" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" x:Name="rememberMeInput">鑷姩鐧诲綍</CheckBox>
                 <Button Margin="0,10,0,0"  Click="Button_Click" Padding="5" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2">鐧诲綍</Button>
             </Grid>
         </Border>
diff --git a/PdmAlert/LoginWindow.xaml.cs b/PdmAlert/LoginWindow.xaml.cs
index 6db9861..0dde24c 100644
--- a/PdmAlert/LoginWindow.xaml.cs
+++ b/PdmAlert/LoginWindow.xaml.cs
@@ -1,4 +1,7 @@
-锘縰sing System.Windows;
+锘縰sing PdmAlert.Util;
+using System;
+using System.Threading.Tasks;
+using System.Windows;
 
 namespace PdmAlert
 {
@@ -9,16 +12,47 @@
     {
         public LoginWindow()
         {
+            _windowTitle = $"V{App.Version}";
+            DataContext = this;
             InitializeComponent();
         }
 
+        private string _windowTitle;
+
+        public string windowTitle
+        {
+            get => _windowTitle;
+        }
+
+
         public void Button_Click(object sender, RoutedEventArgs e)
         {
-            if (LoginUser.Login(usernameTextBlock.Text, passwordTextBlock.Password, rememberMeInput.IsChecked == true))
+            MaskAdorner.ShowMask(mainBorder);
+            string username = usernameTextBlock.Text;
+            string password = passwordTextBlock.Password;
+            bool rememberMe = rememberMeInput.IsChecked == true;
+            Task.Run(() =>
             {
-
-
-            }
+                try
+                {
+                    if (LoginUser.Login(username, password, rememberMe))
+                    {
+                        Dispatcher.Invoke(() =>
+                        {
+                            ((App)Application.Current).InitDockApp();
+                            this.Close();
+                        });
+                    }
+                }
+                catch (Exception ex)
+                {
+                    MessageBox.Show(ex.Message, "鐧诲綍寮傚父", MessageBoxButton.OK, MessageBoxImage.Error);
+                }
+                finally
+                {
+                    MaskAdorner.HideMask(mainBorder);
+                }
+            });
 
         }
     }
diff --git a/PdmAlert/MainWindow.xaml b/PdmAlert/MainWindow.xaml
index 3defeb9..ad6f032 100644
--- a/PdmAlert/MainWindow.xaml
+++ b/PdmAlert/MainWindow.xaml
@@ -39,7 +39,7 @@
                 <Setter Property="FontWeight" Value="SemiBold"/>
                 <Setter Property="Foreground" Value="Black"/>
                 <Setter Property="Width" Value="50"/>
-                <Setter Property="FontSize" Value="20"/>
+                <Setter Property="FontSize" Value="30"/>
                 <Setter Property="BorderThickness" Value="1"/>
                 <Setter Property="BorderBrush" Value="Transparent"/>
 
@@ -97,44 +97,103 @@
 
             </Style>
 
-            <Style x:Key="LinkButton" TargetType="Button">
-                <Setter Property="FontFamily" Value="{StaticResource iconfont}"/>
-                <Setter Property="Foreground" Value="{StaticResource ChildBorder}"/>
-
+            <Style x:Key="LinkButton" TargetType="{x:Type Button}" >
                 <Setter Property="Template">
                     <Setter.Value>
-                        <ControlTemplate TargetType="Button">
-                            <TextBlock Style="{x:Null}" x:Name="label" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
-                           Foreground="{TemplateBinding Foreground}"
-                                   Text="{TemplateBinding Content}"/>
+                        <ControlTemplate TargetType="{x:Type ButtonBase}">
+                            <ContentPresenter x:Name="buttonContent" TextBlock.FontSize="{TemplateBinding FontSize}" 
+                        TextBlock.FontFamily="{StaticResource iconfont}" 
+                        TextBlock.Foreground="{StaticResource ChildBorder}" 
+                        Margin="0,0,5,0"
+                        VerticalAlignment="Center" 
+                        HorizontalAlignment="Center"
+                        Content="{TemplateBinding Content}"/>
+                            <ControlTemplate.Triggers>
+                                <Trigger Property="IsMouseOver" Value="True">
+                                    <Setter TargetName="buttonContent" Property="TextBlock.Foreground" Value="Purple"/>
+                                    <Setter TargetName="buttonContent" Property="Cursor" Value="Hand"/>
+                                </Trigger>
+                            </ControlTemplate.Triggers>
                         </ControlTemplate>
                     </Setter.Value>
                 </Setter>
             </Style>
         </ResourceDictionary>
     </Window.Resources>
+    <Border BorderBrush="Black" BorderThickness="1">
+        <Grid>
+            <Grid.RowDefinitions>
+                <RowDefinition Height="Auto"/>
+                <RowDefinition Height="*"/>
+            </Grid.RowDefinitions>
+            <Border Grid.Row="0" Background="LightGray">
+                <DockPanel LastChildFill="True">
+                    <Button DockPanel.Dock="Right" Style="{StaticResource WindowCloseButton}" Click="Hide_Click" ToolTip="鏈�灏忓寲">&#xe67a;</Button>
+                    <Button DockPanel.Dock="Right" Style="{StaticResource WindowButton}" Click="SwitchUser_Click" ToolTip="鍒囨崲鐢ㄦ埛">&#xe6ed;</Button>
+                    <Button DockPanel.Dock="Right" Style="{StaticResource WindowButton}" Click="Refresh_Click" BorderBrush="Black" ToolTip="鍒锋柊">&#xe600;</Button>
+                    <Label Content="{Binding userInfo}" FontSize="20" VerticalContentAlignment="Center"/>
+                </DockPanel>
+            </Border>
 
+            <AdornerDecorator Grid.Row="1">
+                <Grid x:Name="mainContent" >
+                    <Grid.RowDefinitions>
+                        <RowDefinition Height="Auto"/>
+                        <RowDefinition Height="*"/>
+                        <RowDefinition Height="Auto"/>
+                    </Grid.RowDefinitions>
+                    <DockPanel Grid.Row="0" LastChildFill="True" HorizontalAlignment="Stretch" >
+                        <Button DockPanel.Dock="Right" Margin="0,0,20,0" FontSize="16" Style="{StaticResource LinkButton}" Click="ReadAll_Click">鍏ㄩ儴宸茶</Button>
+                        <Label DockPanel.Dock="Left" FontSize="16" Content="{Binding messageTitle}"/>
+                    </DockPanel>
 
-    <StackPanel>
-        <Border BorderThickness="0" Background="LightGray">
-            <StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
-                <Button Style="{StaticResource WindowButton}" Click="Refresh_Click" BorderBrush="Black" ToolTip="鍒锋柊">&#xe600;</Button>
-                <Button Style="{StaticResource WindowButton}" Click="SwitchUser_Click" ToolTip="鍒囨崲鐢ㄦ埛">&#xe6ed;</Button>
-                <Button Style="{StaticResource WindowCloseButton}" Click="Hide_Click" ToolTip="鏈�灏忓寲">&#xe67a;</Button>
-            </StackPanel>
-        </Border>
+                    <ListView BorderThickness="0,1,0,1" Grid.Row="1" ItemsSource="{Binding messages}">
+                        <ListView.ItemContainerStyle>
+                            <Style TargetType="{x:Type ListViewItem}">
+                                <Setter Property="Focusable" Value="False"/>
+                                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
+                            </Style>
+                        </ListView.ItemContainerStyle>
 
-
-        <Label Content="{Binding messageTitle}"/>
-
-        <ListView ItemsSource="{Binding messages}">
-            <ListView.ItemTemplate>
-                <DataTemplate>
-                    <Label Content="999"/>
-                </DataTemplate>
-            </ListView.ItemTemplate>
-        </ListView>
-
-    </StackPanel>
-
+                        <ListView.ItemTemplate>
+                            <DataTemplate>
+                                <DockPanel LastChildFill="True">
+                                    <Button DockPanel.Dock="Right" FontSize="16" Margin="0,0,15,0" 
+                                        DataContext="{Binding}"
+                                        Click="SingleRead_Click"
+                                        Style="{StaticResource LinkButton}">宸茶</Button>
+                                    <StackPanel DockPanel.Dock="Right">
+                                        <StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
+                                            <Label FontSize="18" FontWeight="Bold" Content="{Binding titile}"/>
+                                            <Label FontSize="18" FontWeight="Bold" Content="{Binding sendTime}"/>
+                                        </StackPanel>
+                                        <Label FontSize="16" Content="{Binding msgContent}"/>
+                                    </StackPanel>
+                                </DockPanel>
+                            </DataTemplate>
+                        </ListView.ItemTemplate>
+                    </ListView>
+                    <StatusBar Grid.Row="2" VerticalAlignment="Center">
+                        <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
+                            <Ellipse Width="12" Height="12"  VerticalAlignment="Center">
+                                <Ellipse.Style>
+                                    <Style TargetType="Ellipse">
+                                        <Style.Triggers>
+                                            <DataTrigger Binding="{Binding socketStatus}" Value="Error">
+                                                <Setter Property="Shape.Fill" Value="Red"/>
+                                            </DataTrigger>
+                                            <DataTrigger Binding="{Binding socketStatus}" Value="Success">
+                                                <Setter Property="Shape.Fill" Value="Green"/>
+                                            </DataTrigger>
+                                        </Style.Triggers>
+                                    </Style>
+                                </Ellipse.Style>
+                            </Ellipse>
+                            <Label FontSize="12" Content="{Binding statusMessage}"/>
+                        </StackPanel>
+                    </StatusBar>
+                </Grid>
+            </AdornerDecorator>
+        </Grid>
+    </Border>
 </Window>
diff --git a/PdmAlert/MainWindow.xaml.cs b/PdmAlert/MainWindow.xaml.cs
index 8d0f0e9..84f3b61 100644
--- a/PdmAlert/MainWindow.xaml.cs
+++ b/PdmAlert/MainWindow.xaml.cs
@@ -2,16 +2,19 @@
 using DevComponents.DotNetBar;
 using System.Windows;
 using System.Drawing;
-using System.Net.WebSockets;
 using System;
 using System.Threading.Tasks;
-using System.Text;
-using System.Diagnostics;
 using System.Timers;
 using System.Collections.ObjectModel;
 using System.ComponentModel;
 using System.Runtime.CompilerServices;
 using PdmAlert.Entity;
+using System.Threading;
+using System.Net.Http;
+using PdmAlert.Util;
+using log4net;
+using WebSocketSharp;
+using System.Windows.Controls;
 
 namespace PdmAlert
 {
@@ -38,10 +41,17 @@
         }
         #endregion
 
-        private ClientWebSocket socket;
+        private static ILog Logger = LogManager.GetLogger("MsgAlert");
+
+        // private ClientWebSocket socket;
+        private WebSocket socket;
         private Task readTask;
-        private Task writeTask;
         private System.Timers.Timer heartbeatTimer;
+        private CancellationTokenSource cancelTokenSource;
+        private CancellationToken cancelToken;
+        private ToolSetting setting;
+        private HttpClient client;
+        private volatile bool IsRefreshing = false;
 
         private string _messageTitle = "鍏辨湁 0 鏉℃湭璇绘秷鎭�";
 
@@ -50,6 +60,31 @@
             get => _messageTitle;
             set => RaiseAndSetIfChanged(ref _messageTitle, value);
         }
+
+        private string _statusMessage = "鍚姩涓�...";
+
+        public string statusMessage
+        {
+            get => _statusMessage;
+            set => RaiseAndSetIfChanged(ref _statusMessage, value);
+        }
+
+        private string _userInfo = "";
+
+        public string userInfo
+        {
+            get => _userInfo;
+            set => RaiseAndSetIfChanged(ref _userInfo, value);
+        }
+
+        private string _socketStatus = "";
+
+        public string socketStatus
+        {
+            get => _socketStatus;
+            set => RaiseAndSetIfChanged(ref _socketStatus, value);
+        }
+
 
         private ObservableCollection<MsgData> _messages;
 
@@ -61,19 +96,104 @@
 
         public MainWindow()
         {
+            cancelTokenSource = new CancellationTokenSource();
+            cancelToken = cancelTokenSource.Token;
+            setting = ToolSetting.Instance;
+            client = new HttpClient
+            {
+                BaseAddress = new Uri($"http://{setting.Ip}:{setting.Port}/{setting.BaseUrl}/"),
+                Timeout = TimeSpan.FromSeconds(setting.TimeOut),
+            };
+            client.DefaultRequestHeaders.Add("Client-Access-Token", LoginUser.CurrentUser.username);
+            userInfo = $"鐢ㄦ埛:{LoginUser.CurrentUser.realName}";
+            DataContext = this;
             InitializeComponent();
+        }
+
+        private void ShowStatus(string status, string message)
+        {
+            Dispatcher.Invoke(() =>
+            {
+                socketStatus = status;
+                statusMessage = message;
+            });
         }
 
         private void Refresh_Click(object sender, RoutedEventArgs e)
         {
+            MaskAdorner.ShowMask(mainContent);
+            Task.Run(() =>
+            {
+                try
+                {
+                    RefreshData();
+                }
+                catch (Exception ex)
+                {
+                    Logger.Error("Request Unread Message Failed.", ex);
+                }
+                finally
+                {
+                    MaskAdorner.HideMask(mainContent);
+                }
+            });
+        }
 
+        public void RefreshData()
+        {
+            try
+            {
+                IsRefreshing = true;
+                Result<Page<MsgData>> res = client.GetSyncAction<Page<MsgData>>("pdm/annountCement/listSysMsgByUser", new Page<object>
+                {
+                    pageNo = 1,
+                    pageSize = 100
+                });
+                Page<MsgData> pageList = res.HandleResult();
+                Dispatcher.Invoke(() =>
+                {
+                    messageTitle = $"鍏辨湁 {pageList.total} 鏉℃湭璇绘秷鎭�";
+                    this.messages = new ObservableCollection<MsgData>(pageList.records);
+                });
+            }
+            finally
+            {
+                IsRefreshing = false;
+            }
+        }
 
+        private void FirstRefreshMsg()
+        {
+            try
+            {
+                Result<Page<MsgData>> res = client.GetSyncAction<Page<MsgData>>("pdm/annountCement/listSysMsgByUser", new Page<object>
+                {
+                    pageNo = 1,
+                    pageSize = 100
+                });
+                Page<MsgData> pageList = res.HandleResult();
+                messageTitle = $"鍏辨湁 {pageList.total} 鏉℃湭璇绘秷鎭�";
+                this.messages = new ObservableCollection<MsgData>(pageList.records);
+                if (pageList.total > 0)
+                {
+                    Dispatcher.Invoke(() =>
+                    {
+                        eDesktopAlertColor color = eDesktopAlertColor.Default;
+                        eAlertPosition position = eAlertPosition.BottomRight;
+                        DesktopAlert.Show($"鎮ㄦ湁{pageList.total}鏉℃湭璇绘秷鎭紝璇锋鏌�", "\uf005", eSymbolSet.Awesome, Color.Empty, color, position, 5,
+                            DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), AlertClicked);
+                    });
+                }
+            }
+            catch (Exception ex)
+            {
+                Logger.Error("First Request Unread Message Failed.", ex);
+            }
         }
 
         private void SwitchUser_Click(object sender, RoutedEventArgs e)
         {
-
-
+            ((App)Application.Current).SwithUser();
         }
 
         private void AlertClicked(long alertId)
@@ -85,33 +205,97 @@
         {
             var screeWidth = SystemParameters.WorkArea.Width;
             var sHeight = SystemParameters.WorkArea.Height;
-
             this.Left = screeWidth - this.Width;
             this.Top = sHeight - this.Height;
+
+            FirstRefreshMsg();
             ConnectWebSocket();
         }
 
-        private async Task ConnectWebSocket()
+        private void ConnectWebSocket()
         {
             try
             {
-                ClientWebSocket ws = new ClientWebSocket();
-                await ws.ConnectAsync(new Uri($"ws://localhost:8888/pdm-web/daws/{LoginUser.CurrentUser?.id}"), default);
+                socket = new WebSocket($"ws://{setting.Ip}:{setting.Port}/{setting.BaseUrl}/daws/{LoginUser.CurrentUser?.id}");
+                socket.OnOpen += Socket_OnOpen;
+                socket.OnClose += Socket_OnClose;
+                socket.OnMessage += Socket_OnMessage;
+                socket.OnError += Socket_OnError;
+                socket.Connect();
+                StartHeartBeat();
+                /*await ws.ConnectAsync(new Uri($"ws://{setting.Ip}:{setting.Port}/{setting.BaseUrl}/daws/{LoginUser.CurrentUser?.id}"), default);
                 socket = ws;
                 ReadMsg();
-                StartHeartbeat();
+                StartHeartbeat();*/
             }
             catch (Exception ex)
             {
-                await ConnectWebSocket();
+                Logger.Error("Connect Websocket Failed.", ex);
+                ShowStatus("Error", "涓庢湇鍔¤繛鎺ヨ繛鎺ュけ璐ワ紝灏濊瘯閲嶈繛...");
             }
         }
 
-        private void ReadMsg()
+        private void Socket_OnError(object sender, ErrorEventArgs e)
+        {
+            Logger.Error("Websocket On Error.", e.Exception);
+            //ResetSocket();
+            //ConnectWebSocket();
+        }
+
+        private void Socket_OnMessage(object sender, MessageEventArgs e)
+        {
+            HandleMsg(e.Data);
+        }
+
+        private void Socket_OnClose(object sender, CloseEventArgs e)
+        {
+            Logger.Info("Websocket On Close.");
+            StopHeartBeat();
+        }
+
+        private void Socket_OnOpen(object sender, EventArgs e)
+        {
+            Logger.Info("Websocket On Open.");
+            ShowStatus("Success", "涓庢湇鍔″櫒杩炴帴鐘舵�佹甯�");
+            // StartHeartBeat();
+        }
+
+        public void StartHeartBeat()
+        {
+            if (heartbeatTimer == null)
+            {
+                heartbeatTimer = new System.Timers.Timer(30 * 1000);
+                heartbeatTimer.Elapsed += HeartbeatTimer_Elapsed;
+                heartbeatTimer.AutoReset = true;
+                heartbeatTimer.Start();
+            }
+        }
+
+        private void HeartbeatTimer_Elapsed(object sender, ElapsedEventArgs e)
+        {
+            if (socket == null || !socket.IsAlive)
+            {
+                Logger.Error($"Websocket HeartBeat Error. Socket is NULL:{socket == null}; IsAlive:{socket.IsAlive}");
+                ShowStatus("Error", "涓庢湇鍔″櫒閫氳涓柇锛屾鍦ㄥ皾璇曢噸杩�...");
+                ResetSocket();
+                ConnectWebSocket();
+            }
+            else
+            {
+                socket.Send("HeartBeat");
+            }
+        }
+
+        public void StopHeartBeat()
+        {
+
+        }
+
+        /*private void ReadMsg()
         {
             readTask = Task.Run(() =>
             {
-                while (socket.State == WebSocketState.Open)
+                while (socket.State == WebSocketState.Open && !cancelToken.IsCancellationRequested)
                 {
                     byte[] buffer = new byte[1024];
                     var task = socket.ReceiveAsync(new ArraySegment<byte>(buffer), default);
@@ -119,9 +303,10 @@
                     var res = task.Result;
                     var msg = Encoding.UTF8.GetString(buffer, 0, res.Count);
                     HandleMsg(msg);
+                    Thread.Sleep(100);
                 }
-            });
-        }
+            }, cancelToken);
+        }*/
 
         private void HandleMsg(string msg)
         {
@@ -129,35 +314,39 @@
             {
                 return;
             }
-            Debug.WriteLine(msg);
             Dispatcher.Invoke(() =>
             {
                 eDesktopAlertColor color = eDesktopAlertColor.Default;
                 eAlertPosition position = eAlertPosition.BottomRight;
                 DesktopAlert.Show(msg, "\uf005", eSymbolSet.Awesome, Color.Empty, color, position, 5,
                     DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), AlertClicked);
+                Refresh_Click(null, null);
             });
         }
 
-        private void StartHeartbeat()
+        public void ResetSocket()
         {
-            heartbeatTimer = new System.Timers.Timer(30 * 1000);
-            heartbeatTimer.Elapsed += HeartbeatTimer_Elapsed;
-            heartbeatTimer.AutoReset = true;
-            heartbeatTimer.Start();
-        }
-
-        private void HeartbeatTimer_Elapsed(object sender, ElapsedEventArgs e)
-        {
-            if (socket == null || socket.State != WebSocketState.Open)
+            if (readTask != null)
             {
-                DoDispose();
-                ConnectWebSocket().Wait();
+                cancelTokenSource.Cancel();
+                readTask = null;
             }
-            else
+            if (socket != null)
             {
-                byte[] buffer = Encoding.UTF8.GetBytes("test");
-                socket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, default);
+                using (var _socketServer = socket)
+                {
+                    try
+                    {
+                        _socketServer.Close();
+                        socket = null;
+                        /*socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "DoDispose", default).Wait();
+                        socket.Dispose();*/
+                    }
+                    catch (Exception ex)
+                    {
+                        Logger.Error("Websocket Close Error.", ex);
+                    }
+                }
             }
         }
 
@@ -169,25 +358,13 @@
                 heartbeatTimer.Dispose();
                 heartbeatTimer = null;
             }
-            if (readTask != null)
-            {
-                readTask.Dispose();
-                readTask = null;
-            }
-            if (socket != null)
-            {
-                try
-                {
-                    socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "DoDispose", default).Wait();
-                    socket.Dispose();
-                }
-                catch (Exception ex)
-                {
+            ResetSocket();
 
-                }
-                finally
+            if (client != null)
+            {
+                using (var _client = client)
                 {
-                    socket = null;
+                    client = null;
                 }
             }
         }
@@ -201,5 +378,56 @@
         {
             this.Hide();
         }
+
+        private void ReadAll_Click(object sender, RoutedEventArgs e)
+        {
+            MaskAdorner.ShowMask(mainContent);
+            Task.Run(() =>
+            {
+                try
+                {
+                    Result<object> res = client.PutSyncAction<object>("pdm/sysAnnouncementSend/readAll");
+                    _ = res.HandleResult();
+                    RefreshData();
+                }
+                catch (Exception ex)
+                {
+                    Logger.Error("Read All Fail.", ex);
+                }
+                finally
+                {
+                    MaskAdorner.HideMask(mainContent);
+                }
+            });
+        }
+
+        private void SingleRead_Click(object sender, RoutedEventArgs e)
+        {
+            Button button = sender as Button;
+            MsgData msg = button.DataContext as MsgData;
+            if (msg == null) return;
+
+            MaskAdorner.ShowMask(mainContent);
+            Task.Run(() =>
+            {
+                try
+                {
+                    Result<object> res = client.PutSyncAction<object>("pdm/sysAnnouncementSend/editByAnntIdAndUserId", new MsgData
+                    {
+                        anntId = msg.id
+                    });
+                    _ = res.HandleResult();
+                    RefreshData();
+                }
+                catch (Exception ex)
+                {
+                    Logger.Error("Read All Fail.", ex);
+                }
+                finally
+                {
+                    MaskAdorner.HideMask(mainContent);
+                }
+            });
+        }
     }
 }
diff --git a/PdmAlert/PdmAlert.csproj b/PdmAlert/PdmAlert.csproj
index 9a18d0d..924b67b 100644
--- a/PdmAlert/PdmAlert.csproj
+++ b/PdmAlert/PdmAlert.csproj
@@ -57,9 +57,15 @@
   <PropertyGroup>
     <ApplicationManifest>app.manifest</ApplicationManifest>
   </PropertyGroup>
+  <PropertyGroup>
+    <ApplicationIcon>Icon.ico</ApplicationIcon>
+  </PropertyGroup>
   <ItemGroup>
     <Reference Include="DevComponents.DotNetBar2">
       <HintPath>..\lib\DevComponents.DotNetBar2.dll</HintPath>
+    </Reference>
+    <Reference Include="log4net">
+      <HintPath>lib\log4net.dll</HintPath>
     </Reference>
     <Reference Include="Newtonsoft.Json">
       <HintPath>lib\Newtonsoft.Json.dll</HintPath>
@@ -78,6 +84,9 @@
     <Reference Include="System.Xaml">
       <RequiredTargetFramework>4.0</RequiredTargetFramework>
     </Reference>
+    <Reference Include="websocket-sharp">
+      <HintPath>lib\websocket-sharp.dll</HintPath>
+    </Reference>
     <Reference Include="WindowsBase" />
     <Reference Include="PresentationCore" />
     <Reference Include="PresentationFramework" />
@@ -87,6 +96,7 @@
       <Generator>MSBuild:Compile</Generator>
       <SubType>Designer</SubType>
     </ApplicationDefinition>
+    <Compile Include="ToolSetting.cs" />
     <Compile Include="Util.cs" />
     <Page Include="LoginWindow.xaml">
       <SubType>Designer</SubType>
@@ -132,6 +142,9 @@
     </EmbeddedResource>
     <None Include="app.manifest" />
     <Resource Include="Icon\iconfont.ttf" />
+    <None Include="log4net.config">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
     <None Include="Properties\Settings.settings">
       <Generator>SettingsSingleFileGenerator</Generator>
       <LastGenOutput>Settings.Designer.cs</LastGenOutput>
@@ -141,9 +154,43 @@
     <None Include="App.config" />
   </ItemGroup>
   <ItemGroup>
+    <Resource Include="Icon.ico" />
     <Content Include="Icon\Icon.ico">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </Content>
+    <Content Include="ReleaseSettings\ToolSetting.xml">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="ReleaseSettings\UpdaterSetting.xml">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="Settings\UpdaterSetting.xml">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="Settings\ToolSetting.xml">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\CommonUpdater\VersionControl\VersionControl.csproj">
+      <Project>{edc73c56-d0c5-4ac9-b296-3253915ef933}</Project>
+      <Name>VersionControl</Name>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PostBuildEvent>xcopy "C:\Main\Workspace\VisualStudio\CommonUpdater\AutoUpdater\bin\x64\$(ConfigurationName)\" "$(TargetDir)AutoUpdater\" /S /Y
+
+IF "$(ConfigurationName)"=="Release" GOTO PRE
+GOTO END
+
+:PRE
+rd /Q/S "$(TargetDir)Settings" &amp;&amp; ren "$(TargetDir)ReleaseSettings" "Settings"
+GOTO END
+
+:END
+xcopy "$(TargetDir)Settings\UpdaterSetting.xml" "$(TargetDir)AutoUpdater\Settings\UpdaterSetting.xml" /Y
+
+</PostBuildEvent>
+  </PropertyGroup>
 </Project>
\ No newline at end of file
diff --git a/PdmAlert/PdmAlert.iss b/PdmAlert/PdmAlert.iss
new file mode 100644
index 0000000..f924a80
--- /dev/null
+++ b/PdmAlert/PdmAlert.iss
@@ -0,0 +1,62 @@
+; AppId
+#define AppId = "PdmMsgAlert"
+; AppName
+#define AppName = "PdmMsgAlert"
+; 打包的应用文件夹路径
+#define AppDir = "C:\Main\Workspace\VisualStudio\PdmSwPlugin2\PdmAlert\bin\x64\Release\"
+; 自动更新程序路径
+#define AutoUpdaterDir = "C:\Main\Workspace\VisualStudio\PdmSwPlugin2\PdmAlert\bin\x64\Release\AutoUpdater\"
+; 版本
+#define Version = "0.0.0.1"
+
+; 生成的Installer存放路径
+#define OutPutDir = "C:\Main\Workspace\Output"
+
+
+[Setup]
+; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
+; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
+AppId={{{#AppId}}
+AppName={#AppName}
+AppVersion={#Version}
+;AppVerName=Test 1.0
+; 安装路径 C:\Program Files (x86)\LHJ\PdmSwPlugin
+DefaultDirName={autopf}\HengXin\PdmMsgAlert
+DisableDirPage=yes
+DefaultGroupName=PdmMsgAlert
+DisableProgramGroupPage=yes
+; Uncomment the following line to run in non administrative install mode (install for current user only.)
+;PrivilegesRequired=lowest
+OutputDir={#OutputDir}
+OutputBaseFilename=PdmMsgAlertInstaller_V{#Version}
+Compression=lzma
+SolidCompression=yes
+WizardStyle=modern
+PrivilegesRequired=admin
+UsedUserAreasWarning=no
+
+[Languages]
+Name: "chinesesimplified"; MessagesFile: "compiler:Languages\ChineseSimplified.isl"
+
+[Files]
+Source: "{#AppDir}*"; DestDir: "{app}"; Excludes: "temp\*,Log\*"; Flags:recursesubdirs ignoreversion
+;Source: "{#AutoUpdaterDir}*"; DestDir: "{app}\AutoUpdater"; Excludes: "download\*"; Flags: ignoreversion
+; NOTE: Don't use "Flags: ignoreversion" on any shared system files
+
+[Dirs]
+Name: {app}; Permissions: users-full
+
+[Icons]
+Name: "{group}\{cm:UninstallProgram,Test}"; Filename: "{uninstallexe}"
+Name: "{userdesktop}\{#AppName}";Filename: "{app}\PdmAlert.exe"; WorkingDir: "{app}"
+
+[code]
+procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
+begin
+  if CurUninstallStep = usDone then
+  begin
+    DelTree(ExpandConstant('{app}'), True, True, True);
+  end;
+end;
+
+
diff --git a/PdmAlert/Properties/AssemblyInfo.cs b/PdmAlert/Properties/AssemblyInfo.cs
index d859239..a71e5fe 100644
--- a/PdmAlert/Properties/AssemblyInfo.cs
+++ b/PdmAlert/Properties/AssemblyInfo.cs
@@ -1,4 +1,5 @@
-锘縰sing System.Reflection;
+锘縰sing log4net.Config;
+using System.Reflection;
 using System.Resources;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
@@ -53,3 +54,4 @@
 // [assembly: AssemblyVersion("1.0.*")]
 [assembly: AssemblyVersion("1.0.0.0")]
 [assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
diff --git a/PdmAlert/ReleaseSettings/ToolSetting.xml b/PdmAlert/ReleaseSettings/ToolSetting.xml
new file mode 100644
index 0000000..c739638
--- /dev/null
+++ b/PdmAlert/ReleaseSettings/ToolSetting.xml
Binary files differ
diff --git a/PdmAlert/ReleaseSettings/UpdaterSetting.xml b/PdmAlert/ReleaseSettings/UpdaterSetting.xml
new file mode 100644
index 0000000..9db2446
--- /dev/null
+++ b/PdmAlert/ReleaseSettings/UpdaterSetting.xml
Binary files differ
diff --git a/PdmAlert/Settings/ToolSetting.xml b/PdmAlert/Settings/ToolSetting.xml
new file mode 100644
index 0000000..918985e
--- /dev/null
+++ b/PdmAlert/Settings/ToolSetting.xml
Binary files differ
diff --git a/PdmAlert/Settings/UpdaterSetting.xml b/PdmAlert/Settings/UpdaterSetting.xml
new file mode 100644
index 0000000..df9d15c
--- /dev/null
+++ b/PdmAlert/Settings/UpdaterSetting.xml
Binary files differ
diff --git a/PdmAlert/ToolSetting.cs b/PdmAlert/ToolSetting.cs
new file mode 100644
index 0000000..aed3932
--- /dev/null
+++ b/PdmAlert/ToolSetting.cs
@@ -0,0 +1,88 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Xml;
+using System.IO;
+
+namespace PdmAlert
+{
+    public class ToolSetting
+    {
+        public static ToolSetting Instance { get; private set; }
+
+        private Dictionary<string, string> DataMap;
+
+        public int TimeOut { get; private set; } = 600;
+        public string Mode { get; private set; } = "prod";
+        public string Ip { get; private set; } = "";
+        public int Port { get; private set; } = 0;
+        public string BaseUrl { get; private set; } = "";
+
+        private void Init()
+        {
+
+        }
+
+        static ToolSetting()
+        {
+            Instance = LoadFromXml(null);
+        }
+
+        private static ToolSetting LoadFromXml(string xmlPath)
+        {
+            if (xmlPath == null)
+            {
+                string dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+                xmlPath = Path.Combine(dir, "Settings", "ToolSetting.xml");
+            }
+
+            ToolSetting setting = new ToolSetting();
+            if (File.Exists(xmlPath))
+            {
+                XmlDocument xmlDoc = new XmlDocument();
+                xmlDoc.Load(xmlPath);
+                XmlNode xmlRoot = xmlDoc.DocumentElement;
+                BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
+                var props = typeof(ToolSetting).GetProperties(flags).ToArray();
+                foreach (var prop in props)
+                {
+                    string name = prop.Name;
+                    string value = xmlRoot.SelectSingleNode(name)?.InnerText;
+                    if (value == null)
+                    {
+                        continue;
+                    }
+                    Type type = prop.PropertyType;
+                    if (type == typeof(int))
+                    {
+                        int.TryParse(value, out int temp);
+                        prop.SetValue(setting, temp);
+                    }
+                    else if (type == typeof(bool))
+                    {
+                        bool.TryParse(value, out bool temp);
+                        prop.SetValue(setting, temp);
+                    }
+                    else if (type == typeof(string))
+                    {
+                        prop.SetValue(setting, value);
+                    }
+                }
+            }
+            setting.Init();
+            return setting;
+        }
+
+        /// <summary>
+        /// 寮哄埗鍒锋柊閰嶇疆
+        /// </summary>
+        /// <param name="xmlPath"></param>
+        /// <returns></returns>
+        public static ToolSetting RefreshFromXml(string xmlPath)
+        {
+            Instance = LoadFromXml(xmlPath);
+            return Instance;
+        }
+    }
+}
diff --git a/PdmAlert/Util.cs b/PdmAlert/Util.cs
index b5ed241..71f1c83 100644
--- a/PdmAlert/Util.cs
+++ b/PdmAlert/Util.cs
@@ -7,10 +7,158 @@
 using System.Text;
 using System.Threading.Tasks;
 using System.Web;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Media;
+using System.Windows;
 using Newtonsoft.Json;
 
 namespace PdmAlert.Util
 {
+    public class MaskAdorner : Adorner
+    {
+        private UIElement child;
+        private TextBox textBox;
+
+        public static readonly Dictionary<Visual, MaskAdorner> cache = new Dictionary<Visual, MaskAdorner>();
+
+        public MaskAdorner(UIElement adornedElement, string message = null) : base(adornedElement)
+        {
+            textBox = new TextBox
+            {
+                TextAlignment = TextAlignment.Center,
+                Background = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)),
+                Text = message,
+                BorderThickness = new Thickness(0),
+                BorderBrush = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0))
+            };
+            StackPanel stackPanel = new StackPanel()
+            {
+                HorizontalAlignment = HorizontalAlignment.Center,
+                VerticalAlignment = VerticalAlignment.Center,
+                Background = new SolidColorBrush(Color.FromArgb(0, 255, 255, 255)),
+            };
+            stackPanel.Children.Add(new ProgressBar
+            {
+                Width = 100,
+                Height = 20,
+                IsIndeterminate = true
+            });
+            stackPanel.Children.Add(textBox);
+            Child = new Border
+            {
+                Background = new SolidColorBrush(Color.FromArgb(100, 0, 0, 0)),
+                HorizontalAlignment = HorizontalAlignment.Stretch,
+                VerticalAlignment = VerticalAlignment.Stretch,
+                Child = stackPanel
+            };
+        }
+        //Adorner 鐩存帴缁ф壙鑷� FrameworkElement锛�
+        //娌℃湁Content鍜孋hild灞炴�э紝
+        //鑷繁娣诲姞涓�涓紝鏂逛究鍚戝叾涓坊鍔犳垜浠殑鎺т欢
+        public UIElement Child
+        {
+            get => child;
+            set
+            {
+                if (value == null)
+                {
+                    RemoveVisualChild(child);
+                }
+                else
+                {
+                    AddVisualChild(value);
+                }
+                child = value;
+            }
+        }
+        //閲嶅啓VisualChildrenCount 琛ㄧず姝ゆ帶浠跺彧鏈変竴涓瓙鎺т欢
+        protected override int VisualChildrenCount => 1;
+        //鎺т欢璁$畻澶у皬鐨勬椂鍊欙紝鎴戜滑鍦ㄨ楗板眰涓婃坊鍔犵殑鎺т欢涔熻绠椾竴涓嬪ぇ灏�
+        protected override Size ArrangeOverride(Size finalSize)
+        {
+            child?.Arrange(new Rect(finalSize));
+            return finalSize;
+        }
+        //閲嶅啓GetVisualChild,杩斿洖鎴戜滑娣诲姞鐨勬帶浠�
+        protected override Visual GetVisualChild(int index)
+        {
+            if (index == 0 && child != null) return child;
+            return base.GetVisualChild(index);
+        }
+
+        public void ShowMessage(string message)
+        {
+            this.textBox.Text = message;
+        }
+
+
+        public static void ShowMask(Visual visual, string message = null)
+        {
+            var sb = cache;
+            if (cache.ContainsKey(visual))
+            {
+                return;
+            }
+            visual.Dispatcher.Invoke(() =>
+            {
+                AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(visual);
+                if (adornerLayer == null) return;
+                Adorner[] ads = adornerLayer.GetAdorners(adornerLayer);
+                if (ads != null)
+                {
+                    foreach (Adorner ad in ads)
+                    {
+                        if (ad is MaskAdorner adorner)
+                        {
+                            return;
+                        }
+                    }
+                }
+                //鍒涘缓鎴戜滑瀹氫箟鐨凙dorner
+                MaskAdorner _adorner = new MaskAdorner(adornerLayer, message);
+                //娣诲姞鍒癮dornerLayer瑁呴グ灞備笂
+                adornerLayer.Add(_adorner);
+                cache.Add(visual, _adorner);
+            });
+        }
+
+        public static void ShowMessage(Visual visual, string message)
+        {
+            if (!cache.ContainsKey(visual))
+            {
+                return;
+            }
+            visual.Dispatcher.Invoke(() =>
+            {
+                AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(visual);
+                MaskAdorner mask = cache[visual];
+                if (mask == null)
+                {
+                    return;
+                }
+                mask.ShowMessage(message);
+            });
+        }
+
+        public static void HideMask(Visual visual)
+        {
+            if (!cache.ContainsKey(visual))
+            {
+                return;
+            }
+            visual.Dispatcher.Invoke(() =>
+            {
+                if (cache.ContainsKey(visual))
+                {
+                    AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(visual);
+                    adornerLayer.Remove(cache[visual]);
+                    cache.Remove(visual);
+                }
+            });
+        }
+    }
+
     [Serializable]
     public class Result<T>
     {
@@ -37,6 +185,16 @@
         {
             get; set;
         }
+    }
+
+    public class Page<T>
+    {
+        public int pageNo { get; set; }
+        public int pageSize { get; set; }
+        public int total { get; set; }
+        public int current { get; set; }
+        public int size { get; set; }
+        public List<T> records { get; set; }
     }
 
     public static class ResultHandler
@@ -236,6 +394,27 @@
             return task2.Result;
         }
 
+        public static Result<T> PutSyncAction<T>(this HttpClient client, string url, object data = null)
+        {
+            StringContent content;
+            if (data != null)
+            {
+                string dataStr = JsonUtil.Serialize(data);
+                content = new StringContent(dataStr, Encoding.UTF8, "application/json");
+            }
+            else
+            {
+                content = new StringContent("");
+            }
+            Task<HttpResponseMessage> task = client.PutAsync(url, content);
+            task.Wait();
+            HttpResponseMessage response = task.Result;
+            response.EnsureSuccessStatusCode();
+            Task<string> task2 = response.Content.ReadAsStringAsync();
+            task2.Wait();
+            return JsonUtil.Deserialize<Result<T>>(task2.Result);
+        }
+
         public static async Task<T> PostAsyncAction<T>(this HttpClient client, string url, string data)
         {
             StringContent content = new StringContent(data, Encoding.UTF8, "application/json");
diff --git a/PdmAlert/lib/Fleck.dll b/PdmAlert/lib/Fleck.dll
new file mode 100644
index 0000000..8879ec4
--- /dev/null
+++ b/PdmAlert/lib/Fleck.dll
Binary files differ
diff --git a/PdmAlert/lib/log4net.dll b/PdmAlert/lib/log4net.dll
new file mode 100644
index 0000000..5752c20
--- /dev/null
+++ b/PdmAlert/lib/log4net.dll
Binary files differ
diff --git a/PdmAlert/lib/websocket-sharp.dll b/PdmAlert/lib/websocket-sharp.dll
new file mode 100644
index 0000000..01614c8
--- /dev/null
+++ b/PdmAlert/lib/websocket-sharp.dll
Binary files differ
diff --git a/PdmAlert/log4net.config b/PdmAlert/log4net.config
new file mode 100644
index 0000000..0bf240b
--- /dev/null
+++ b/PdmAlert/log4net.config
@@ -0,0 +1,35 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<log4net>
+	<!-- 鎺у埗鍙版棩蹇楅厤缃� -->
+	<appender name="Console" type="log4net.Appender.ConsoleAppender">
+		<!-- 鏃ュ織杈撳嚭鏍煎紡 -->
+		<layout type="log4net.Layout.PatternLayout">
+			<conversionPattern value="%5level [%thread] (%file:%line) - %message%newline" />
+		</layout>
+	</appender>
+
+	<!-- 鏂囦欢瀛樺偍鏃ュ織閰嶇疆 -->
+	<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
+		<!-- 淇濆瓨鏂囦欢鐨勫悕绉� -->
+		<file value="./Log/" />
+		<appendToFile value="true" />
+		<rollingStyle value="Date" />
+		<datePattern value="'log_'yyyyMMdd'.log'"/>
+		<staticLogFileName value="false"/>
+
+		<!-- 鏂囦欢鐨勭紪鐮佹柟寮� -->
+		<param name="Encoding" value="UTF-8"/>
+		<!-- 淇濆瓨鏂囦欢鏁伴噺 -->
+		<maxSizeRollBackups value="7" />
+		<!-- 鏃ュ織杈撳嚭鏍煎紡 -->
+		<layout type="log4net.Layout.PatternLayout">
+			<conversionPattern value="%date{ISO8601} [%logger]  %level  %class - %message%newline" />
+		</layout>
+	</appender>
+
+	<root>
+		<level value="INFO" />
+		<appender-ref ref="Console" />
+		<appender-ref ref="RollingFile" />
+	</root>
+</log4net>
\ No newline at end of file
diff --git a/PdmSw/.vs/PdmSw/FileContentIndex/1e97e5f0-ad3c-4fa0-845d-d0d4b508b3aa.vsidx b/PdmSw/.vs/PdmSw/FileContentIndex/1e97e5f0-ad3c-4fa0-845d-d0d4b508b3aa.vsidx
deleted file mode 100644
index 46d18d2..0000000
--- a/PdmSw/.vs/PdmSw/FileContentIndex/1e97e5f0-ad3c-4fa0-845d-d0d4b508b3aa.vsidx
+++ /dev/null
Binary files differ
diff --git a/PdmSw/.vs/PdmSw/FileContentIndex/4671096b-140b-4229-a025-97df57021262.vsidx b/PdmSw/.vs/PdmSw/FileContentIndex/4671096b-140b-4229-a025-97df57021262.vsidx
deleted file mode 100644
index 3814108..0000000
--- a/PdmSw/.vs/PdmSw/FileContentIndex/4671096b-140b-4229-a025-97df57021262.vsidx
+++ /dev/null
Binary files differ
diff --git a/PdmSw/.vs/PdmSw/FileContentIndex/6b982709-fe14-4b34-a175-b50bca946af4.vsidx b/PdmSw/.vs/PdmSw/FileContentIndex/6b982709-fe14-4b34-a175-b50bca946af4.vsidx
deleted file mode 100644
index 725a19c..0000000
--- a/PdmSw/.vs/PdmSw/FileContentIndex/6b982709-fe14-4b34-a175-b50bca946af4.vsidx
+++ /dev/null
Binary files differ
diff --git a/PdmSw/.vs/PdmSw/FileContentIndex/92f976c2-0875-4c1f-bb43-2d01b4d875dc.vsidx b/PdmSw/.vs/PdmSw/FileContentIndex/92f976c2-0875-4c1f-bb43-2d01b4d875dc.vsidx
deleted file mode 100644
index 2a9545b..0000000
--- a/PdmSw/.vs/PdmSw/FileContentIndex/92f976c2-0875-4c1f-bb43-2d01b4d875dc.vsidx
+++ /dev/null
Binary files differ
diff --git a/PdmSw/.vs/PdmSw/FileContentIndex/a5ce55b6-65c6-4de9-8b17-865577fcdb4d.vsidx b/PdmSw/.vs/PdmSw/FileContentIndex/a5ce55b6-65c6-4de9-8b17-865577fcdb4d.vsidx
deleted file mode 100644
index 01fbcaf..0000000
--- a/PdmSw/.vs/PdmSw/FileContentIndex/a5ce55b6-65c6-4de9-8b17-865577fcdb4d.vsidx
+++ /dev/null
Binary files differ

--
Gitblit v1.9.1