Create a Windows service components to use step by step Topshelf

We first introduce the benefits of using it, the following discussion reference from other great God.

topshelf is a way to create windows services, compared to the original implement ServiceBase, Install.Installer more simple and convenient, we only need a few lines of code to achieve the development of windows services.

topshelf support itself on windows and linux mono deployed at installation, it is also open source.

topshelf relatively speaking native, debugging more convenient, the console may be in the form of direct f5 debugging during development, deployment as a service of publishing command.

Still another feature is useful supports multiple instances of the deployment, so that the service can be deployed in a plurality of opposing a machine. Similar tools have instsrv and srvany.

There is a multi-instance advantage is that disaster recovery, when more than one service deployment, so that any instance of a service hung up, the remaining can continue.

Examples may be a plurality of standby mode, the standby main hanging service will be performed. Can also be a way to achieve load balancing, multi-instance process to seize the lock or distributed lock, who gets who performed.

 

The first to write specific steps:

// Create a new console application
// use Nuget installation Topshelf, select the latest version usable
// use Nuget installation NLog and NLog.config, select the latest version can be used for printing logs Nlog requires a configuration file, see NLog .config
// initial configuration file, create AppConfigHelper classes, inheritance ConfigurationSection (need to reference the System.Configuration assembly)
// perfect App.Config configuration file, read App.Config profile, specific view AppConfigHelper class
// create a registration service class TopshelfRegistService, initialization Topshelf registration
// our goal is simply to make a print service log file
// compile and build the project into the bin \ Debug directory to find xxx.exe execute the install command, Windows service was born
// Note: If you are prompted to start as an administrator appeared, re-start as administrator cmd

// followed directly on the code and screenshots

 

 

 

 Uninstall the service:

When we start the service successfully print out the log shows every success

Program structure is very simple, as shown below:

 Next, we direct the implementation code, I will give the order follow these steps:

1, Program main program code

 1 namespace ProcessPrintLogService
 2 {
 3     class Program
 4     {
 5         public static readonly Logger log = LogManager.GetCurrentClassLogger();
 6         private static readonly AppConfigHelper config = AppConfigHelper.Initity();
 7         static void Main(string[] args)
 8         {
 9             TopshelfRegistService.Regist(config, true);
10         }
11     }
12 }

2.AppConfigHelper class for reading the configuration file, use the configuration files the way you can make the post-service applied to multiple applications

namespace ProcessPrintLogService 
{ 
    public  class AppConfigHelper: the ConfigurationSection 
    { 
        Private  static AppConfigHelper _AppConfig = null ;
         Private  static  Readonly  Object LockThis = new new  Object (); 

        ///  <Summary> 
        /// acquire the content acquisition section configured current node
         // singleton mode
         ///  </ Summary> 
        ///  <Returns> </ Returns> 
        public  static AppConfigHelper Initity () 
        { 
            IF (_AppConfig == null) 
            { 
                Lock (LockThis) 
                { 
                    IF (_AppConfig == null ) 
                    { 
                        // Get app.config file section configuration node 
                        _AppConfig = (AppConfigHelper) ConfigurationManager.GetSection ( " AppConfigHelper " ); 
                    } 
                } 
            } 
            return _AppConfig; 
        } 


        // create a AppConfigHelper node
         // attribute are: ServiceName, Desc and so on ....
         // introduce here properties tab: ConfigurationProperty it can get value from value property name in the configuration file
         //可以参考文章https://www.cnblogs.com/liunlls/p/configuration.html


        /// <summary>
        /// 服务名称
        /// </summary>
        [ConfigurationProperty("ServiceName", IsRequired = true)]
        public string ServiceName
        {
            get { return base["ServiceName"].ToString(); }
            internal set { base["ServiceName"] = value; }
        }

        /// <summary>
        /// 描述
        /// </summary>
        [ConfigurationProperty("Desc", IsRequired = true)]
        public string Description
        {
            get { return base["Desc"].ToString(); }
            internal set { base["Desc"] = value; }
        }

    }
}

3.Topshelf component registration service

namespace ProcessPrintLogService 
{ 
    ///  <Summary> 
    /// topshelf component registration service
     ///  </ Summary> 
    Internal  class TopshelfRegistService 
    { 
        ///  <Summary> 
        /// Register inlet
         ///  </ Summary> 
        ///  <param name = "config"> profile </ param> 
        ///  <param name = "isreg"> is registered </ param> 
        public  static  void the Regist (config AppConfigHelper, BOOL isreg = to false ) 
        { 
            // herein may be used HostFactory .Run () instead of HostFactory.New ()
            var Host = HostFactory.New (X => 
            { 
                x.Service <QuartzHost> (S => 
                { 
                    // by new QuartzHost () to build a service instance 
                    s.ConstructUsing (name => new new QuartzHost ());
                     // if the service What are executed after starting 
                    s.WhenStarted (tc => tc.Start ());
                     // What to perform when the service stops 
                    s.WhenStopped (tc => tc.Stop ());
                     // execute what services will be suspended when the 
                    s. WhenPaused (w => w.Stop ());
                     // What to perform when the service continues
                    s.WhenContinued (W => w.Start ()); 
                }); 
                IF ! (isreg) return ; // default not register 

                @ service account with the local system to run 
                x.RunAsLocalSystem ();
                 // description information and services 
                x.SetDescription (config.Description);
                 // display the name of the service 
                x.SetDisplayName (config.ServiceName);
                 // name of the service (best not to include spaces or characters with spaces attributes) Windows service name can not be repeated. 
                x.SetServiceName (config.ServiceName); 
            }); 
            host.Run ();   // Start Service If HostFactory.Run () method is not required 
        }
    }

    ///  <Summary> 
    /// custom service
     ///  </ Summary> 
    Internal  class QuartzHost 
    { 
        public  Readonly Logger LogManager.GetLogger = log ( " QuartzHost " ); 

        public QuartzHost () 
        { 
            var -Service = AppConfigHelper.Initity () ; 
        } 

        // service start 
        public  void start () 
        { 
            the try 
            { 
                Task.Run (() => 
                { 
                    log.info ($ ' service start success! "); 
                }); 
            } 
            The catch (Exception EX) 
            { 
                Task.Run (() => 
                { 
                    log.Fatal (EX, $ " service start failed error message:! {0} " , EX); 
                }); 
                the throw ; 
            } 
        } 

        // service stops 
        public  void the stop () 
        { 
            Task.Run (() => 
            { 
                log.Trace ( " service end Job " ); 
            });  
        }
    } 

}

4.App.config profile

<? xml Version = " 1.0 " encoding = " UTF-8 " ?> 
<the Configuration> 

  <-! This node must be placed in the uppermost -> 
  <configSections> 
    <Section name = " AppConfigHelper " of the type = " ProcessPrintLogService. AppConfigHelper, ProcessPrintLogService " /> 
  </ configSections> 

  <-! TopSelf service configuration file -> 
  < AppConfigHelper 
    ServiceName = " Process_PrintLogService " 
    Asc = " log Print services " 
    />

  <! - database connection string ->
  <connectionStrings>
    <add name="ConnectionString" connectionString="123123123"/>
  </connectionStrings>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
  </startup>
</configuration>

5.Nlog.config log configuration file

<? xml Version = " 1.0 " encoding = " UTF-8 " ?> 
<nlog xmlns = " http://www.nlog-project.org/schemas/NLog.xsd " 
      xmlns: xsi = " HTTP: // the WWW .w3.org / 2001 / XMLSchema-instance " > 
  <targets> 
    <- of the type =! " file | console " property is set the log output destination is the " file " (file) or " console " (console) -> 
    <-! fileName = " $ {} the basedir / logs / ShortDate} {$ / $ {Level} / {$} .log CallSite "Set the path and name of journaling file -> " 
    <-! Layout =${longdate} ${level} ${callsite}:${message}" 设置日志输出格式-->
    <target name="t1"
            type="File"
            fileName="${basedir}/logs/${shortdate}/${level} ${callsite}.log"
            layout="${longdate} ${level} ${callsite}:${message}"
          archiveAboveSize="3145728"
          archiveNumbering="Rolling"
          concurrentWrites="false"
          keepFileOpen = " to true " 
          maxArchiveFiles = " 20 is " 
    /> 

    <-! to the console -> 
    <target name = " T2 " type = " Console " layout = " $ {$ {Level of longdate}}} $ {CallSite : the message $ {} " /> 
  </ Targets> 

  <rules> 
    ! <- * If fill, then all of the Logger will use this rule, the log information at all levels are written to" t1 "and" t2 " these two goals in -> 
    <Logger name = " * " writeTo = " T1, T2 " />
  </rules>
</nlog>

That's all the code examples of this, this you may have a problem that I want to perform my regular job? For example, a few perform every day, or once every few minutes to perform, and so on, then how do we do it?

The answer is to use: Quartz.net, then I will use Quartz.net achieve the above timing tasks.

references:

https://www.jianshu.com/p/f2365e7b439c

 

Guess you like

Origin www.cnblogs.com/peterzhang123/p/11894837.html