托管到Windows Service中

众所周知,ASP.NET Core采用了和传统ASP.NET不同的托管和HTTP处理方式,即把服务器和托管环境完全解耦。

ASP.NET Core内置了两个HTTP服务器实现,一个是基于libuv实现的Kestrel(支持跨平台),一个是基于Windows HTTP Server API实现的WebListener(仅支持Windows)。

而托管环境可以和服务器不相关,一般情况是自托管,或者托管到IIS/IISExpress中(此处的IIS仅作为反向代理把请求转发给所使用的服务器实现)。

因此,打算以Windows Service这种比较传统的方式来部署ASP.NET Core的Web应用也是可行的(本质还是自托管,只是启动进程并非控制台程序,而是一个Windows Service)。这不,微软就很贴心的提供了一个Nuget来支持:Microsoft.AspNetCore.Hosting.WindowsServices,它的源码在:https://github.com/aspnet/Hosting/tree/dev/src/Microsoft.AspNetCore.Hosting.WindowsServices

使用它也很简单:

  1. 创建一个以.NET Framework为运行时的ASP.NET Core应用,即模版选择“ASP.NET Core Web Application (.NET Framework)”。VS2017中没有此模板,可以选择框架为.NET Framework4.6,模板为ASP.NET Core Web Application,然后编辑项目文件,修改TargetFramework为“<TargetFramework>net461;netcoreapp2.0</TargetFramework>”,这样编译出来就是两个框架的(NetCore本身就支持一个项目多个运行时的)
  2. 引用Microsoft.AspNetCore.Hosting.WindowsServices。--此包是.Net Framework的
  3. 在Program的Main方法中,把默认的host.Run改为host.RunAsService。
  4. 编译程序后,会在Debug目录下看到你选用的运行时版本的一个目录,比如“net46”,在里面会看到编译好的exe文件和一个类似“win7-x64”的这样文件夹。
  5. 进入到“win7-x64”文件夹,在命令行执行“sc create MyService binPath = "Full\Path\To\The\Console\file.exe --windows-service”(必须加参数,否则启动服务报1053错误),来创建一个Windows Service。注意:binPath必须是全路径。
  6. 这样就可以在Windows Service中托管ASP.NET Core应用了。
  7. 如果希望在服务启动和停止的过程中做一些额外处理,比如记录日志,那么可以实现一个CustomWebHostService来继承WebHostService ,并在其中编写所需的代码。
  8. 并实现如下的扩展方法:
public static class CustomWebHostWindowsServiceExtensions
{
public static void RunAsCustomService(this IWebHost host)
{
var webHostService = new CustomWebHostService(host);
ServiceBase.Run(webHostService);
}
}
host.RunAsCustomService();

  


把ASP.NET Core应用托管到Windows Service中,就这么简单!

更多问题?

不过,我想从我的场景来谈谈为什么我有托管到Windows Service的需求。这几天在构思一个中间件(包含多个组件)的架构,考虑到初期会以比较传统的方式来部署,后期有可能跨平台,并且希望组件之间能够相对独立和解耦。所以,最自然的想法就是架构设计为微服务,基于ASP.NET Core实现(未来不排除使用其他技术栈)。部署的话,初期分离部署为多个Windows Service,后期也可以很平滑的过度到容器或者类似Service Fabric这样的微服务运行平台中。

基于这样的设计考虑,要解决的第一个问题就是是否可以把ASP.NET Core应用托管到Windows Service中(上面已经验证了),第二个问题是是否可以根据环境条件跑在不同的启动进程中,第三问题是是否可以同时支持多种运行时。2,3个问题要解决其实也非常简单。

支持不同启动方式

第二个问题的解决办法如下:

  1. 在Program的Main方法中,判断一下特定的命令行参数,比如“--windows-service”
  2. 以这个参数启动的情况下,就host.RunAsService,不是的话就host.Run。

就是这么简单粗暴。

支持不同运行时

.NET Core本来就支持一个项目多个运行时,就算把net46和netcoreapp1.0混合也是可以的。具体方法如下:

  1. 修改project.json文件,在frameworks下额外添加“netcoreapp1.0”。
  2. 把对Microsoft.AspNetCore.Hosting.WindowsServices的依赖移到net46下
  3. 在netcoreapp1.0下添加“Microsoft.NETCore.App”的依赖
  4. 在Program的Main方法中,基于条件编译的符号来判断不同的运行时,具体的符号表见:https://docs.microsoft.com/en-us/dotnet/articles/core/tutorials/libraries#how-to-multitarget

示例源代码

为了避免在文章中贴大段的源代码,大家转到GitHub中去看示例代码吧:https://github.com/heavenwing/HostingAspCoreAsWindowsService

