踩坑 Windows 服务来宿主 .NET 程序
本文所指的 .NET 程序为 .NET6 的程序。因为 .NET 的版本更新很快,所以方式、方法也有变化,所以网上搜到的方法有些也过时了。以下是最近我实践下来的一点心得(坑)。
上一篇说到 不安装运行时运行 .NET 程序 后我们的程序已经只有一个 dll/exe 了,但是在 windows 上运行的时候会是一个控制台程序,很容易人不小心关闭了。所以想着把我们的程序部署成 windows 服务,这样不会误关,重启服务器的时候也会自动启动。所以最近折腾了一下把 .NET 程序,特别是 ASP.NET Core 程序部署为 windows 服务。本来以为网上随便搜一搜就很容易,事实上没想得这么美好。
Worker Service
如果你的服务只想执行一些后台任务,比如定时任务,并不提供网站的服务。那么使用 Worker service 项目模板新建一个项目是最合适的。
新建完项目后使用 nuget 安装:
Microsoft.Extensions.Hosting.WindowsServices
修改 program.cs 文件
using WorkerService1;
IHost host = Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureServices(services =>
{
services.AddHostedService<Worker>();
})
.Build();
await host.RunAsync();
其中就只添加一句 UseWindowsService
就可以了。
编译之后使用 sc
命令就可以注册为服务了。
sc create "wsTest" binPath=wsTest.exe
sc start "wsTest"
pause
我们把它写成一个 bat 文件方便执行。使用管理权限运行这个 bat 文件服务会被注册并且直接运行:
ASP.NET Core
以上尝试了一下 worker service 模式注册为服务,感觉简单的很。但是下面把 ASP.NET Core 程序注册为服务的时候就没那么简单啦。我查了一些文章,写的时间有些早了,所以还是安照微软官方的文档 Host ASP.NET Core in a Windows Service 的提示来操作。这篇文章虽然叫 Host ASP.NET Core in a Windows Service ,但其实里面的内容说的是上面的 worker service 。当按照上面的步骤尝试把 asp.net core 程序部署为服务的时候死活起不来,一直报未找到文件的异常。
我们新建一个最简单的 asp.net core 程序来演示一下:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Host.UseWindowsService();
var app = builder.Build();
app.UseStaticFiles();
app.UseRouting();
await app.RunAsync();
这是一个最简单的 asp.net core razor pages 程序。我们按照文档安装扩展包:
Microsoft.Extensions.Hosting.WindowsServices
然后调用 UseWindowsService 方法
builder.Host.UseWindowsService();
同样使用 sc 命令注册为服务并运行它。很遗憾它会报错。
经过多种尝试方法都不行。最后翻了一下微软仓库里的 sample 代码才发现原来他们自己的 sample 代码里多了几行代码 。
注意下面的代码了啊 !!!
在构建 builder 的时候需要多传几个参数:
var options = new WebApplicationOptions
{
Args = args,
ContentRootPath = WindowsServiceHelpers.IsWindowsService() ? AppContext.BaseDirectory : default
};
var builder = WebApplication.CreateBuilder(options);
只要使用这段代码来构建 builder ,服务就可以顺利的运行起来。根据以往的经验,可能还是作为服务运行的时候程序根目录的问题,通过以上方法来指定 AppContext.BaseDirectory 来作为程序的根目录,不然就有可能被定位到 system32 目录下。
吐槽。。。虽然解决方案很简单,但是微软没有在文档里把这么关键的代码给些出来,着实有点坑啊,辛亏现在代码都在 github 上,很容易翻到,不然得折腾死人。
关注我的公众号一起玩转技术
踩坑 Windows 服务来宿主 .NET 程序的更多相关文章
- Windows 服务为宿主的WCF服务,详细图解。
废话不多说,直接进入主题: 1.打开vs2010新建项目,选择Windows服务. 2.选中WindowsService右击,添加WCF服务. 3.添加成功后,为下图.将接口类ITestService ...
- windows服务启动有界面的程序
大家写windows服务守护进程的时候,肯定会遇到启动的程序看不到界面,只能在任务管理器里面看到xxx.exe问题. 发现可能有如下情况 a.无论是开机,还是程序被关掉后,守护服务启动的程序只能看到任 ...
- Windows服务项目打包成安装包(Windows服务)-----------VS2017项目程序打包成.msi或者.exe
VS2017项目程序打包成.msi或者.exe Windows服务项目使用VS2017项目程序打包成.msi或者.exe安装包 项目打包成安装包(Windows服务) 1.安装打包插件:Microso ...
- C#穿透session隔离———Windows服务启动UI交互程序
在Windows服务里面启动其他具有界面的应用程序,需要穿透session隔离,尝试了很多种方法,都可行,现在一一列举下来,并写下几个需要注意的地方. 需要注意的地方 首先要将服务的Account属性 ...
- C# windows服务,解决应用程序开机自启问题
最近在东营做一个超市购物的项目,业务体量很小,是仅供内部员工使用的内网应用程序,其中涉及一个商品数据同步的winform应用程序,有一个问题就是服务器重启后,必须登录服务器操作系统,手动启动才行,于是 ...
- windows服务怎么向应用程序发消息(部署在同一台机,非SCOKET)
命名管道:NamedPipeClientStream & NamedPipeClientStream 参考实例:http://msdn.microsoft.com/zh-cn/library/ ...
- 将springboot打包成的jar文件做成windows服务,解决java程序自启动问题
https://blog.csdn.net/weixin_40411331/article/details/80193376 https://blog.csdn.net/qq_33188180/art ...
- 踩坑 Windows 解决pip install出现“由于目标计算机积极拒绝,无法连接”的问题
解决pip install出现“由于目标计算机积极拒绝,无法连接”的问题 可能是使用某软件自动设置了代理, 所以需要手动的取消代理才可以. 在Intel选项中把所有的代理都给去掉就可以了... ...
- C#判断程序是由Windows服务启动还是用户启动
在Windows系统做网络开发,很多时候都是使用Windows服务的模式,但在调度阶段,我们更多的是使用控制台的模式.在开发程序的时候,我们在Program的Main入口进行判断.最初开始使用Envi ...
随机推荐
- Vue.js与ElementUI搭建无限级联层级表格组件
前言 今天,回老家了.第一件事就是回家把大屏安排上,写作的感觉太爽了,终于可以专心地写文章了.我们今天要做的项目是怎么样搭建一个无限级联层级表格组件,好了,多了不多说,赶快行动起来吧!项目一览 到底是 ...
- ArrayList和LinkedList内部是怎么实现的?他们之间的区别和优缺点?
ArrayList 内部使用了数组形式进行了存储,利用数组的下标进行元素的访问,因此对元素的随机访问速度非常快.因为是数组,所以ArrayList在初始化的时候, 有初始大小10,插入新元素的时候,会 ...
- 最小生成树 链式前向星 Prim&Kruskal
Prim: Prim的思想是将任意节点作为根,再找出与之相邻的所有边(用一遍循环即可),再将新节点更新并以此节点作为根继续搜,维护一个数组:dis,作用为已用点到未用点的最短距离. 证明:Prim算法 ...
- Spring 核心概念
Spring 核心概念 引言 本文主要介绍 Spring 源码中使用到的一些核心类 1. BeanDefinition BeanDefinition表示Bean定义,BeanDefinition 中存 ...
- docker快速安装openvas
项目地址 1.更换国内docker源 2.docker run -d -p 443:443 -e PUBLIC_HOSTNAME=此处填你宿主机IP --name openvas mikesplain ...
- Markdown扩展语法
目录 Markdown 语法补充 一.快速生成 HTML 表格代码 在线表格编辑器--TablesGenerator 二. 插入视频.音频或GIF 1. 视频 2. 音频 方法一 方法二 方法三 3. ...
- @ConditionalOnMissingBean 如何实现覆盖第三方组件中的 Bean
1. 自定义一个简单 spring-boot 组件 创建 olive-starter 项目 对应的 pom.xml文件如下 <project xmlns="http://maven.a ...
- c:找到出现次数最多的递增数字串
如题,如何在一亿位整数组成的字符串中找到出现次数最多的递增数字串? 答案: #include <stdio.h> #include <string.h> #define MAX ...
- Nginx 限制上传文件的大小。responded with a status of 413 (Request Entity Too Large)
# 限制请求体的大小,若超过所设定的大小,返回413错误. client_max_body_size 50m; # 读取请求头的超时时间,若超过所设定的大小,返回408错误. client_heade ...
- Nginx 浏览器缓存配置指令
# 浏览器缓存 # 当浏览器第一次访问服务器资源的时候,服务器返回到浏览器后,浏览器进行缓存 # 缓存的大概内容有: # 1.缓存过期的日期和时间 # 2.设置和缓存相关的配置信息 # 3.请求资源最 ...