diff --git a/TopshelfDemo.Client/App.config b/TopshelfDemo.Client/App.config
new file mode 100644
index 0000000..b50c74f
--- /dev/null
+++ b/TopshelfDemo.Client/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TopshelfDemo.Client/Program.cs b/TopshelfDemo.Client/Program.cs
new file mode 100644
index 0000000..593da6a
--- /dev/null
+++ b/TopshelfDemo.Client/Program.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace TopshelfDemo.Client
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("这是一个由[码友网]创建的ERP系统示例程序,目前正在运行...");
+ Console.WriteLine("技术支持:码友网(https://codedefautl.com) by Rector");
+ Console.ReadLine();
+ }
+ }
+}
diff --git a/TopshelfDemo.Client/Properties/AssemblyInfo.cs b/TopshelfDemo.Client/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..edc908a
--- /dev/null
+++ b/TopshelfDemo.Client/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("TopshelfDemo.Client")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("TopshelfDemo.Client")]
+[assembly: AssemblyCopyright("Copyright © 2019")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("6c8d57bd-1708-433a-bd9c-b4b4830663cb")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/TopshelfDemo.Client/TopshelfDemo.Client.csproj b/TopshelfDemo.Client/TopshelfDemo.Client.csproj
new file mode 100644
index 0000000..4330376
--- /dev/null
+++ b/TopshelfDemo.Client/TopshelfDemo.Client.csproj
@@ -0,0 +1,53 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {6C8D57BD-1708-433A-BD9C-B4B4830663CB}
+ Exe
+ TopshelfDemo.Client
+ TopshelfDemo.Client
+ v4.6.2
+ 512
+ true
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TopshelfDemoService.sln b/TopshelfDemoService.sln
index 8ecb31e..186ca27 100644
--- a/TopshelfDemoService.sln
+++ b/TopshelfDemoService.sln
@@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.28729.10
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TopshelfDemoService", "TopshelfDemoService\TopshelfDemoService.csproj", "{9C3F12DC-3192-4E4E-9CF7-15CFD568AB15}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TopshelfDemo.Client", "TopshelfDemo.Client\TopshelfDemo.Client.csproj", "{6C8D57BD-1708-433A-BD9C-B4B4830663CB}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -15,6 +17,10 @@ Global
{9C3F12DC-3192-4E4E-9CF7-15CFD568AB15}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C3F12DC-3192-4E4E-9CF7-15CFD568AB15}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C3F12DC-3192-4E4E-9CF7-15CFD568AB15}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6C8D57BD-1708-433A-BD9C-B4B4830663CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6C8D57BD-1708-433A-BD9C-B4B4830663CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6C8D57BD-1708-433A-BD9C-B4B4830663CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6C8D57BD-1708-433A-BD9C-B4B4830663CB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/TopshelfDemoService/DaemonApplicationInfo.cs b/TopshelfDemoService/DaemonApplicationInfo.cs
new file mode 100644
index 0000000..7e369fa
--- /dev/null
+++ b/TopshelfDemoService/DaemonApplicationInfo.cs
@@ -0,0 +1,26 @@
+namespace TopshelfDemoService
+{
+ ///
+ /// 需守护的应用程序实体
+ ///
+ public class DaemonApplicationInfo
+ {
+ ///
+ /// 进程中显示的名称
+ ///
+ public string ProcessName { get; set; }
+ ///
+ /// 应用程序安装路径
+ ///
+ public string AppFilePath { get; set; }
+ ///
+ /// 应用程序的名称
+ ///
+ public string AppDisplayName { get; set; }
+
+ ///
+ /// 参数
+ ///
+ public string Args { get; set; }
+ }
+}
diff --git a/TopshelfDemoService/HealthMonitorService.cs b/TopshelfDemoService/HealthMonitorService.cs
index e11cc30..38d9e6e 100644
--- a/TopshelfDemoService/HealthMonitorService.cs
+++ b/TopshelfDemoService/HealthMonitorService.cs
@@ -1,15 +1,62 @@
using System;
+using System.Collections.Generic;
using System.Timers;
namespace TopshelfDemoService
{
internal class HealthMonitorService
{
+ ///
+ /// 检测周期计时器
+ ///
private readonly Timer _timer;
+ ///
+ /// 检测周期(秒)
+ ///
+ private int _monitorInterval = 3;
+ ///
+ /// 要守护的应用程序列表
+ ///
+ private List _daemonApps { get; set; }
+
public HealthMonitorService()
{
- _timer = new Timer(1000) { AutoReset = true };
- _timer.Elapsed += (sender, eventArgs) => Console.WriteLine("执行系统健康检查任务,所有指标均正常。执行时间:{0}", DateTime.Now);
+ // 初始化要守护的应用程序列表
+ // 实际项目中,你可以将这里的初始化参数放到配置文件/数据库/缓存中(怎么方便怎么来)
+ _daemonApps = new List {
+ new DaemonApplicationInfo {
+ ProcessName ="TopshelfDemo.Client", // 请根据你的情况填写
+ AppDisplayName ="TopshelfDemo Client", // 请根据你的情况填写
+ AppFilePath =@"D:\Projects\github\TopshelfDemoService\TopshelfDemo.Client\bin\Debug\TopshelfDemo.Client.exe" // 请根据你的情况填写
+ }
+ };
+ _timer = new Timer(_monitorInterval*1000) { AutoReset = true };
+ _timer.Elapsed += (sender, eventArgs) => Monitor();
+ }
+
+ ///
+ /// 守护应用程序的方法
+ ///
+ private void Monitor()
+ {
+ foreach (var app in _daemonApps)
+ {
+ // 判断当前进程是存已启动
+ if (ProcessorHelper.IsProcessExists(app.ProcessName))
+ {
+ Console.WriteLine("Application[{0}] already exists.", app.ProcessName);
+ return;
+ }
+ try
+ {
+ // 当前主机进程列表中没有需要守护的进程名称,则启动这个进程对应的应用程序
+ ProcessorHelper.RunProcess(app.AppFilePath, app.Args);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("Start application failed:{0}", ex);
+ }
+ }
}
public void Start()
diff --git a/TopshelfDemoService/ProcessorHelper.cs b/TopshelfDemoService/ProcessorHelper.cs
new file mode 100644
index 0000000..192dbed
--- /dev/null
+++ b/TopshelfDemoService/ProcessorHelper.cs
@@ -0,0 +1,61 @@
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+
+namespace TopshelfDemoService
+{
+ ///
+ /// 进程处理帮助类
+ ///
+ internal class ProcessorHelper
+ {
+ ///
+ /// 获取当前计算机所有的进程列表(集合)
+ ///
+ ///
+ public static List GetProcessList()
+ {
+ return GetProcesses().ToList();
+ }
+
+ ///
+ /// 获取当前计算机所有的进程列表(数组)
+ ///
+ ///
+ public static Process[] GetProcesses()
+ {
+ var processList = Process.GetProcesses();
+ return processList;
+ }
+
+ ///
+ /// 判断指定的进程是否存在
+ ///
+ ///
+ ///
+ public static bool IsProcessExists(string processName)
+ {
+ return Process.GetProcessesByName(processName).Length > 0;
+ }
+
+ ///
+ /// 启动一个指定路径的应用程序
+ ///
+ ///
+ ///
+ public static void RunProcess(string applicationPath, string args = "")
+ {
+ try
+ {
+ var psi = new ProcessStartInfo
+ {
+ FileName = applicationPath,
+ WindowStyle = ProcessWindowStyle.Normal,
+ Arguments = args
+ };
+ Process.Start(psi);
+ }
+ catch{}
+ }
+ }
+}
diff --git a/TopshelfDemoService/TopshelfDemoService.csproj b/TopshelfDemoService/TopshelfDemoService.csproj
index 63a33a5..989e64e 100644
--- a/TopshelfDemoService/TopshelfDemoService.csproj
+++ b/TopshelfDemoService/TopshelfDemoService.csproj
@@ -48,8 +48,10 @@
+
+