当前位置: 移动技术网 > IT编程>开发语言>c# > C#用Topshelf创建Windows服务的步骤分享

C#用Topshelf创建Windows服务的步骤分享

2020年06月23日  | 移动技术网IT编程  | 我要评论
一、项目创建创建一个控制台应用程序,项目右键->管理 nuget 程序包->topshelft及topshelf.log4net。二、topshelf配置 一般来说,服务都会设置每隔多长时

一、项目创建

创建一个控制台应用程序,项目右键->管理 nuget 程序包->topshelft及topshelf.log4net。

 

   

二、topshelf配置

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

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

总结

到此这篇关于c#用topshelf创建windows服务的文章就介绍到这了,更多相关c#用topshelf创建windows服务内容请搜索移动技术网以前的文章或继续浏览下面的相关文章希望大家以后多多支持移动技术网!

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

  • c# 面试必备线程基础知识点

    c# 面试必备线程基础知识点

    线程的知识太多,知识点有深有浅,往深的研究会涉及操作系统、cpu、内存,往浅了说就是一些语法。没有一定的知识积累,很难把线程的知识写得全面,当然我也没有这个能力... [阅读全文]
  • C#使用System.Net邮件发送功能踩过的坑

    C#使用System.Net邮件发送功能踩过的坑

    1.eazyemail邮件发送类库net 类库自带了邮件发送功能。笔者对该类库,从使用的角度进行了二次封装,nuget上可搜索eazyemail,注入容器时通过... [阅读全文]
  • C#基于Modbus三种CRC16校验方法的性能对比

    C#基于Modbus三种CRC16校验方法的性能对比

    1.背景介绍主要应用场景在物联网中,底端设备注册报文的上报,需要对报文的有效载荷(data)进行crc16的复验,验证与设备端的crc校验是否相等,如果相等,报... [阅读全文]
  • 深入谈谈C#9新特性的实际运用

    前言你一定会好奇:“老周,你去哪开飞机了?这么久没写博客了。”老周:“我买不起飞机,开了个铁矿,挖了一年半的石头。谁知铁矿垮了,压死了几条蜈蚣,什么也没挖着。”... [阅读全文]
  • C# 泛型集合的自定义类型排序的实现

    C# 泛型集合的自定义类型排序的实现

    一、泛型集合list<t>排序经sort方法之后,采用了升序的方式进行排列的。二、对自定义类型进行排序定义一个普通类:接下来,将定义的person实... [阅读全文]
  • C#开发中常用的加密解密方法汇总

    相信很多人在开发过程中经常会遇到需要对一些重要的信息进行加密处理,今天给大家分享我个人总结的一些加密算法:常见的加密方式分为可逆和不可逆两种方式可逆:rsa,a... [阅读全文]
  • C# 如何添加错误日志信息

    系统日志系统日志包含了由windows系统组件记录的事件。例如,在启动期间装入驱动程序或其他系统组件失败被记录到系统日志。要查看系统日志: 打开命令提示符。 ... [阅读全文]
  • 关于C#委托三种调用的分享使用

    关于C#委托三种调用的分享使用

    一、同步调用1、同步调用会按照代码顺序来执行2、同步调用会阻塞线程,如果是要调用一项繁重的工作(如大量io操作),可能会让程序停顿很长时间,造成糟糕的用户体验,... [阅读全文]
  • 用c# 自动更新程序

    作者:冰封一夏出处:hzhcontrols官网:首先看获取和更新的接口更新程序program.cs更新程序界面定义服务端接口,你可以用任意接口都行,我这里用we... [阅读全文]
  • c# 生成二维码的示例

    二维码是越来越流行了,很多地方都有可能是使用到。如果是静态的二维码还是比较好处理的,通过在线工具就可以直接生成一张二维码图片,比如:草料二维码。但有的时候是需要... [阅读全文]
验证码:
移动技术网