ASP.NET Core使用TopShelf部署Windows服务

admin
1041
文章
3
评论
2020年1月22日16:34:56 评论 68 2519字阅读8分23秒

asp.net core很大的方便了跨平台的开发者,linux的开发者可以使用apache和nginx来做反向代理,windows上可以用IIS进行反向代理。
反向代理可以提供很多特性,固然很好。但是还有复杂性,我们也可以使用windows service来直接启动kestrel。

asp.net core官方网站提供了一种基于windows服务部署的方法:在 Windows 服务中托管 ASP.NET Core
这种方式需要修改代码,然后部署的时候,使用命令行创建、安装服务,然后再启动。

感觉还是不够爽快,我们可以使用topshelf改造一下。

TopShelf

topshelf可以很便捷地将一个windows console程序改造成windows service,只需要稍微修改一下代码结构,然后通过nuget包就可以简单操作了。安装与部署也是极其方便,而且,topshelf在调试的时候,直接是作为console程序,极其便于调试。

TopShelf项目地址:http://topshelf-project.com/

步骤

首先引用nuget包:

Install-Package TopShelf

然后改造一下program.cs

public class Program
{
    public static void Main(string[] args)
    {
        var rc = HostFactory.Run(x =>                                   //1
        {
            x.Service<MainService>(s =>                                   //2
            {
                s.ConstructUsing(name => new MainService(args));                //3
                s.WhenStarted(tc => tc.Start());                         //4
                s.WhenStopped(tc => tc.Stop());                          //5
            });
            x.RunAsLocalSystem();                                       //6

            x.SetDescription("JwtAPIService");                   //7
            x.SetDisplayName("JwtAPIService");                                  //8
            x.SetServiceName("JwtAPIService");                                  //9
        });                                                             //10

        var exitCode = (int)Convert.ChangeType(rc, rc.GetTypeCode());  //11
        Environment.ExitCode = exitCode;

        //CreateWebHostBuilder(args).Build().RunAsService();
    }
}

这里指定服务程序的内容在MainService这个类里面,并通过代码指定了服务的名称和描述等行为。以前的启动CreateWebHostBuilder方法转移到了这个类中:

public class MainService
{
    private string[] args;
    public MainService(string[] vs)
    {
        args = vs;
    }
    public void Start()
    {
        var isService = !(Debugger.IsAttached || args.Contains("--console"));
        var builder = CreateWebHostBuilder(args.Where(arg => arg != "--console").ToArray());

        if (isService)
        {
            var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
            var pathToContentRoot = Path.GetDirectoryName(pathToExe);
            builder.UseContentRoot(pathToContentRoot);
        }

        var host = builder.Build();
        host.Run();
    }

    public void Stop()
    {
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {
        var config = new ConfigurationBuilder()
// .SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("config.json", optional: true, reloadOnChange: true)
.Build();

        return WebHost.CreateDefaultBuilder(args)
                .UseKestrel()
                .UseConfiguration(config)
                .UseStartup<Startup>();
    }
}

Start方法指定服务启动时,服务的执行不需要依赖于Microsoft.AspNetCore.Hosting.WindowsServices这个nuget包。
另外Contentroot需要注意,使用windows服务进行提供服务,GetCurrentDirectory的根目录是system32,而不是asp.net core的dll的目录。使用appsettings.json时,可能会引起问题,最好使用自定义的程序配置(例如这里通过config.json进行设置)。

运行

  • 确定是否存在 Windows 运行时标识符 (RID),或将其添加到包含目标框架的 中:
<PropertyGroup>
   <TargetFramework>netcoreapp2.1</TargetFramework>
   <RuntimeIdentifier>win7-x64</RuntimeIdentifier>
</PropertyGroup>
  • 发布,最终可以得到可执行程序。直接双击运行,程序就可以以console的形式启动,方便调试。
  • 命令行运行xxxx.exe install就而可以安装服务,然后服务就可以自动启动。
  • 命令行运行xxxx.exe uninstall就可以卸载服务。整个过程不需要新建用户与策略。

后记

吐槽:直接使用TopShelf,调试windows服务的过程变得不那么痛苦了,想起附加调试器的过程,简直了。
P.S. 需要最新版本的topshelf才可以支持asp.net core的服务部署。

继续阅读
  • 文本由 发表于 2020年1月22日16:34:56
  • 除非特殊声明,本站文章均为原创,转载请务必保留本文链接
linux命令后台运行 技术文章

linux命令后台运行

有两种方式: 1. command & : 后台运行,你关掉终端会停止运行 2. nohup command & : 后台运行,你关掉终端也会继续运行   一、 简介 Lin...
linux free 命令 技术文章

linux free 命令

free 命令显示系统内存的使用情况,包括物理内存、交换内存(swap)和内核缓冲区内存。 如果加上 -h 选项,输出的结果会友好很多: 有时我们需要持续的观察内存的状况,此时可以使用 -s 选项并指...
Linux常用命令学习 技术文章

Linux常用命令学习

1、ls命令 就是list的缩写,通过ls 命令不仅可以查看linux文件夹包含的文件,而且可以查看文件权限(包括目录、文件夹、文件权限)查看目录信息等等 常用参数搭配: ls -a 列出目录所有文...
Linux网络编程入门 (转载) 技术文章

Linux网络编程入门 (转载)

(一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍 客户端和服务端 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户端 在网络程序...
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: