首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将ASP.NET核心作为Windows服务托管

将ASP.NET核心作为Windows服务托管
EN

Stack Overflow用户
提问于 2016-05-20 20:08:46
回答 7查看 58.4K关注 0票数 36

据我所知,RC2支持在Windows Services中托管应用程序。我尝试在一个简单的web项目上测试它(使用.NET框架4.6.1)。

下面是我的Program.cs代码:

代码语言:javascript
复制
using System;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.WindowsServices;

namespace WebApplication4
{
  public class Program : ServiceBase
  {
    public static void Main(string[] args)
    {
      if (args.Contains("--windows-service"))
      {
        Run(new Program());
        return;
      }

      var program = new Program();
      program.OnStart(null);
      Console.ReadLine();
      program.OnStop();
    }

    protected override void OnStart(string[] args)
    {
      var host = new WebHostBuilder()
      .UseKestrel()
      .UseContentRoot(Directory.GetCurrentDirectory())      
      .UseStartup<Startup>()
      .Build();

      host.RunAsService();
    }

    protected override void OnStop() {}
  }
}

所有其他东西基本上都来自.NET核心模板(尽管我将框架改为net461,并在project.json中添加了一些依赖项)。

在用dotnet publish发布它并用sc create创建Windows service之后,我可以成功地启动我的服务,但我无法连接到我的任何控制器(端口没有列出)。我想我做错了什么。

所以我猜主要的问题是如何制作自托管web api并将其作为Windows服务运行。所有找到的解决方案在RC2更新后都不起作用。

EN

回答 7

Stack Overflow用户

发布于 2016-05-26 22:41:58

这里有几个选择--使用微软的WebHostService类、继承WebHostService或编写自己的类。后者的原因是,使用微软的实现,我们不能编写带有继承WebHostService的类型参数的泛型扩展方法,因为这个类不包含无参数构造函数,也不能访问服务定位器。

使用WebHostService

在本例中,我将创建一个控制台应用程序,它使用Microsoft.DotNet.Web.targets,输出一个.exe,并作为MVC应用程序(视图、控制器等)运行。我假设创建控制台应用程序,更改.xproj中的目标,修改project.json以具有适当的发布选项,以及从标准.NET核心web应用程序模板复制视图、控制器和webroot -都很简单。

现在最重要的部分是:

  1. 获取this包并确保project.json文件中的框架为net451 (或更高版本)
  2. 确保入口点中的内容根已正确设置为应用程序.exe文件的发布目录,并且调用了RunAsService()扩展方法。例如:

System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;= Path.GetDirectoryName(exePath);var exePath= = WebHostBuilder() .UseKestrel() .UseContentRoot( directoryPath ) .UseStartup() .Build();if (Debugger.IsAttached || args.Contains("--debug")) { host.Run();} else { host.RunAsService();} }

现在可以使用以下命令轻松安装.exe

代码语言:javascript
复制
    sc create MyService binPath = "Full\Path\To\The\Console\file.exe"

一旦服务启动,web应用程序就会被托管,并成功地找到并呈现它的视图。

继承WebHostService

这种方法的一个主要好处是,它允许我们覆盖OnStopping、OnStarting和OnStarted方法。

假设下面是我们的自定义类,它继承了WebHostService

代码语言:javascript
复制
internal class CustomWebHostService : WebHostService
{
    public CustomWebHostService(IWebHost host) : base(host)
    {
    }

    protected override void OnStarting(string[] args)
    {
        // Log
        base.OnStarting(args);
    }

    protected override void OnStarted()
    {
        // More log
        base.OnStarted();
    }

    protected override void OnStopping()
    {
        // Even more log
        base.OnStopping();
    }
}

按照上面的步骤,我们必须写下我们自己的扩展方法,该方法使用我们的自定义类运行主机:

代码语言:javascript
复制
public static class CustomWebHostWindowsServiceExtensions
{
    public static void RunAsCustomService(this IWebHost host)
    {
        var webHostService = new CustomWebHostService(host);
        ServiceBase.Run(webHostService);
    }
}

与前面的入口点示例相比,唯一需要更改的行是最后的else语句,它必须调用正确的扩展方法

代码语言:javascript
复制
host.RunAsCustomService();

最后,使用与上面相同的步骤安装服务。

代码语言:javascript
复制
sc create MyService binPath = "Full\Path\To\The\Console\file.exe"
票数 56
EN

Stack Overflow用户

发布于 2016-10-29 23:03:55

如果可以只在完整的.NET框架上运行,那么前面的答案就足够了(继承自ServiceBase或使用微软的WebHostService)。

但是,如果你有/想要在.NET内核上运行(例如,在windows nano服务器上,作为普通应用程序和windows上的服务工作的单一二进制文件,或者需要与旧的.NET框架版本上的应用程序并行运行,所以你不能更新系统框架),你将不得不通过P/Invokes自己进行适当的windows API调用。因为我必须这样做,所以我创建了一个library that does exactly that

当以管理权限(例如dotnet MyService.dll --register-as-service)运行时,也可以安装sample

票数 9
EN

Stack Overflow用户

发布于 2017-05-24 17:31:55

您需要引用Microsoft.AspNetCore.HostingMicrosoft.AspNetCore.Hosting.WindowsServices,并在启动类中使用以下代码,以使其可作为windows服务运行:

代码语言:javascript
复制
public static void Main(string[] args)
{
    var host = new WebHostBuilder()
                .UseIISIntegration()
                .UseKestrel()
                .UseContentRoot(@"Path\To\Content\Root")
                .UseStartup<Startup>()
                .Build();

    if (Debugger.IsAttached || args.Contains("--debug"))
    {
        host.Run();
    }
    else
    {
        host.RunAsService();
    }
}

然后,您需要为IWebHost.RunAsService添加一个扩展方法,以便使用OnStoppingOnStarting事件处理程序将其包装在自定义WebHostService类中:

代码语言:javascript
复制
public static class MyWebHostServiceServiceExtensions
{
    public static void RunAsMyService(this IWebHost host)
    {
        var webHostService = new MyWebHostService(host);
        ServiceBase.Run(webHostService);
    }
}

internal class MyWebHostService : WebHostService
{
    public MyWebHostService(IWebHost host) : base(host)
    {
    }

    protected override void OnStarting(string[] args)
    {
        base.OnStarting(args);
    }

    protected override void OnStarted()
    {
        base.OnStarted();
    }

    protected override void OnStopping()
    {
        base.OnStopping();
    }
}

这篇文章的How to host your ASP.NET Core in a Windows Service和评论涵盖了细节。

更新(在Quick summary of what’s new in ASP.NET Core 2.0中查看更多详细信息):

ASP.NET Core 1.1中,我们有这样的东西:

代码语言:javascript
复制
public class Program
{
    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build();

        host.Run();
    }
}

ASP.NET Core 2.0中,它看起来像这样:

代码语言:javascript
复制
public class Program
{
    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build();
}
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37346383

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档