本文首發於:碼友網--一個專一.NET/.NET Core開發的編程愛好者社區。git
C#/.NET基於Topshelf建立Windows服務的系列文章目錄:github
在上一篇文章《C#/.NET基於Topshelf建立Windows服務程序及服務的安裝和卸載》中,咱們瞭解發C#/.NET建立基於Topshelf Windows服務程序的大體流程,參數配置以及服務的安裝和卸載。同時,咱們也使用一個簡單的定時任務演示了Topshelf服務的執行狀況。數據庫
今天我將繼續爲你們分享關於Topshelf主題的技術文章。本文主要演示在C#/.NET應用程序開發中建立一個基於Topshelf的應用程序守護進程(服務)。編程
首先,打開以前咱們建立的[TopshelfDemoService.sln]解決方案。在這個解決方案中再建立一個名爲TopshelfDemo.Client
的客戶端控制檯應用程序,這個客戶端程序便是咱們須要使用[TopshelfDemoService]守護的。只是爲了演示,因此客戶端並無實際意義的邏輯和功能,在Program.cs
文件中,添加以下示例代碼:windows
using System; namespace TopshelfDemo.Client { class Program { static void Main(string[] args) { Console.WriteLine("這是一個由[碼友網]建立的ERP系統示例程序,目前正在運行..."); Console.WriteLine("技術支持:碼友網(https://codedefautl.com) by Rector"); Console.ReadLine(); } } }
僅此而已。數組
編寫好後,生成或者運行一下這個項目。你會看到一個控制檯應用程序界面,如:緩存
再回到項目[TopshelfDemoService]中,打開類文件HealthMonitorService.cs
,其中的定時功能演示的是一個檢查某系統健康情況的任務,如今咱們把定時任務功能改成守護某個或者某些應用程序。app
這裏爲了演示方便,沒有從新建立服務類,在實際項目中,你也能夠根據本身的狀況建立不一樣的服務類。
修改其中代碼爲以下所示:ui
using System; using System.Collections.Generic; using System.Timers; namespace TopshelfDemoService { internal class HealthMonitorService { /// <summary> /// 檢測週期計時器 /// </summary> private readonly Timer _timer; /// <summary> /// 檢測週期(秒) /// </summary> private int _monitorInterval = 10; /// <summary> /// 要守護的應用程序列表 /// </summary> private List<DaemonApplicationInfo> _daemonApps { get; set; } public HealthMonitorService() { // 初始化要守護的應用程序列表 // 實際項目中,你能夠將這裏的初始化參數放到配置文件/數據庫/緩存中(怎麼方便怎麼來) _daemonApps = new List<DaemonApplicationInfo> { 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(); } /// <summary> /// 守護應用程序的方法 /// </summary> 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() { _timer.Start(); } public void Stop() { _timer.Stop(); } } }
新建類DaemonApplicationInfo.cs
和ProcessorHelper.cs
,編寫以下代碼。編碼
DaemonApplicationInfo.cs(需守護的應用程序實體類):
namespace TopshelfDemoService { /// <summary> /// 需守護的應用程序實體 /// </summary> public class DaemonApplicationInfo { /// <summary> /// 進程中顯示的名稱 /// </summary> public string ProcessName { get; set; } /// <summary> /// 應用程序安裝路徑 /// </summary> public string AppFilePath { get; set; } /// <summary> /// 應用程序的名稱 /// </summary> public string AppDisplayName { get; set; } /// <summary> /// 參數 /// </summary> public string Args { get; set; } } }
ProcessorHelper.cs(進程處理幫助類):
using System.Collections.Generic; using System.Diagnostics; using System.Linq; namespace TopshelfDemoService { /// <summary> /// 進程處理幫助類 /// </summary> internal class ProcessorHelper { /// <summary> /// 獲取當前計算機全部的進程列表(集合) /// </summary> /// <returns></returns> public static List<Process> GetProcessList() { return GetProcesses().ToList(); } /// <summary> /// 獲取當前計算機全部的進程列表(數組) /// </summary> /// <returns></returns> public static Process[] GetProcesses() { var processList = Process.GetProcesses(); return processList; } /// <summary> /// 判斷指定的進程是否存在 /// </summary> /// <param name="processName"></param> /// <returns></returns> public static bool IsProcessExists(string processName) { return Process.GetProcessesByName(processName).Length > 0; } /// <summary> /// 啓動一個指定路徑的應用程序 /// </summary> /// <param name="applicationPath"></param> /// <param name="args"></param> public static void RunProcess(string applicationPath, string args = "") { try { var psi = new ProcessStartInfo { FileName = applicationPath, WindowStyle = ProcessWindowStyle.Normal, Arguments = args }; Process.Start(psi); } catch{} } } }
完成以上編碼後,咱們將項目程序[TopshelfDemo.Client]和[TopshelfDemoService]先都關閉掉(若是已運行),接着運行項目[TopshelfDemoService],下面就是見證奇蹟的時刻啦:
能夠看到,守護程序[TopshelfDemoService]自動啓動了客戶端程序[TopshelfDemo.Client.exe],而且只會啓動一個客戶端實例程序。當咱們把客戶端關閉後,下次守護程序檢測的時候客戶端程序又會被重啓。
若是你正高高興興地將TopshelfDemoService做爲Windows服務安裝,那麼你可能會遇到這個問題,即守護進程正常運行,客戶端程序也能正常地被守護而且啓動,在Windows的"任務管理器"中也能夠找到客戶端的進程,但卻看不到客戶端程序的UI界面。
這是怎麼回事呢???是否是哪裏出錯了呢???應該如何解決呢???
預知後事如何請聽下回分解(未完待續)...
好了,今天的在C#/.NET應用程序開發中建立一個基於Topshelf的應用程序守護進程(服務)的分享就到這裏。
我是Rector,但願本文對C#/.NET開發的你有所幫助。
本示例代碼託管地址能夠在原出處找到:示例代碼下載地址