C ා use Topshelf to create Windows service

Keywords: C# xml encoding

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" />

Posted by HA7E on Fri, 15 May 2020 07:26:46 -0700