這幾天在弄一個項目,須要定時抓取一些數據,當時也想直接用timer算了。由於以前也弄過這樣的項目,可是一想,已經用過了,再去使用同一種思路,未免太乏味了。就換了一種新玩法。這裏將以前看到的一篇文章中提出的一個思路,在這個項目中實踐了一下,發現樂在其中。html
[轉]C#建立服務及使用程序自動安裝服務,.NET建立一個便是可執行程序又是Windows服務的exewindows
這篇文章,給了一種好玩的方式,而且本身也實踐了一下,並且也確確實實在項目中用到了。app
簡單一個demo,先熟悉如何使用Quartz.NETide
關於如何windows service的內容,這裏再也不贅述,一搜一大堆。函數
首先引入lib中的dll。post
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Diagnostics; 6 using System.Linq; 7 using System.ServiceProcess; 8 using System.Text; 9 using System.Threading.Tasks; 10 using Quartz; 11 using Quartz.Job; 12 using Common.Logging; 13 using Quartz.Impl; 14 using Statistics.WindowService.JobManager; 15 using System.Configuration; 16 namespace Statistics.WindowService 17 { 18 /// <summary> 19 /// 數據同步windows服務 20 /// </summary> 21 public partial class SyncDataService : ServiceBase 22 { 23 private readonly ILog logger; 24 private IScheduler scheduler; 25 //時間間隔 26 private readonly string StrCron = ConfigurationManager.AppSettings["cron"] == null ? "* 10 * * * ?" : ConfigurationManager.AppSettings["cron"]; 27 /// <summary> 28 ///構造函數 29 /// </summary> 30 public SyncDataService() 31 { 32 InitializeComponent(); 33 //初始化 34 logger = LogManager.GetLogger(this.GetType()); 35 //新建一個調度器工工廠 36 ISchedulerFactory factory = new StdSchedulerFactory(); 37 //使用工廠生成一個調度器 38 scheduler = factory.GetScheduler(); 39 40 } 41 /// <summary> 42 /// 服務開啓 43 /// </summary> 44 /// <param name="args"></param> 45 protected override void OnStart(string[] args) 46 { 47 if (!scheduler.IsStarted) 48 { 49 //啓動調度器 50 scheduler.Start(); 51 //新建一個任務 52 IJobDetail job = JobBuilder.Create<AppLogJob>().WithIdentity("AppLogJob", "AppLogJobGroup").Build(); 53 //新建一個觸發器 54 ITrigger trigger = TriggerBuilder.Create().StartNow().WithCronSchedule(StrCron).Build(); 55 //將任務與觸發器關聯起來放到調度器中 56 scheduler.ScheduleJob(job, trigger); 57 logger.Info("Quarzt 數據同步服務開啓"); 58 } 59 60 } 61 /// <summary> 62 /// 服務中止 63 /// </summary> 64 protected override void OnStop() 65 { 66 if (!scheduler.IsShutdown) 67 { 68 scheduler.Shutdown(); 69 } 70 } 71 /// <summary> 72 /// 暫停 73 /// </summary> 74 protected override void OnPause() 75 { 76 scheduler.PauseAll(); 77 base.OnPause(); 78 } 79 /// <summary> 80 /// 繼續 81 /// </summary> 82 protected override void OnContinue() 83 { 84 scheduler.ResumeAll(); 85 base.OnContinue(); 86 } 87 } 88 }
時間間隔採用的是cron表達式,關於cron表達式的定義,能夠參考這篇文章:http://www.cnblogs.com/linjiqin/archive/2013/07/08/3178452.htmlui
定義Job,能夠經過自定義類,而且實現IJob接口,能夠很方便的定義一個任務,而且也很是容易擴展。this
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using Quartz; 7 using Quartz.Job; 8 namespace Statistics.WindowService.JobManager 9 { 10 /// <summary> 11 /// 同步applog任務 12 /// </summary> 13 public class AppLogJob:IJob 14 { 15 //使用Common.Logging.dll日誌接口實現日誌記錄 16 private static readonly Common.Logging.ILog logger = Common.Logging.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 17 /// <summary> 18 /// 定時任務執行 19 /// </summary> 20 /// <param name="context"></param> 21 public void Execute(IJobExecutionContext context) 22 { 23 try 24 { 25 logger.Info("AppLogJob 任務開始運行"); 26 27 for (int i = 0; i < 10; i++) 28 { 29 logger.InfoFormat("AppLogJob 正在運行{0}", i); 30 } 31 32 logger.Info("AppLogJob 任務運行結束"); 33 } 34 catch (Exception ex) 35 { 36 logger.Error("AppLogJob 運行異常", ex); 37 } 38 } 39 } 40 }
修改windows 服務的入口程序:url
1 using System; 2 using System.Collections.Generic; 3 using System.Diagnostics; 4 using System.Linq; 5 using System.ServiceProcess; 6 using System.Text; 7 using System.Threading.Tasks; 8 9 namespace Statistics.WindowService 10 { 11 static class Program 12 { 13 /// <summary> 14 /// 應用程序的主入口點。 15 /// </summary> 16 static void Main(string[] args) 17 { 18 //若是傳遞了參數 s 就啓動服務 19 if (args.Length > 0 && args[0] == "s") 20 { 21 ServiceBase[] ServicesToRun; 22 ServicesToRun = new ServiceBase[] { new SyncDataService() }; 23 ServiceBase.Run(ServicesToRun); 24 } 25 else 26 { 27 Console.WriteLine("這是Windows應用程序"); 28 Console.WriteLine("請選擇,[1]安裝服務 [2]卸載服務 [3]退出"); 29 var rs = int.Parse(Console.ReadLine()); 30 string strServiceName = "syncService[數據同步服務]"; 31 switch (rs) 32 { 33 case 1: 34 //取當前可執行文件路徑,加上"s"參數,證實是從windows服務啓動該程序 35 var path = Process.GetCurrentProcess().MainModule.FileName + " s"; 36 Process.Start("sc", "create " + strServiceName + " binpath= \"" + path + "\" displayName= " + strServiceName + " start= auto"); 37 Console.WriteLine("安裝成功"); 38 Console.Read(); 39 break; 40 case 2: 41 Process.Start("sc", "delete " + strServiceName + ""); 42 Console.WriteLine("卸載成功"); 43 Console.Read(); 44 break; 45 case 3: break; 46 } 47 48 } 49 50 51 } 52 } 53 }
修改app.configspa
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/> <sectionGroup name="common"> <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging"/> </sectionGroup> </configSections> <common> <logging> <factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4net"> <arg key="configType" value="INLINE"/> </factoryAdapter> </logging> </common> <log4net> <appender name="InfoFileAppender" type="log4net.Appender.RollingFileAppender"> <file value="log/" /> <appendToFile value="true" /> <param name="DatePattern" value="yyyyMMdd".txt"" /> <rollingStyle value="Date" /> <maxSizeRollBackups value="100" /> <maximumFileSize value="1024KB" /> <staticLogFileName value="false" /> <Encoding value="UTF-8" /> <filter type="log4net.Filter.LevelRangeFilter"> <param name="LevelMin" value="INFO" /> <param name="LevelMax" value="INFO" /> </filter> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date %-5level %logger - %message%newline" /> </layout> </appender> <appender name="ErrorFileAppender" type="log4net.Appender.RollingFileAppender"> <file value="log/error.txt" /> <appendToFile value="true" /> <rollingStyle value="Size" /> <maxSizeRollBackups value="100" /> <maximumFileSize value="10240KB" /> <staticLogFileName value="true" /> <Encoding value="UTF-8" /> <filter type="log4net.Filter.LevelRangeFilter"> <param name="LevelMin" value="WARN" /> <param name="LevelMax" value="FATAL" /> </filter> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date %-5level %logger - %message%newline" /> </layout> </appender> <root> <level value="INFO" /> <appender-ref ref="InfoFileAppender" /> <appender-ref ref="ErrorFileAppender" /> </root> </log4net> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> <appSettings> <!--每五分鐘執行一次--> <add key="cron" value="* 5 * * * ?"/> </appSettings> </configuration>
弄這個demo的目的是先讓Quartz.net
找到bin目錄下的exe文件,右鍵以管理員身份運行。
查看生成的log日誌
1 2015-05-22 10:43:23,115 INFO Quartz.Impl.StdSchedulerFactory - Default Quartz.NET properties loaded from embedded resource file 2 2015-05-22 10:43:23,147 INFO Quartz.Impl.StdSchedulerFactory - Using default implementation for object serializer 3 2015-05-22 10:43:23,168 INFO Quartz.Impl.StdSchedulerFactory - Using default implementation for ThreadExecutor 4 2015-05-22 10:43:23,181 INFO Quartz.Core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: Quartz.Core.SchedulerSignalerImpl 5 2015-05-22 10:43:23,181 INFO Quartz.Core.QuartzScheduler - Quartz Scheduler v.2.0.0.400 created. 6 2015-05-22 10:43:23,184 INFO Quartz.Simpl.RAMJobStore - RAMJobStore initialized. 7 2015-05-22 10:43:23,186 INFO Quartz.Core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.0.0.400) 'DefaultQuartzScheduler' with instanceId 'NON_CLUSTERED' 8 Scheduler class: 'Quartz.Core.QuartzScheduler' - running locally. 9 NOT STARTED. 10 Currently in standby mode. 11 Number of jobs executed: 0 12 Using thread pool 'Quartz.Simpl.SimpleThreadPool' - with 10 threads. 13 Using job-store 'Quartz.Simpl.RAMJobStore' - which does not support persistence. and is not clustered. 14 15 2015-05-22 10:43:23,186 INFO Quartz.Impl.StdSchedulerFactory - Quartz scheduler 'DefaultQuartzScheduler' initialized 16 2015-05-22 10:43:23,187 INFO Quartz.Impl.StdSchedulerFactory - Quartz scheduler version: 2.0.0.400 17 2015-05-22 10:43:23,191 INFO Quartz.Core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started. 18 2015-05-22 10:43:23,250 INFO Statistics.WindowService.SyncDataService - Quarzt 數據同步服務開啓 19 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任務開始運行 20 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行0 21 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行1 22 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行2 23 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行3 24 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行4 25 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行5 26 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行6 27 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行7 28 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行8 29 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行9 30 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任務運行結束 31 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任務開始運行 32 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行0 33 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行1 34 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行2 35 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行3 36 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行4 37 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行5 38 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行6 39 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行7 40 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行8 41 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行9 42 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任務運行結束 43 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任務開始運行 44 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行0 45 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行1 46 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行2 47 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行3 48 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行4 49 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行5 50 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行6 51 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行7 52 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行8 53 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行9 54 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任務運行結束 55 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任務開始運行 56 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行0 57 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行1 58 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行2 59 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行3 60 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行4 61 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行5 62 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行6 63 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行7 64 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行8 65 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行9 66 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任務運行結束 67 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任務開始運行 68 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行0 69 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行1 70 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行2 71 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行3 72 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行4 73 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行5 74 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行6 75 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行7 76 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行8 77 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行9 78 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任務運行結束 79 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任務開始運行 80 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行0 81 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行1 82 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行2 83 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行3 84 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行4 85 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行5 86 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行6 87 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行7 88 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行8 89 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在運行9 90 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任務運行結束 91 2015-05-22 10:49:17,048 INFO Quartz.Core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutting down. 92 2015-05-22 10:49:17,048 INFO Quartz.Core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED paused. 93 2015-05-22 10:49:17,052 INFO Quartz.Core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED Shutdown complete.
內容很簡單。只是將以前在博客園看到的一種方式在項目中實踐了一下。
參考文章:
http://www.cnblogs.com/lzrabbit/archive/2012/04/15/2448326.html