TopShelf概述
Topshelf是创建Windows服务的另一种方法,老外的一篇文章Create a .NET Windows Service in 5 steps with Topshelf通过5个步骤详细的介绍使用使用Topshelf创建Windows 服务。Topshelf是一个开源的跨平台的宿主服务框架,支持Windows和Mono,只需要几行代码就可以构建一个很方便使用的服务宿主。
不了解TopShelf的童鞋可以先百度或者根据LZ提供的链接看看TopShelf是什么以及如何使用。
在了解TopShelf为何物后,我们首先建立一个控制台项目,将我们所需要的组件一一安装。
Install-package Quartz.Net Install-package Log4Net Install-package HtmlAgility Install-package TopShelf
第一步:配置Log4Net日志
新建Log4net.config配置文件
<?xml version="1.0" encoding="utf-8" ?><configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/> </configSections> <log4net> <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender"> <!--日志路径--> <param name= "File" value= "D:\App_Log\servicelog\"/> <!--是否是向文件中追加日志--> <param name= "AppendToFile" value= "true"/> <!--log保留天数--> <param name= "MaxSizeRollBackups" value= "10"/> <!--日志文件名是否是固定不变的--> <param name= "StaticLogFileName" value= "false"/> <!--日志文件名格式为:2008-08-31.log--> <param name= "DatePattern" value= "yyyy-MM-dd".read.log""/> <!--日志根据日期滚动--> <param name= "RollingStyle" value= "Date"/> <layout type="log4net.Layout.PatternLayout"> <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n %loggername" /> </layout> </appender> <!-- 控制台前台显示日志 --> <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender"> <mapping> <level value="ERROR" /> <foreColor value="Red, HighIntensity" /> </mapping> <mapping> <level value="Info" /> <foreColor value="Green" /> </mapping> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%n%date{HH:mm:ss,fff} [%-5level] %m" /> </layout> <filter type="log4net.Filter.LevelRangeFilter"> <param name="LevelMin" value="Info" /> <param name="LevelMax" value="Fatal" /> </filter> </appender> <root> <!--(高) OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL (低) --> <level value="all" /> <appender-ref ref="ColoredConsoleAppender"/> <appender-ref ref="RollingLogFileAppender"/> </root> </log4net></configuration>
image.png
在Main方法种开始执行时,对Log4Net进行日志配置加载。
第二部:爬取信息
使用HtmlAgility,如果对此第三方库不是很理解的,可以参考LZ的爬虫系列文章,里面有对其讲解。
代码不做过多讲解,主要就是注意获取当天数据
public class JKNews { /// <summary> /// 得到今日的新闻 /// </summary> /// <returns></returns> public static List<Notice> GetTodayNews() { string[] url = { "http://www.jit.edu.cn/myNews_list_out.aspx?infotype=1", "http://www.jit.edu.cn/myNews_list_out.aspx?infotype=2" }; var web = new HtmlWeb(); web.OverrideEncoding = Encoding.GetEncoding("gb2312"); List<Notice> noticeItems = new List<Notice>(); for (int i = 0; i < url.Length; i++) { var docWeb = web.Load(url[i]); var listItems = docWeb.DocumentNode.SelectNodes("//*[@id=\"table_list\"]/li").ToList(); foreach (var item in listItems) { string href = item.SelectSingleNode("./a").Attributes["href"].Value; string title = item.InnerText; string remark = item.SelectSingleNode("./span[@class=\'puber\']").InnerText; var splitArr = remark.Split(' '); string dep = splitArr[0].TrimStart('['); string time = splitArr[1].TrimEnd(']'); noticeItems.Add(new Notice() { Href = href, Title = title, Dep = dep, Time = time }); } } return noticeItems.Where(u => Convert.ToDateTime(u.Time).Date.Equals(DateTime.Now)).ToList(); } }
比较俩日期相同
方法一:
System.Data.Entity.DbFunctions.DiffDays(cs.StartTime.Value,DateTime.Now) == 0只获取当天
方法二:
XX.StartTime.Value.Date.Equals(DateTime.Now.Date)//只获取当天
使用方法一.png
第三步:使用QuartZ建立一个定时任务
1.建立一个 ToExcelJob 继承 IJob接口,实现方法
定时方法.png
定时方法Exceute种分俩部分执行
第一部分:获取爬取后的数据
第二部分:数据保存到Excel文件
public class ToExcelJob : IJob { private static string excelPath = ConfigurationManager.AppSettings["ExcelPath"]; static readonly ILog Log = LogManager.GetLogger(typeof(ToExcelJob)); public void Execute(IJobExecutionContext context) { try { if (!Directory.Exists(excelPath)) { Directory.CreateDirectory(excelPath); } var items = JKNews.GetTodayNews(); var excel = new Excel(); excel.CreateSheet("Sheet1"); int rowIndex = 0; excel.WriteTitle(new string[] { "链接", "标题", "部门", "日期" }, 0, 0); rowIndex++; foreach (var item in items) { excel.CreateRow(0, rowIndex); excel.WriteProperty<Notice>(item, 0, rowIndex, 0); rowIndex++; } excel.SetColumnWidth(0, 0, new[] { 20, 30, 10, 10 }); string savePath = Path.Combine(excelPath, string.Format("{0}.xlsx", DateTime.Now.ToString("yyyy.MM.dd"))); excel.WriteFile(savePath); } catch (Exception ex) { Log.Error(ex.Message, ex); } } }
第四步:定制TopShelf服务类,对开始和结束进行代码描述
构造函数中使用Quartz.Net 开始进行任务的创建
首先创建一个调度器
然后创建一个任务
然后创建一个触发器,这一步中我们设置了cron为每晚8点,具体使用的大家可以看cron语法
然后将任务与触发器添加到调度器中并执行
在构造函数中对当前任务(Job)进行初始化配置,然后开放俩个方法Start和Stop让便上层调用
public class ToExcelRunner { static readonly ILog _log = LogManager.GetLogger(typeof(ToExcelRunner)); private readonly IScheduler scheduler; public ToExcelRunner() { // 创建一个调度器 scheduler = StdSchedulerFactory.GetDefaultScheduler(); //2、创建一个任务 IJobDetail job = JobBuilder.Create<ToExcelJob>().WithIdentity("job1", "group1").Build(); //3、创建一个触发器 ITrigger trigger = TriggerBuilder.Create() .WithIdentity("trigger1", "group1") .WithCronSchedule("0 0 20 ? * *") //每天晚上8点执行 .Build(); //4 将任务与触发器添加到调度器中并执行 scheduler.ScheduleJob(job, trigger); } public void Start() { try { _log.Info("服务开启"); scheduler.Start(); } catch (Exception e) { Console.WriteLine(e); throw; } } public void Stop() { _log.Info("服务结束"); scheduler.Shutdown(false); } }
第五步:TopShelf配置
s.ConstructUsing(name => new ToExcelRunner()); 服务使用ToExcelRunner
对服务的Started注册tc.Start()方法
对服务的Stopped注册tc.Stop()方法
使用日志记录,出错时候记录。
class Program { static readonly ILog _log = LogManager.GetLogger(typeof(Program)); static void Main(string[] args) { FileInfo fi = new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "\\log4net.config"); XmlConfigurator.ConfigureAndWatch(fi); try { HostFactory.Run(x => { x.Service<ToExcelRunner>(s => { s.ConstructUsing(name => new ToExcelRunner()); s.WhenStarted(tc => tc.Start()); s.WhenStopped(tc => tc.Stop()); }); x.RunAsLocalSystem(); x.SetDescription("每天晚上8点讲当日新闻保存为Excel"); x.SetDisplayName("新闻保存服务"); x.SetServiceName("新闻保存服务"); }); } catch (Exception ex) { _log.Error(ex); } } }
第六步:发布为windows服务
配置运行
没错,整个程序已经开发完了,接下来,只需要简单配置一下,即可以当服务来使用了。安装很方便:
安装:JKNoticeget.exe install
启动:JKNoticeget.exe start
卸载:JKNoticeget.exe uninstall
管理员身份进入,对应路径,注册服务
image.png
image.png
image.png
作者:HapplyFox
链接:https://www.jianshu.com/p/b18ee789fded