You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将.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能启动并监听端点,但无法映射项目控制器文件夹里的控制器。

测试截图:
通过默认方式启动API时一切正常
通过静态方法启动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服务,无需自定义启动类,步骤如下:

  1. 安装NuGet包
    在API项目中安装Microsoft.Extensions.Hosting.WindowsServices包:
Install-Package Microsoft.Extensions.Hosting.WindowsServices
  1. 修改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();
  1. 发布API
    右键项目→发布,选择文件夹作为目标,完成发布后得到发布目录。

  2. 安装并启动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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 22:50:22