AspNet Core 部署为Windows服务
- 基于 Web 应用的服务
- 发布
- 脚本
- 安装为服务并运行
- 停止并卸载服务
- 安装为 WindowsServer
- 删除安装失败的服务
- 重新发布安装
- 卸载服务
- 服务仅执行后台任务
- 脚本
- 依赖部署 VS 独立部署
官方文档:
https://docs.microsoft.com/zh-cn/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-6.0&viewFallbackFrom=aspnetcore-3.0&tabs=visual-studio
官方示例:
https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/host-and-deploy/windows-service
部署为windowsServer,首先要看网站是基于什么类型的!
对于使用 Razor Pages 或 MVC 框架的基于 Web 应用的服务,请在项目文件中指定 Web SDK:
如果服务仅执行后台任务(例如 托管服务),请在项目文件中指定辅助角色 SDK:
不同的网站类型,选择不同的的依赖包;
当然可以这两种的网站类型是可以同时存在,官方示例,就是这样子的,
项目工程文件:
net6.0
enable
enable
true
|
Program.cs
// 托管服务
builder.Services.AddHostedService();
// 基于 Web 应用的服务
builder.Host.UseWindowsService();
其中,托管服务 ServiceA 的定义如下:
public class ServiceA : BackgroundService
{
public ServiceA(ILoggerFactory loggerFactory)
{
Logger = loggerFactory.CreateLogger();
}
public ILogger Logger { get; }
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
Logger.LogInformation("ServiceA is starting.");
stoppingToken.Register(() => Logger.LogInformation("ServiceA is stopping."));
while (!stoppingToken.IsCancellationRequested)
{
Logger.LogInformation("ServiceA is doing background work.");
await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
}
Logger.LogInformation("ServiceA has stopped.");
}
}
基于 Web 应用的服务
创建 AspNet Core 项目,项目名称为:WebWinServer1
添加包 Microsoft.Extensions.Hosting.WindowsServices
...
...
接着修改 Program.cs
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()//指定项目可以部署为Windows服务
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup()
.UseUrls("http://*:8787"); //使用的端口号
});
发布
右键工程文件,在菜单中选择【发布】,设置发布配置
注意,这里的
部署模式:选择【框架依赖】,目标框架选择 netcoreapp3.1,
但是我的电脑没有 .netcore3.1的运行时,之所以这样设置,只是为了测试和模拟真实的生成环境可能遇到的情况
多个网站版本不同,需要安装各个版本的运行时,这有不太可能,除非使用Docker部署。
其中,发布文件地址是:
E:\webpulish\web-winserver
然后点击发布
脚本
参见:https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/host-and-deploy/windows-service/samples/scripts
安装为服务并运行
创建文件install.bat
set serviceName=AspNetCore-WinServer
set serviceFilePath=%cd%\WebWinServer1.exe
set serviceDescription=AspNetCoreweb程序部署为WindowsServer
sc create %serviceName% binPath=%serviceFilePath%
sc config %serviceName% start=auto
sc description %serviceName% %serviceDescription%
sc start %serviceName%
pause
停止并卸载服务
创建文件uninstall.bat
set serviceName=AspNetCore-WinServer
sc stop %serviceName%
sc delete %serviceName%
pause
安装为 WindowsServer
把上面创建的安装脚本 install.bat 和卸载脚本 uninstall.bat 复制到发布文件跟目录,示例中的目录是:
E:\webpulish\web-winserver
使用管理员身份打开CMD,执行安装脚本 install.bat
注意:一定要是管理员身份打开,否则报错:
[SC] OpenService 失败 5:拒绝访问
>E:
>E:\>cd E:\webpulish\web-winserver
>E:\webpulish\web-winserver>install.bat
....
E:\webpulish\web-winserver>sc.exe start AspNetCore-WinServer
[SC] StartService 失败 2:
服务启动失败,这是因为,我的电脑用的是 .Net 6,现在发布的目标框架是.netcoreapp3.1
本机没有.netcore3.1的运行时。所以启动失败!
删除安装失败的服务
执行以下命令,删除服务
sc delelte AspNetCore-WinServer
虽然删除WindowsServer成功,但是服务列表中还是存在,要彻底删除,
打开系统注册表,删掉服务的注册表信息,通常路径在:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services 找到你的Service服务的名字,然后把整个文件夹删掉
这时,服务列表中还是存在服务:AspNetCore-WinServer,重启电脑即可。
重新发布安装
上节说到我的电脑用的是.Net 6,现在发布的目标框架是.netcoreapp3.1 ,这种情况跟实际的生成环境一样,
生成环境有多个网站,第一个网站是 .netcore3.1, 第二个网站是基于.net5, 第三个网站是.net6,
这时不可能同时安装3个版本的 .net运行时,所以发布的时候,发布配置如下:
部署模式:选择【独立】,目标框架选择 netcoreapp3.1,如下图所示:
点击发布。
复制 安装脚本 install.bat到发布目录:E:\webpulish\web-winserver
然后打开CMD【管理员身份】,切换到发布目录 ,执行安装脚本 install.bat
E:\webpulish\web-winserver>install.bat
输入结果
E:\webpulish\web-winserver>set serviceName=AspNetCore-WinServer
E:\webpulish\web-winserver>set serviceFilePath=E:\webpulish\web-winserver\WebWinServer1.exe
E:\webpulish\web-winserver>set serviceDescription=AspNetCoreweb程序部署为WindowsServer
E:\webpulish\web-winserver>sc config AspNetCore-WinServer start=auto
[SC] ChangeServiceConfig 成功
E:\webpulish\web-winserver>sc description AspNetCore-WinServer AspNetCoreweb程序部署为WindowsServer
[SC] ChangeServiceConfig2 成功
E:\webpulish\web-winserver>sc start AspNetCore-WinServer
SERVICE_NAME: AspNetCore-WinServer
TYPE : 10 WIN32_OWN_PROCESS
STATE : 2 START_PENDING
(NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x7d0
PID : 11148
FLAGS :
E:\webpulish\web-winserver>pause
安装成功,启动也成功了。
访问站点:http://localhost:8787/
卸载服务
用管理员身份打开CMD,执行如下卸载脚本 uninstall.bat
>E:
>E:\>cd E:\webpulish\web-winserver
>E:\webpulish\web-winserver>uninstall.bat
输出结果:
E:\webpulish>set serviceName=AspNetCore-WinServer
E:\webpulish>sc stop AspNetCore-WinServer
SERVICE_NAME: AspNetCore-WinServer
TYPE : 10 WIN32_OWN_PROCESS
STATE : 3 STOP_PENDING
(STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0
E:\webpulish>sc delete AspNetCore-WinServer
[SC] DeleteService 成功
E:\webpulish>pause
请按任意键继续. . .
删除成功
,此时服务只是被禁用,属于标记删除,如果要彻底删除,使用注册表删除,见上一节的具体操作。
服务仅执行后台任务
创建控制台程序,项目名称为:WorkerWinService,修改项目工程文件为:
添加包 Microsoft.AspNetCore.Hosting.WindowsServices
...
...
接着修改 Program.cs
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService(); // 添加托管服务
});
定义后台托管服务:Worker, 继承 BackgroundService
Worker.cs
public class Worker : BackgroundService
{
private readonly ILogger _logger;
public Worker(ILogger logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
}
}
脚本
安装和卸载脚本同上,只是修改服务名称为 WorkerWinService 即可。
依赖部署 VS 独立部署
参见:https://docs.microsoft.com/zh-cn/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-6.0&viewFallbackFrom=aspnetcore-3.0&tabs=visual-studio