1. 程式人生 > 程式設計 >C#用Topshelf建立Windows服務的步驟分享

C#用Topshelf建立Windows服務的步驟分享

一、專案建立

建立一個控制檯應用程式,專案右鍵->管理 NuGet 程式包->Topshelft及Topshelf.Log4Net。

C#用Topshelf建立Windows服務的步驟分享

C#用Topshelf建立Windows服務的步驟分享

二、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服務:

C#用Topshelf建立Windows服務的步驟分享

四、新增管理員許可權要求

專案右鍵->新增->新建項->應用程式清單檔案。

C#用Topshelf建立Windows服務的步驟分享

將requestedExecutionLevel節點的level設定為"requireAdministrator"。

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

總結

到此這篇關於C#用Topshelf建立Windows服務的文章就介紹到這了,更多相關C#用Topshelf建立Windows服務內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!