簡體   English   中英

.NET Core 3.1 控制台應用作為 Windows 服務

[英].NET Core 3.1 Console App as a Windows Service

我目前有一個運行 ASP.NET Core 3.1 的相當大的控制台應用程序。 我現在的任務是在我們的一台服務器上將這項工作作為窗口服務進行。 我已經准備好讓它在服務器本身上作為服務運行,但是,我目前遇到的一件事是如何在代碼中實際更改它以使其作為服務運行而不會破壞它。

我已經發現一對夫婦像教程是做解釋如何運行一個控制台應用程序作為一種服務,但是,所有的人,我已經從一個全新的項目中找到的開始。 我的問題是我當前的項目已經寫好了。 我尋求幫助的主要問題是如何讓我的項目作為 Windows 服務工作,同時保持當前在 startup.cs 中的功能。 對於上下文,這是我當前的 startup.cs 和 program.cs:

啟動文件

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddSignalR();
        services.AddTransient<SharePointUploader>();
        services.AddTransient<FileUploadService>();
        services.AddSingleton<UploaderHub>();
        //services.AddAuthentication(IISDefaults.AuthenticationScheme);
        services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate();
        services.AddAuthorization();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHttpsRedirection();
        }

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapHub<UploaderHub>("/uploadHub");
        });
    }
}

程序.cs

public class Program
{
    public static void Main(string[] args)
    {
        var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
        try
        {
            logger.Debug("init main");
            CreateHostBuilder(args).Build().Run();
        }
        catch (Exception exception)
        {
            //NLog: catch setup errors
            logger.Error(exception, "Stopped program because of exception");
            throw;
        }
        finally
        {
            // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
            NLog.LogManager.Shutdown();
        }
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            })
            .ConfigureLogging(logging =>
            {
                logging.ClearProviders();
                logging.SetMinimumLevel(LogLevel.Trace);
            })
            .UseNLog();
}

我真的不明白這在作為 Windows 服務運行時應該如何工作(基於上面鏈接的教程)。 任何幫助將不勝感激。

使用 IWebHostBuilder 而不是 IHostBuilder:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((context, config) =>
        {
            // Configure the app here.
        })
        .UseNLog()
        .UseUrls("http://localhost:5001/;" +
                    "https://localhost:5002/;")
        .UseStartup<Startup>();

您還需要以下軟件包:

Microsoft.AspNetCore.Hosting;
Microsoft.AspNetCore.Hosting.WindowsServices;

修改你的主函數:

bool isService = !(Debugger.IsAttached || args.Contains("--console"));
var builder = CreateWebHostBuilder(args.Where(arg => arg != "--console").ToArray());
var host = builder.Build();

if (isService)
{
    host.RunAsService();
}
else
{
    host.Run();
}

要安裝服務,請使用工具 sc.exe。 您可以通過將 --console 作為參數傳遞給應用程序來將應用程序作為控制台應用程序運行。 對於調試,您還需要傳遞 --console 。

我忘了回答這個問題,因為我在問它幾個小時后解決了這個問題,但你可以將“.UseWindowsService()”添加到 Host.CreateDefaultBuilder(args) 行。 例如:

 public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseWindowsService()                     //<==== THIS LINE
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            })
            .ConfigureLogging(logging =>
            {
                logging.ClearProviders();
                logging.SetMinimumLevel(LogLevel.Trace);
            })
            .UseNLog();

就我而言,我的主機構建器設置中確實包含了“UseWindowsService()”語句。 不過,我有一個配置在多行爆發了,問題是,在開發過程中的某個時刻,我放在:

UseConsoleLifetime()

語句在代碼中進一步混合。 一旦我弄清楚發生了什么,使用以下部分代碼塊解決了這個問題:

        var hostBuilder = Host.CreateDefaultBuilder(args);
        if (WindowsServiceHelpers.IsWindowsService())
        {
            hostBuilder.UseWindowsService();
        }
        else
        {
            hostBuilder.UseConsoleLifetime();
        }

請注意,WindowsServiceHelpers 是“Microsoft.Extensions.Hosting.WindowsServices”命名空間中的靜態類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM