使用.netcore部署window服务完成过程(使用nssm,Topshelf)
一,新建.netcore控制台应用程序。本文使用.netcore2.2版本,结构如下
二,negut引用Topshelf.Log4Net,Topshelf
三,代码如下:
1>Program.cs
using log4net.Config; using System; using System.IO; using Topshelf; namespace TopShelfWs { class Program { static void Main(string[] args) { HostFactory.Run(x => { x.Service<ServiceHandler>(s => { s.ConstructUsing(name => new ServiceHandler()); s.WhenStarted(tc => tc.Start()); s.WhenStopped(tc => tc.Stop()); }); x.RunAsLocalSystem(); x.SetDescription("Sample Topshelf Host"); x.SetDisplayName("TopshelfWs"); x.SetServiceName("TopshelfWs"); x.UseLog4Net("log4net.config"); }); } } }
2>ServiceHandler.cs
using log4net; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.ServiceProcess; using System.Text; using System.Timers; namespace TopShelfWs { partial class ServiceHandler { readonly Timer _timer; readonly ILog _log = LogManager.GetLogger(typeof(ServiceHandler)); public ServiceHandler() { _timer = new Timer(1000) { AutoReset = true }; _timer.Elapsed += new ElapsedEventHandler(OnTick); _timer.Elapsed += (sender, eventArgs) => Console.WriteLine("当前时间:", DateTime.Now); } protected virtual void OnTick(object sender, ElapsedEventArgs e) { _log.Debug("Tick:" + DateTime.Now.ToLongTimeString()); } public void Start() { _log.Info("Service is Started"); _timer.Start(); } public void Stop() { _log.Info("Service is Stopped"); _timer.Stop(); } } }
3>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"> <!--定义文件存放位置--> <file value="log\\"/> <!--是否追加到文件,默认为true,通常无需设置--> <appendToFile value="true"/> <!--多线程时采用最小锁定--> <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/> <!--变换的形式为日志大小--> <!--这种情况下MaxSizeRollBackups和maximumFileSize的节点设置才有意义--> <!--<rollingStyle value="Size"/>--> <!--每天记录的日志文件个数,与maximumFileSize配合使用--> <!--<MaxSizeRollBackups value="10"/>--> <!--每个日志文件的最大大小--> <!--可用的单位:KB|MB|GB--> <!--不要使用小数,否则会一直写入当前日志--> <!--<maximumFileSize value="2MB"/>--> <!--变换的形式为日期,这种情况下每天只有一个日志--> <!--此时MaxSizeRollBackups和maximumFileSize的节点设置没有意义--> <rollingStyle value="Date"/> <!--每分钟写一个文件--> <!--<datePattern value="yyyyMMdd-HHmm" />--> <!--日期的格式,每天换一个文件记录,如不设置则永远只记录一天的日志,需设置--> <datePattern value="yyyyMMdd\\HH'.txt'"/> <staticLogFileName value="false"/> <param name="MaxSizeRollBackups" value="100"/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%newline %n记录时间:%date %n描述:%message"/> <!--<conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别: %-5level %n出错类:%logger property: [%property{NDC}] - %n错误描述:%message%newline %n"/>--> </layout> </appender> <!--定义输出到MySql中--> <!--注意 Mysql.data 引用属性中复制本地一定要选True--> <appender name="AdoNetAppender_MySql" type="log4net.Appender.AdoNetAppender"> <bufferSize value="100"/> <param name="ConnectionType" value="MySql.Data.MySqlClient.MySqlConnection, MySql.Data"/> <param name="ConnectionString" value="server=localhost;database=test;uid=root;pwd=maocaiming;"/> <commandText value="INSERT INTO mylog111 (log_datetime,log_thread,log_level,log_logger,log_message,Exception) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)"/> <parameter> <parameterName value="@log_date"/> <dbType value="DateTime"/> <layout type="log4net.Layout.RawTimeStampLayout"/> </parameter> <parameter> <parameterName value="@thread"/> <dbType value="String"/> <size value="255"/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%thread"/> </layout> </parameter> <parameter> <parameterName value="@log_level"/> <dbType value="String"/> <size value="50"/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%level"/> </layout> </parameter> <parameter> <parameterName value="@logger"/> <dbType value="String"/> <size value="255"/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%logger"/> </layout> </parameter> <parameter> <parameterName value="@message"/> <dbType value="String"/> <size value="4000"/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%message"/> </layout> </parameter> <parameter> <parameterName value="@exception"/> <dbType value="String"/> <size value="2000"/> <layout type="log4net.Layout.ExceptionLayout"/> </parameter> </appender> <root> <!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF--> <!--比如定义级别为INFO,则INFO级别向下的级别,比如DEBUG日志将不会被记录--> <!--如果没有定义LEVEL的值,则缺省为DEBUG--> <level value="ALL"/> <!--文件形式记录日志--> <appender-ref ref="RollingLogFileAppender"/> <!--<appender-ref ref="AdoNetAppender_MySql"/>--> </root> </log4net> </configuration>
四,发布项目配置
五,生成成功后,我们使用nssm部署服务
下载nssm,下载地址http://www.nssm.cc/download
六,使用命令启动nssm
cd C:\Users\May\Desktop\nssm-2.24\win64
nssm install TopShelfWs
七,打开如下:
八,选择生成的文件目录:(C:\Users\May\Desktop\ws)
九,生成服务
右键启动服务,即可看到生成的日志文件
十,移除服务: nssm remove TopShelfWs//删除创建的TopShelfWs服务
十一,刷新后发现生成的服务已经删除
PS :如果启用服务出现如下图问题:
原因是nssm install TopShelfWs 这个启用服务的名字跟 代码中 x.SetServiceName("TopShelfWs"); 相同,或者这句话被注释掉,总结问题原因:1,名字相同(TopShelfWs),2,代码被注释掉
参考博客
https://www.cnblogs.com/uptothesky/p/5318420.html
http://www.cnblogs.com/hai-cheng/p/8670395.html