ASP.NET Core应用到Windows Service中的更多相关文章

  1. 如何托管ASP.NET Core应用到Windows Service中

    (此文章同时发表在本人微信公众号"dotNET开发经验谈",欢迎右边二维码来关注.) 题记:正在构思一个中间件的设计,考虑是否既可以使用最新的技术,也可以兼顾传统的部署模式.所以有 ...

  2. ASP.NET Core在Azure Kubernetes Service中的部署和管理

    目录 ASP.NET Core在Azure Kubernetes Service中的部署和管理 目标 准备工作 注册 Azure 账户 AKS文档 进入Azure门户(控制台) 安装 Azure Cl ...

  3. NetCore Selfhost,IIShost,Windows Service Host详解(自宿主、宿主在IIS,宿主在Windows Service中)

    第一部分.自托管 一.依赖.Net Core环境 修改 project.json 文件内容,增加发布时需要包含文件的配置内容(NetCore2.0版本不需要任何设置,NetCore2.0开始彻底放弃p ...

  4. asp.net core 托管到windows服务,并用iis做反向代理

    使用NSSM把.Net Core部署至 Windows 服务   为什么部署至Windows Services 在很多情况下,很少会把.Net Core项目部署至Windows服务中,特别是Asp.n ...

  5. .NET 6学习笔记(3)——在Windows Service中托管ASP.NET Core并指定端口

    在上一篇<.NET 6学习笔记(2)--通过Worker Service创建Windows Service>中,我们讨论了.NET Core 3.1或更新版本如何创建Windows Ser ...

  6. ASP .NET CORE MVC 部署Windows 系统上 IIS具体步骤---.Net Core 部署到 IIS位系统中的步骤

    一.IIS 配置 启用 Web 服务器 (IIS) 角色并建立角色服务. 1.Windows Ddesktop 桌面操作系统(win7及更高版本) 导航到“控制面板” > “程序” > “ ...

  7. 尝新体验ASP.NET Core 6预览版本中发布的最小Web API(minimal APIS)新特性

    本文首发于<尝新体验ASP.NET Core 6预览版本中发布的最小Web API(minimal APIS)新特性> 概述 .NET开发者们大家好,我是Rector. 几天前(美国时间2 ...

  8. ASP.NET Boilerplate 学习 AspNet Core2 浏览器缓存使用 c#基础,单线程,跨线程访问和线程带参数 wpf 禁用启用webbroswer右键菜单 EF Core 2.0使用MsSql/MySql实现DB First和Code First ASP.NET Core部署到Windows IIS QRCode.js:使用 JavaScript 生成

    ASP.NET Boilerplate 学习   1.在http://www.aspnetboilerplate.com/Templates 网站下载ABP模版 2.解压后打开解决方案,解决方案目录: ...

  9. ASP.NET Core 新建项目(Windows) - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 新建项目(Windows) - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 新建项目(Windows) 对于任何语言和框架,都 ...

随机推荐

  1. Java.lang包的接口解读

    Java.lang包中提供了八个接口: 1.Appendable 能够被追加 char 序列和值的对象.如果某个类的实例打算接收来自 Formatter的格式化输出,那么该类必须实现 Appendab ...

  2. Python基础学习(第8天)

    先补充些iter函数的用法:iter()其实就是一个迭代器,参数可传个list.dict等等,然后可通过调用next函数获取下一个元素,默认并未指向对象的第一个元素,可理解为指向了第一个元素的前面的位 ...

  3. L125

    The United States Senate (参议院)has taken the first step toward ending President Barack Obama's health ...

  4. 探索Javascript 异步编程

    在我们日常编码中,需要异步的场景很多,比如读取文件内容.获取远程数据.发送数据到服务端等.因为浏览器环境里Javascript是单线程的,所以异步编程在前端领域尤为重要. 异步的概念 所谓异步,是指当 ...

  5. 详解scrapy

    >> (1) 基本概念 >> (2) 爬虫与反爬 >> (3) 基本概念 >> (4) 基本概念

  6. Python爬虫----抓取豆瓣电影Top250

    有了上次利用python爬虫抓取糗事百科的经验,这次自己动手写了个爬虫抓取豆瓣电影Top250的简要信息. 1.观察url 首先观察一下网址的结构 http://movie.douban.com/to ...

  7. S2SH框架中的无刷新验证码功能实现

    暑假期间在实验室做使用S2SH框架的项目,其中登录和注册需要验证码,实现了一个没有实现刷新验证码功能的简单版本,代码如下: 1 package com.sem.action; 2 3 import j ...

  8. Kivy: Building GUI and Mobile apps with Python

    Intro Python library for building gui apps (think qt, gdk,processing) build from ground up for lates ...

  9. 深入理解java虚拟机-第六章

    第6章 类文件 6.3 Class类文件的结构 Class文件是一组以8位字节为基础单位的二进制流. Class文件格式采用一种类似C语言结构伪结构存储数据,这种伪结构中只有两种数据类型:无符号数和表 ...

  10. HDU - 3949 :XOR(线性基,所有集合的不同异或和中,求从小到大第K个)

    XOR is a kind of bit operator, we define that as follow: for two binary base number A and B, let C=A ...