• C#使用Topshelf创建Windows服务


        一、项目创建

        创建一个控制台应用程序,项目右键->管理 NuGet 程序包->Topshelft及Topshelf.Log4Net。

        二、Topshelf配置

        一般来说,服务都会设置每隔多长时间执行一次任务,这里使用System.Threading.Timer来做个简单的日志记录,将日志写入到DebugLog文件夹下。

        2.1、Log4Net配置

        新建一个log4net.config的配置文件,在其属性的复制到输出目录项下选择始终复制。

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
      </configSections>
      <log4net>
        <!-- Console部分log输出格式的设定 -->
        <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"/>
          <!--最小锁定模型以允许多个进程可以写入同一个文件-->
          <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

        新建一个TopshelfService类:

    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; //单位:毫秒
            private readonly int periodInterval = 1000 * 5;  //单位:毫秒
    
            /// <summary>
            /// 构造函数
            /// </summary>
            public TopshelfService()
            {
                timerAsync = new Timer(AutoAsyncCallback, null, Timeout.Infinite, Timeout.Infinite);
            }
    
            /// <summary>
            /// 启动服务
            /// </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>
            /// 停止服务
            /// </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>
            /// 回调函数
            /// </summary>
            /// <param name="state"></param>
            private void AutoAsyncCallback(object state)
            {
                try
                {
                    timerAsync.Change(Timeout.Infinite, Timeout.Infinite);
                    logger.Info("AutoAsyncCallback执行开始");
                    Thread.Sleep(1000 * 10);
                }
                catch (Exception ex)
                {
                    logger.ErrorFormat("AutoAsyncCallback执行异常:{0}", ex.Message);
                }
                finally
                {
                    timerAsync.Change(dueTimeInterval, periodInterval);
                    logger.Info("AutoAsyncCallback执行结束");
                    logger.Info(Environment.NewLine);
                }
            }
        }
    }

        2.3、配置和运行宿主服务

    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());
                    //服务的描述
                    x.SetDescription("你好,Topshelf!");
                    //服务的显示名称
                    x.SetDisplayName("Hello Topshelf Service");
                    //服务名称
                    x.SetServiceName("HelloTopshelf");
                });
            }
        }
    }

        三、安装与卸载

        3.1、安装服务

        在Debug文件夹下面,创建一个"安装服务.bat"的批处理文件:

    @echo on
    
    rem 设置DOS窗口的背景颜色及字体颜色
    color 2f
    
    rem 设置DOS窗口大小 
    mode con: cols=80 lines=25
    
    @echo off
    echo 请按任意键开始安装LinkTo.Test.TopshelfService服务
    
    rem 输出空行
    echo.
    pause
    
    LinkTo.Test.TopshelfService install
    net start HelloTopShelf
    
    pause

        3.2、卸载服务

        在Debug文件夹下面,创建一个"卸载服务.bat"的批处理文件:

    @echo on
    
    rem 设置DOS窗口的背景颜色及字体颜色
    color 2f
    
    rem 设置DOS窗口大小 
    mode con: cols=80 lines=25
    
    @echo off
    echo 请按任意键开始卸载LinkTo.Test.TopshelfService服务
    
    rem 输出空行
    echo.
    pause
    
    net stop HelloTopShelf
    LinkTo.Test.TopshelfService uninstall
    
    pause

        3.3、查看服务

        在运行中输入"services.msc"进入服务,即可看到新建的HelloTopshelf服务:

        四、添加管理员权限要求

        项目右键->添加->新建项->应用程序清单文件。

        将requestedExecutionLevel节点的level设置为"requireAdministrator"。

    <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
  • 相关阅读:
    在luogu上嫖到了一张感觉很NB的图
    luoguP6028算术 题解(推柿子+整除分块+调和级数)
    notebook
    不氵的 0xd
    点分治&&DSU on tree学习笔记
    洛谷10月月赛2T1题解
    概率与期望题库题目整理
    TiDB-TiUP工具使用
    TiDB-单机学习环境部署(4.X版本)
    DB-异构数据库迁移工具
  • 原文地址:https://www.cnblogs.com/atomy/p/12893948.html
Copyright © 2020-2023  润新知