【问题标题】:.net core hosted as windows service - How to use configuration files?作为 Windows 服务托管的 .net 核心 - 如何使用配置文件?
【发布时间】:2018-09-13 18:31:38
【问题描述】:

我有一个希望作为 Windows 服务运行的 .Net Core 2 WebAPI。 默认情况下,服务在http://localhost:5000 上运行。当我在本地运行它时,我使用hosting.json 文件在那里设置 IP 和端口,但由于某种原因,当我尝试使用配置文件时服务不会启动。

这是我的代码:

public static void Main(string[] args)
{
    var config = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile("hosting.json", optional: false, reloadOnChange: true)
        .AddCommandLine(args)
        .Build();

    if (Debugger.IsAttached || args.Contains("--console"))
        BuildWebHost(config, args).Run();
    else
        BuildServiceWebHost(config, args).RunAsService();
}

public static IWebHost BuildWebHost(IConfigurationRoot config, string[] args)
{
    return WebHost.CreateDefaultBuilder(args)
        .UseConfiguration(config)
        .UseStartup<Startup>()
        .Build();
}

public static IWebHost BuildServiceWebHost(IConfigurationRoot config, string[] args)
{
    var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
    var pathToContentRoot = Path.GetDirectoryName(pathToExe);

    var webHostArgs = args.Where(arg => arg != "--console").ToArray();

    return WebHost.CreateDefaultBuilder(webHostArgs)
        .UseConfiguration(config)
        .UseContentRoot(pathToContentRoot)
        .UseStartup<Startup>()
        .Build();
}

它在 Debug 上运行(例如,不是作为服务),但是当我将它设置为 Windows 服务 sc create MyService binPath="..." 并尝试运行它时,我收到了这个错误:

Windows could not start the MyService service on Local Computer.

Error 1053:
The service did not respond to the start or control request in a timely fashion.

我检查了Event Viewer,发现了这个错误: Exception Info: System.IO.FileNotFoundException: The configuration file 'appsettings.json' was not found and is not optional. The physical path is 'C:\WINDOWS\system32\appsettings.json'.

作为服务运行时,如何将配置文件的路径设置为与.exe 相同?

【问题讨论】:

  • 您找到解决方案了吗?我正在为同样的事情苦苦挣扎
  • @tony09uk - 我已经发布了答案,希望对您有所帮助。

标签: asp.net-core-2.0


【解决方案1】:

我已经设法通过以下方式解决了这个问题:

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;

namespace WebAPI
{
    public class Program
    {
        public static void Main(string[] args)
        {
            if (Debugger.IsAttached || args.Contains("--console"))
                BuildWebHost(args).Run();
            else
            {
                var webHost = BuildServiceWebHost(args);

                var webHostService = new CustomWebHostService(webHost);
                ServiceBase.Run(webHostService);
            }
        }

        public static IWebHost BuildWebHost(string[] args)
        {
            var config = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile("hosting.json", optional: false, reloadOnChange: true)
                .AddCommandLine(args)
                .Build();

            return WebHost.CreateDefaultBuilder(args)
                .UseConfiguration(config)
                .UseStartup<Startup>()
                .Build();
        }

        public static IWebHost BuildServiceWebHost(string[] args)
        {
            var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
            var pathToContentRoot = Path.GetDirectoryName(pathToExe);

            var webHostArgs = args.Where(arg => arg != "--console").ToArray();

            JObject hosting = JsonConvert.DeserializeObject<JObject>(File.ReadAllText($"{pathToContentRoot}/hosting.json"));
            return WebHost.CreateDefaultBuilder(webHostArgs)
                .UseUrls(hosting.Value<string>("server.urls"))
                .UseContentRoot(pathToContentRoot)
                .UseStartup<Startup>()
                .Build();
        }
    }
}

希望这可以帮助其他遇到同样问题的人。

【讨论】:

  • ` var pathToExe = Process.GetCurrentProcess().MainModule.FileName; var pathToContentRoot = Path.GetDirectoryName(pathToExe);`,我搜索这个脚本很多时间,干得好,tnx。
  • 不错!您还可以像这样获取内容根目录的路径:var pathToContentRoot = System.AppDomain.CurrentDomain.BaseDirectory
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-08
  • 2021-05-19
  • 2020-09-26
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
相关资源
最近更新 更多