• 使用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

  • 相关阅读:
    形象理解ERP(转)
    禁用windows server 2008 域密码复杂性要求策略
    How to adding find,filter,remove filter on display method Form
    Windows Server 2008 R2激活工具
    How to using bat command running VS development SSRS report
    Creating Your First Mac AppGetting Started
    Creating Your First Mac AppAdding a Track Object 添加一个 Track 对象
    Creating Your First Mac AppImplementing Action Methods 实现动作方法
    Creating Your First Mac AppReviewing the Code 审查代码
    Creating Your First Mac AppConfiguring the window 设置窗口
  • 原文地址:https://www.cnblogs.com/amylis_chen/p/10303835.html
Copyright © 2020-2023  润新知