写在前面
前面写了一篇关于将.NET应用转换成Windows服务的方法,其实真正的目的是为了探索如何将Asp.Net Core Web Api 部署成Windows 服务。基于上一篇的基础,只需把创建 WebApplication 的代码放到 BackgroundService 的ExecuteAsync方法中即可。
其中比较重要的一个细节就是需要指定一下配置:
host.ConfigureAppConfiguration((hostingContext, config) => {
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
config.AddEnvironmentVariables();
});
appsettings.json 的内容如下:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*", "urls": "http://localhost:6001", "server.urls": "http://localhost:6001"}
重点部分:
"urls": "http://localhost:6001",
"server.urls": "http://localhost:6001"
代码实现
using System.Runtime.InteropServices;using System.Text.Json.Serialization;using Microsoft.Extensions.Hosting;public class Program{ public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) { var host = Host.CreateDefaultBuilder(args); //判断当前系统是否为windows if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { host.UseWindowsService(); } host.ConfigureAppConfiguration((hostingContext, config) => { config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); config.AddEnvironmentVariables(); }); return host.ConfigureServices((hostContext, services) => { services.AddHostedService<WebApp>(); }); }}public class WebApp: BackgroundService{ public void StartApp() { var builder = WebApplication.CreateSlimBuilder([]); builder.Services.ConfigureHttpJsonOptions(options => { options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default); }); var app = builder.Build(); var sampleTodos = new Todo[] { new(1, "Walk the dog"), new(2, "Do the dishes", DateOnly.FromDateTime(DateTime.Now)), new(3, "Do the laundry", DateOnly.FromDateTime(DateTime.Now.AddDays(1))), new(4, "Clean the bathroom"), new(5, "Clean the car", DateOnly.FromDateTime(DateTime.Now.AddDays(2))) }; var todosApi = app.MapGroup("/todos"); todosApi.MapGet("/", () => sampleTodos); todosApi.MapGet("/{id}", (int id) => sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo ? Results.Ok(todo) : Results.NotFound()); app.Run(); } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { StartApp(); }}public record Todo(int Id, string? Title, DateOnly? DueBy = null, bool IsComplete = false);[JsonSerializable(typeof(Todo[]))]internal partial class AppJsonSerializerContext : JsonSerializerContext{}
项目目录结构:
运行目录结构:
setup.bat 内容:
sc create MyService binPath= %~dp0AspNetCoreWindowsService.exesc failure MyService actions= restart/60000/restart/60000/""/60000 reset= 86400sc start MyServicesc config MyService start=auto
调用示例
执行setup.bat
服务被成功创建并运行
用浏览器访问一下
访问正常,到此结束。