項目中有些時候須要寫服務,通常咱們都是先建立控制檯程序,測試,運行,成功以後再建立windows服務程序,這樣好麻煩啊,有沒有簡單的控制檯程序直接變成Widnows服務,通過查找,找到了Topshelf。Topshelf是一個託管使用.NET框架編寫的服務的框架,簡化了服務的建立,容許開發人員建立一個簡單的控制檯應用程序,可使用Topshelf做爲服務安裝。html
根據下面的評論,增長了這一部分的內容,NSSM是一款比較好用的將exe封裝爲服務的工具git
1.下載NSSM官網https://nssm.cc/,download
2. 解壓
3. 在cmd中找到nssm.exe
例如:E:\nssm-2.24\nssm-2.24\win64>github
4. 安裝服務
安裝服務:nssm install <servicename>windows
寫的控制檯程序須要注意,不要一閃而過,也就是運行控制檯程序的時候,控制檯不會本身關閉,本身關閉意味着程序結束,服務啓動以後也會結束,因此最後的 Console.ReadKey();仍是須要的。框架
啓動服務:nssm start <servicename>
中止服務:nssm stop <servicename>
重啓服務: nssm restart <servicename>
服務刪除:nssm remove <servicename>工具
這個工具的使用是根據下面的評論來的,比較好用,可是也有點小缺點,就是程序都須要寫在main中,須要控制好運行的順序,若是要服務開始的時候運行什麼,中間運行什麼,中止的時候運行什麼,這個程序就沒辦法控制了,若是是通常的服務用工具就能夠了,若是比較複雜,須要作流程控制,能夠參考下面的程序。測試
Topshelf是一個託管使用.NET框架編寫的服務的框架。簡化了服務的建立,容許開發人員建立一個簡單的控制檯應用程序,可使用Topshelf做爲服務安裝。緣由很簡單:調試控制檯應用程序比使用服務要容易得多。一旦應用程序通過測試並能夠投入生產,Topshelf即可以輕鬆地將應用程序做爲服務進行安裝。這是一個開源的項目,項目地址,Nuget上能夠搜到響應的庫。spa
1.建立控制檯程序
2.安裝Topshelf,在Nuget上搜下
3.安裝NLog、NLog.Config,目的是爲了看日誌,能夠清楚的知道服務在運行,能夠不要
NLog.Config簡單配置調試
<?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd" autoReload="true" throwExceptions="false" internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log"> <!-- optional, add some variables https://github.com/nlog/NLog/wiki/Configuration-file#variables --> <variable name="myvar" value="myvalue"/> <!-- See https://github.com/nlog/nlog/wiki/Configuration-file for information on customizing logging rules and outputs. --> <targets> <!-- add your targets here See https://github.com/nlog/NLog/wiki/Targets for possible targets. See https://github.com/nlog/NLog/wiki/Layout-Renderers for the possible layout renderers. --> <!-- Write events to a file with the date in the filename. --> <target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log" layout="${longdate} ${uppercase:${level}} ${message}" /> </targets> <rules> <!-- add your logging rules here --> <!-- Write all events with minimal level of Debug (So Debug, Info, Warn, Error and Fatal, but not Trace) to "f" --> <logger name="*" minlevel="Debug" writeTo="f" /> </rules> </nlog>
4.代碼實現rest
class Program { private static readonly Logger logger = LogManager.GetLogger("Program"); static void Main(string[] args) { logger.Info($"Main主程序{DateTime.Now}"); var rc = HostFactory.Run(x => //1.啓動程序 { logger.Info($"主程序{DateTime.Now}"); x.Service<TownCrier>(s => //2.設置服務類型 { s.ConstructUsing(name => new TownCrier()); //3.建立服務實例 s.WhenStarted(tc => tc.Start()); //4.啓動程序 s.WhenStopped(tc => tc.Stop()); //5.中止程序 }); x.RunAsLocalSystem(); //6.本地系統運行 x.SetDescription("超級簡單的windows服務"); //7.windows服務的描述 x.SetDisplayName("SimpleWindowsService 服務"); //8.windows服務的顯示名稱 x.SetServiceName("SimpleWindowsService"); //9.windows服務的服務名稱 }); var exitCode = (int)Convert.ChangeType(rc, rc.GetTypeCode()); //11.退出程序 Environment.ExitCode = exitCode; } } public class TownCrier { private static readonly Logger logger = LogManager.GetLogger("logTest"); readonly Timer _timer; //System.Timers不要引用錯誤 public TownCrier() { _timer = new Timer(1000) { AutoReset = true }; _timer.Elapsed += (sender, eventArgs) => { Console.WriteLine($"It is {DateTime.Now} and all is well"); logger.Info($"It is {DateTime.Now} and all is well"); }; } public void Start() { _timer.Start(); } public void Stop() { _timer.Stop(); } }
必須有啓動方法(Start)和中止方法(Stop)
4. 運行控制檯程序,也能夠是調試,效果以下
5. 程序調試運行成功,一切ok,如今能夠安裝服務了,以管理員身份運行cmd找到對應路徑,開始安裝
安裝:SimpleWindowsService.exe install
查看服務
啓動:SimpleWindowsService.exe start
服務已經運行,查看運行狀況,日誌
卸載:SimpleWindowsService.exe uninstall
能夠看到服務已經沒有了
中止:SimpleWindowsService.exe stop
中止以後能夠再次啓動,這個功能不介紹了,卸載服務的時候會調用這個方法。
安裝動做以前:Topshelf容許指定在安裝服務以前執行的操做。請注意,只有在安裝服務時纔會執行此操做。
HostFactory.New(x => { x.BeforeInstall(settings => { ... }); });
安裝動做後:Topshelf容許指定在安裝服務後執行的操做。請注意,只有在安裝服務時纔會執行此操做。
HostFactory.New(x => { x.AfterInstall(settings => { ... }); });
在卸載操做以前:Topshelf容許指定在卸載服務以前執行的操做。請注意,只有在卸載服務時纔會執行此操做。
HostFactory.New(x => { x.BeforeUninstall(() => { ... }); });
卸載操做後:Topshelf容許指定在卸載服務後執行的操做。請注意,只有在卸載服務時纔會執行此操做。
HostFactory.New(x => { x.AfterUninstall(() => { ... }); });
異常:爲服務運行時拋出的異常提供回調。此回調不是處理程序,不會影響Topshelf已提供的默認異常處理。它旨在提供對觸發外部操做,日誌記錄等的拋出異常的可見性。
HostFactory.New(x => { x.OnException(ex => { // Do something with the exception }); });
其餘的一些功能,若是須要能夠查看英文官網文檔
通常的服務都沒有這麼簡單,通常都須要定時任務,這裏的定時任務服務用到了FluentScheduler,FluentScheduler定時器介紹 ,這篇文章對FluentScheduler定時器進行了詳細的介紹,這裏再也不介紹,只展現使用。
/// <summary> /// 用MySchedule的任務定時功能 /// </summary> public class MyJob { private static readonly Logger logger = LogManager.GetLogger("MyJob"); public MyJob() { } public void Start() { logger.Info($"MySchedule啓動 {DateTime.Now}"); JobManager.Initialize(new MySchedule()); } public void Stop() { logger.Info($"MySchedule中止 {DateTime.Now}"); JobManager.Stop(); } } /// <summary> /// 定時器 /// </summary> public class MySchedule : Registry { private static readonly Logger logger = LogManager.GetLogger("MySchedule"); public MySchedule() { SetNewsSchedule(); } /// <summary> /// 設置任務 /// </summary> private void SetNewsSchedule() { //獲取連接發送郵件 Schedule(() => { logger.Info($"MySchedule運行 {DateTime.Now}"); } ).ToRunNow().AndEvery(1000).Milliseconds(); } }
控制檯程序調用
class Program { private static readonly Logger logger = LogManager.GetLogger("Program"); static void Main(string[] args) { logger.Info($"Main主程序{DateTime.Now}"); var rc = HostFactory.Run(x => //1.啓動程序 { logger.Info($"主程序{DateTime.Now}"); x.Service<MyJob>(s => //2.設置服務類型 { s.ConstructUsing(name => new MyJob()); //3.建立服務實例 s.WhenStarted(tc => tc.Start()); //4.啓動程序 s.WhenStopped(tc => tc.Stop()); //5.中止程序 }); x.RunAsLocalSystem(); //6.本地系統運行 x.SetDescription("超級簡單的windows服務"); //7.windows服務的描述 x.SetDisplayName("SimpleWindowsService 服務"); //8.windows服務的顯示名稱 x.SetServiceName("SimpleWindowsService"); //9.windows服務的服務名稱 }); var exitCode = (int)Convert.ChangeType(rc, rc.GetTypeCode()); //11.退出程序 Environment.ExitCode = exitCode; } }
服務安裝兩步走,管理員cmd,SimpleWindowsService.exe install, SimpleWindowsService.exe start
1. 寫控制檯程序
2.管理員cmd,SimpleWindowsService.exe install
3.啓動服務SimpleWindowsService.exe start
4.卸載服務SimpleWindowsService.exe uninstall