如何将.NET6的ASP.NET Core API部署为Windows服务及控制器映射问题
问题描述
我在Visual Studio 2022中基于ASP.NET Core API模板创建了一个目标框架为.NET 6的小型API,本地测试调试时以控制台应用启动一切正常,但生产环境需要将其作为Windows服务运行,不知道该怎么实现。
我试过把API的.exe和服务放在同一目录调用,但了解到无用户登录时控制台应用无法启动,所以希望把API和服务打包在一起,随Windows服务启动。
我做了个测试:创建静态类Test.cs并写了Start方法,把Program.cs的代码全复制进去,然后从测试应用调用这个Start方法。API能启动并监听端点,但无法映射项目控制器文件夹里的控制器。
测试截图:

Program.cs 代码
var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); //to avoid json serialize camel casing builder.Services.AddControllers().AddJsonOptions(opts => { opts.JsonSerializerOptions.PropertyNamingPolicy = null; opts.JsonSerializerOptions.NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.AllowNamedFloatingPointLiterals; //para aceitar NAN, infinitos etc no json }); ////////// //Nedeed builder.Services.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()); }); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseCors("CorsPolicy"); //app.UseAuthorization(); app.MapControllers(); app.Run();
Test.cs 代码
namespace ProjectX.Api { public static class Test { public static void Start() { var builder = WebApplication.CreateBuilder(); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); //to avoid json serialize camel casing builder.Services.AddControllers().AddJsonOptions(opts => { opts.JsonSerializerOptions.PropertyNamingPolicy = null; opts.JsonSerializerOptions.NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.AllowNamedFloatingPointLiterals; //para aceitar NAN, infinitos etc no json }); ////////// //Nedeed builder.Services.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()); }); var app = builder.Build(); app.UseSwagger(); app.UseSwaggerUI(); app.UseHttpsRedirection(); app.UseCors("CorsPolicy"); //app.UseAuthorization(); app.MapControllers(); app.Run(); } } }
测试应用代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace ProjectX.Tester { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { try { ProjectX.Api.Test.Start(); } catch (Exception ex ) { } } } }
解决方案
一、正确将ASP.NET Core 6 API部署为Windows服务(推荐方案)
.NET 6原生支持将控制台应用转为Windows服务,无需自定义启动类,步骤如下:
- 安装NuGet包
在API项目中安装Microsoft.Extensions.Hosting.WindowsServices包:
Install-Package Microsoft.Extensions.Hosting.WindowsServices
- 修改Program.cs配置服务运行方式
在WebApplication.CreateBuilder后添加Windows服务支持:
var builder = WebApplication.CreateBuilder(args); // 添加Windows服务支持,自定义服务名称 builder.Host.UseWindowsService(options => { options.ServiceName = "ProjectX API Service"; }); // 保留原有服务配置(AddControllers、Cors等) // ... 你的原有代码 ... var app = builder.Build(); // 保留原有的中间件配置 // ... 你的原有代码 ... app.Run();
发布API
右键项目→发布,选择文件夹作为目标,完成发布后得到发布目录。安装并启动Windows服务
以管理员身份打开命令提示符/PowerShell,执行以下命令:
# 安装服务(替换为你的发布路径) sc create "ProjectX API Service" binPath="C:\你的发布目录\ProjectX.Api.exe" # 启动服务 sc start "ProjectX API Service"
如需卸载服务:
sc stop "ProjectX API Service" sc delete "ProjectX API Service"
二、解决测试中控制器未映射的问题(静态类启动场景)
测试中控制器未映射的核心原因是:WebApplication.CreateBuilder()未指定程序集信息,导致框架无法扫描到控制器所在的程序集。修改Test.cs的Start方法:
public static void Start() { // 指定应用程序集和内容根路径 var builder = WebApplication.CreateBuilder(new WebApplicationOptions { ApplicationName = typeof(Test).Assembly.FullName, ContentRootPath = Path.GetDirectoryName(typeof(Test).Assembly.Location) }); // 添加控制器时指定程序集 builder.Services.AddControllers() .AddApplicationPart(typeof(Test).Assembly) // 关键:告知框架控制器所在程序集 .AddJsonOptions(opts => { opts.JsonSerializerOptions.PropertyNamingPolicy = null; opts.JsonSerializerOptions.NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.AllowNamedFloatingPointLiterals; }); // ... 原有Cors、Swagger等配置 ... var app = builder.Build(); // ... 原有中间件配置 ... app.MapControllers(); app.Run(); }
注意事项
- 部署为Windows服务时,需确保服务账户拥有API所需的资源访问权限(如数据库、文件等)。
- Windows服务会在系统启动后自动运行,无需用户登录,符合生产环境需求。
内容的提问来源于stack exchange,提问作者Vitor Barros
相关产品推荐
相关产品推荐

