I. project creation
Create a console application. Right click the project - > manage NuGet packages - > topshelft and Topshelf.Log4Net.
II. Topshelf configuration
Generally speaking, the service will set how often to perform tasks. Here, use System.Threading.Timer to make a simple log record and write the log to the Debug\Log folder.
2.1 Log4Net configuration
Create a new log4net.config configuration file, and select "always copy" under the "copy properties to output directory" item.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> </configSections> <log4net> <!-- Console part log Setting of output format --> <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender"> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level %logger - %message %newline" /> </layout> </appender> <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender"> <file value="Log\"/> <appendToFile value="true"/> <maxSizeRollBackups value="10"/> <maximumFileSize value="1MB"/> <rollingStyle value="Date"/> <datePattern value='yyyy-MM-dd".log"' /> <staticLogFileName value="false"/> <!--Minimal locking model to allow multiple processes to write to the same file--> <param name="lockingModel" type="log4net.Appender.FileAppender+MinimalLock" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date %-5level %logger - %message %newline"/> </layout> </appender> <root> <level value="ALL" /> <appender-ref ref="ConsoleAppender" /> <appender-ref ref="RollingLogFileAppender" /> </root> </log4net> </configuration>
2.2,TopshelfService
Create a new TopshelfService class:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using Topshelf; using Topshelf.Logging; namespace LinkTo.Test.TopshelfService { public class TopshelfService : ServiceControl { private static readonly LogWriter logger = HostLogger.Get<TopshelfService>(); private static Timer timerAsync = null; private readonly int dueTimeInterval = 1000 * 5; //Unit: ms private readonly int periodInterval = 1000 * 5; //Unit: ms /// <summary> /// Constructor /// </summary> public TopshelfService() { timerAsync = new Timer(AutoAsyncCallback, null, Timeout.Infinite, Timeout.Infinite); } /// <summary> /// Start service /// </summary> /// <param name="hostControl"></param> /// <returns></returns> public bool Start(HostControl hostControl) { try { logger.Info("HelloTopshelf Start"); timerAsync.Change(dueTimeInterval, periodInterval); } catch (Exception ex) { logger.Info(ex.Message); } return true; } /// <summary> /// Out of Service /// </summary> /// <param name="hostControl"></param> /// <returns></returns> public bool Stop(HostControl hostControl) { try { logger.Info("HelloTopshelf Stop"); if (timerAsync != null) { timerAsync.Change(Timeout.Infinite, Timeout.Infinite); timerAsync.Dispose(); timerAsync = null; } } catch (Exception ex) { logger.Info(ex.Message); } return true; } /// <summary> /// Callback function /// </summary> /// <param name="state"></param> private void AutoAsyncCallback(object state) { try { timerAsync.Change(Timeout.Infinite, Timeout.Infinite); logger.Info("AutoAsyncCallback Execution start"); Thread.Sleep(1000 * 10); } catch (Exception ex) { logger.ErrorFormat("AutoAsyncCallback Execution exception:{0}", ex.Message); } finally { timerAsync.Change(dueTimeInterval, periodInterval); logger.Info("AutoAsyncCallback end of execution"); logger.Info(Environment.NewLine); } } } }
2.3 configure and run the hosting service
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Topshelf; namespace LinkTo.Test.TopshelfService { class Program { static void Main(string[] args) { HostFactory.Run(x => { x.UseLog4Net("log4net.config"); x.RunAsLocalSystem(); x.Service(settings => new TopshelfService()); //Description of the service x.SetDescription("Hello, Topshelf!"); //Display name of the service x.SetDisplayName("Hello Topshelf Service"); //Service name x.SetServiceName("HelloTopshelf"); }); } } }
III. installation and uninstallation
3.1 installation service
Under the Debug folder, create a batch file of "install service. bat":
@echo on
rem set up DOS Window background color and font color
color 2f
rem set up DOS Window size
mode con: cols=80 lines=25
@echo off
echo Press any key to start the installation LinkTo.Test.TopshelfService service
rem Output empty line
echo.
pause
LinkTo.Test.TopshelfService install
net start HelloTopShelf
pause
3.2 uninstall service
Under the Debug folder, create a batch file of "uninstall service. bat":
@echo on
rem set up DOS Window background color and font color
color 2f
rem set up DOS Window size
mode con: cols=80 lines=25
@echo off
echo Please press any key to start uninstallation LinkTo.Test.TopshelfService service
rem Output empty line
echo.
pause
net stop HelloTopShelf
LinkTo.Test.TopshelfService uninstall
pause
3.3 viewing services
Enter "services.msc" to enter the service, and you can see the new HelloTopshelf service:
IV. add administrator authority requirements
Right click item - > Add - > New Item - > application manifest file.
Set the level of the requestedExecutionLevel node to requireAdministrator.
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />