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

    Winndows Service 是一种可随 Windows 操作系统启动而启动的,在后台运行的,通常不和用户产生交互的程序。它无法通过双击来运行,类似于 Unix 守护进程(daemon processes),当用户注销时它也不会停止。

    Windows 服务由三部分组成:

    • 一个服务可执行文件;
    • 一个服务控制程序(SCP);
    • 服务控制管理器(SCM),负责在 HKLM"SYSTEM"CurrentControlSet"Services 下创建服务键值。用户可通过 SCP 控制服务的启动、停止、暂停等,SCP 会通过 SCM 调用服务程序

    开发一个Windows服务通常也比较简单,在开发的时候我们期望以命令行方式运行,想对Windows服务有更多的控制,就有一个Windows服务框架TopShelf 可以满足,使用这个框架要求你使用一个IoC容器,在框架中使用的是common service locator 接口,可以根据你的喜好去选择你自己中意的IoC容器。

    TopShelf的基本介绍可以参看Dru Sellers 的介绍性文章 TopShelf。下面的代码就是创建了一个Windows服务:

    using System;
        using System.Collections.Generic;
        using System.IO;
        using System.Timers;
        using log4net.Config;
        using Microsoft.Practices.ServiceLocation;
        using StructureMap;
        using Topshelf;
        using Topshelf.Configuration;

        internal class Program
        {
            static void Main(string[] args)
            {
                XmlConfigurator.ConfigureAndWatch(new FileInfo(".\\log4net.config"));
                IRunConfiguration cfg = RunnerConfigurator.New(x =>
                {
                    x.AfterStoppingTheHost(h => { Console.WriteLine("AfterStop called invoked, services are stopping"); });

                     x.SetDescription("Sample Topshelf Host");
                    x.SetDisplayName("Stuff");
                    x.SetServiceName("stuff");

                    x.ConfigureServiceInIsolation<TownCrier>("tc", s =>
                    {
                        s.CreateServiceLocator(()=>
                        {
                            ObjectFactory.Initialize(i =>
                            {
                                i.ForConcreteType<TownCrier>().Configure.WithName("tc");
                            });

                            return new StructureMapServiceLocator();
                        });
                        s.WhenStarted(tc => tc.Start());
                        s.WhenStopped(tc => tc.Stop());
                    });

                    x.RunAsLocalSystem();

                   });

                Runner.Host(cfg, args);
            }
        }

    这里我们使用了StructureMap 作为IoC容器,创建了一个StructureMapServiceLocator来掩藏StructureMap,创建的Windows服务的名称是stuff,可以吊相应的方法启动,停止服务。通过直接运行.exe文件在控制台中运行或者调试服务了。

    通过命令运行,安装卸载Windows服务

    Stuff.exe                #控制台方式运行

    Stuff.exe /install     #安装Windows服务

    Stuff.exe /uninstall  #卸载Windows服务

    默认情况下,Windows服务只能运行一个实例,如果我们想运行多个实例怎么办,可以在Topshelf的命令行参数中增加–instance <instance name>来指定实例的名称,也可以通过运行时读取配置文件来达到目的,我更喜欢使用后一种方式设置,在应用程序的配置文件上增加个配置WindowsServiceInstanceName:

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

       <appSettings file="applicationSettings.config">

        <add key="WindowsServiceInstanceName" value="Stuff"/>

       </appSettings>

    </configuration>

    然后改造一下上述代码

           static void Main(string[] args)
            {

                var instanceName = ConfigurationManager.AppSettings["WindowsServiceInstanceName"];

                XmlConfigurator.ConfigureAndWatch(new FileInfo(".\\log4net.config"));
                IRunConfiguration cfg = RunnerConfigurator.New(x =>
                {
                    x.AfterStoppingTheHost(h => { Console.WriteLine("AfterStop called invoked, services are stopping"); });

                    x.SetDescription("Sample Topshelf Host");
                    x.SetDisplayName(instanceName );
                    x.SetServiceName(instanceName );
    ……

    这样我们就可以达到在同台机器上安装多个Windows 服务实例,推荐大家使用这个Windows服务框架TopShelf ,可以简化很多工作和增加灵活性

    欢迎大家扫描下面二维码成为我的客户,为你服务和上云

  • 相关阅读:
    RabbitMQ系列2 RabbitMQ安装与基础入门
    RabbitMQ系列1 什么是MQ
    数据结构与算法系列1之数组介绍与动态数组实现
    数据结构与算法系列3之从内存角度分析数组与链表的区别
    Dubbo学习
    Can't locate Pod/Text.pm问题分析及解决
    “画饼”陷阱论
    自述
    结构光、立体视觉、ToF三种3D传感原理
    游侠郭解是如何被无脑粉坑死的?
  • 原文地址:https://www.cnblogs.com/shanyou/p/1609862.html
Copyright © 2011-2022 走看看