天天看點

ASP.NET Core使用TopShelf部署Windows服務TopShelf步驟運作後記

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的服務部署。

轉載于:https://www.cnblogs.com/podolski/p/10054286.html

繼續閱讀