zoukankan      html  css  js  c++  java
  • 使用Topshelf创建Windows服务

    概述

    Topshelf是创建Windows服务的另一种方法,老外的一篇文章Create a .NET Windows Service in 5 steps with Topshelf通过5个步骤详细的介绍使用使用Topshelf创建Windows 服务。Topshelf是一个开源的跨平台的宿主服务框架,支持Windows和Mono,只需要几行代码就可以构建一个很方便使用的服务宿主。

    引用安装

    1、官网:http://topshelf-project.com/  这里面有详细的文档及下载

    2、Topshelf的代码托管在 http://github.com/topshelf/Topshelf/downloads   ,可以在这里下载到最新的代码。

    3、新建一个项目,只需要引用Topshelf.dll 即可,为了日志输出显示,建议也同时引用Topshelf.Log4Net。程序安装命令

    • Install-Package Topshelf
    • Install-Package Topshelf.Log4Net

    使用

    官网文档给过来的例子非常简单,直接使用即可以跑起来,官网文档地址:http://docs.topshelf-project.com/en/latest/configuration/quickstart.html

    public class TownCrier
    {
        readonly Timer _timer;
        public TownCrier()
        {
            _timer = new Timer(1000) {AutoReset = true};
            _timer.Elapsed += (sender, eventArgs) => Console.WriteLine("It is {0} and all is well", DateTime.Now);
        }
        public void Start() { _timer.Start(); }
        public void Stop() { _timer.Stop(); }
    }
    
    public class Program
    {
        public static void Main()
        {
            HostFactory.Run(x =>                                 //1
            {
                x.Service<TownCrier>(s =>                        //2
                {
                   s.ConstructUsing(name=> new TownCrier());     //3
                   s.WhenStarted(tc => tc.Start());              //4
                   s.WhenStopped(tc => tc.Stop());               //5
                });
                x.RunAsLocalSystem();                            //6
    
                x.SetDescription("Sample Topshelf Host");        //7
                x.SetDisplayName("Stuff");                       //8
                x.SetServiceName("Stuff");                       //9
            });                                                  //10
        }
    }

    程序跑起来后,每隔一秒钟有输出,看到的效果如下:

    配置运行

    没错,整个程序已经开发完了,接下来,只需要简单配置一下,即可以当服务来使用了。安装很方便:

    安装:TopshelfDemo.exe install
    启动:TopshelfDemo.exe start
    卸载:TopshelfDemo.exe uninstall

    安装成功后,接下来,我们就可以看到服务里多了一个服务:

    扩展说明

    Topshelf Configuration 简单配置

    官方文档,对HostFactory 里面的参数做了详细的说明:http://docs.topshelf-project.com/en/latest/configuration/config_api.html ,下面只对一些常用的方法进行简单的解释:

    我们将上面的程序代码改一下:

                HostFactory.Run(x =>                                 //1
                {
                    x.Service<TownCrier>(s =>                        //2
                    {
                        s.ConstructUsing(name => new TownCrier());     //配置一个完全定制的服务,对Topshelf没有依赖关系。常用的方式。
                //the start and stop methods for the service
                        s.WhenStarted(tc => tc.Start()); //4 s.WhenStopped(tc => tc.Stop()); //5 }); x.RunAsLocalSystem(); // 服务使用NETWORK_SERVICE内置帐户运行。身份标识,有好几种方式,如:x.RunAs("username", "password"); x.RunAsPrompt(); x.RunAsNetworkService(); 等 x.SetDescription("Sample Topshelf Host服务的描述"); //安装服务后,服务的描述 x.SetDisplayName("Stuff显示名称"); //显示名称 x.SetServiceName("Stuff服务名称"); //服务名称 });

    重装安装运行后:

     通过上面,相信大家都很清楚 SetDescription、SetDisplayName、SetServiceName区别。不再细说。

    Service Configuration 服务配置

    Topself的服务一般有主要有两种使用模式。

    一、简单模式。继承ServiceControl接口,实现该接口即可。

    实例:

    namespace TopshelfDemo
    {
        public class TownCrier : ServiceControl
        {
            private Timer _timer = null;
            readonly ILog _log = LogManager.GetLogger(typeof(TownCrier));
            public TownCrier()
            {
                _timer = new Timer(1000) { AutoReset = true };
                _timer.Elapsed += (sender, eventArgs) => _log.Info(DateTime.Now);
    
            }
            public bool Start(HostControl hostControl)
            {
                _log.Info("TopshelfDemo is Started");
                _timer.Start();
                return true;
            }
    
            public bool Stop(HostControl hostControl)
            {
                throw new NotImplementedException();
            }
        }
        class Program
        {
            public static void Main(string[] args)
            {
                var logCfg = new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "log4net.config");
                XmlConfigurator.ConfigureAndWatch(logCfg);
    
                HostFactory.Run(x =>
                {
                    x.Service<TownCrier>();
                    x.RunAsLocalSystem();
    
                    x.SetDescription("Sample Topshelf Host服务的描述");
                    x.SetDisplayName("Stuff显示名称");
                    x.SetServiceName("Stuff服务名称");
                });
            }
        }
    }

    二、常用模式。

    实例:

    namespace TopshelfDemo
    {
        public class TownCrier
        {
            private Timer _timer = null;
            readonly ILog _log = LogManager.GetLogger(
                                             typeof(TownCrier));
            public TownCrier()
            {
                _timer = new Timer(1000) { AutoReset = true };
                _timer.Elapsed += (sender, eventArgs) => _log.Info(DateTime.Now);
            }
            public void Start(){ _timer.Start();}
            public void Stop() { _timer.Stop(); }
        }
    
        class Program
        {
            public static void Main(string[] args)
            {
                var logCfg = new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "log4net.config");
                XmlConfigurator.ConfigureAndWatch(logCfg);
    
                HostFactory.Run(x =>
                {
                    x.Service<TownCrier>(s =>
                    {
                        s.ConstructUsing(name => new TownCrier());
                        s.WhenStarted(tc => tc.Start());              
                        s.WhenStopped(tc => tc.Stop());             
                    });
                    x.RunAsLocalSystem();
    
                    x.SetDescription("Sample Topshelf Host服务的描述");
                    x.SetDisplayName("Stuff显示名称");
                    x.SetServiceName("Stuff服务名称");
                });
            }
        }
    }

    两种方式,都使用了Log4Net,相关配置:

    <?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_Dataservicelog"/>
          <!--是否是向文件中追加日志-->
          <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&quot;.log&quot;"/>
          <!--日志根据日期滚动-->
          <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>

     推荐使用第二种常用模式。

    源代码下载:http://download.csdn.net/detail/jys1216/8860119

    下一篇,将介绍:Topself与Quartz.net的结合使用,结合起来使用,真是一个很完美的后台作业调试服务。

  • 相关阅读:
    Mysql 多字段去重
    一个不错的PHP二维数组排序函数简单易用存用
    关于威富通的微信扫码支付处理思路和流程
    牛顿迭代法求解平方根
    impex 语法
    屏幕取词技术实现原理与关键源码
    支持向量机通俗导论(理解SVM的三层境界)
    用 Chrome 扩展实现修改
    可编辑表格
    在浏览器右键添加自定义菜单
  • 原文地址:https://www.cnblogs.com/jys509/p/4614975.html
Copyright © 2011-2022 走看看