ASP.NET 核心作为 Windows 服务 wwwroot 位置

ASP.NET Core as Windows service wwwroot location

我有一个 windows 服务应用程序,其中包含 ASP .NET Core

project.json 有 2 个命令:

"commands": {
    "web": "Microsoft.AspNet.Server.Kestrel",
    "service": "MyAppNamespace"
}

入口点class:

public class Program : ServiceBase
{
    IApplication _application;

    public Program(IServiceProvider serviceProvider)
    {

    }

    public void Main(string[] args)
    {
        Run(this);
    }

    protected override void OnStart(string[] args)
    {
        var configProvider = new MemoryConfigurationProvider();
        configProvider.Add("server.urls", "http://*:80");

        var config = new ConfigurationBuilder()
            .Add(configProvider)
            .AddEnvironmentVariables()
            .Build();

        _application = new WebHostBuilder(config)
            .UseServer("Microsoft.AspNet.Server.Kestrel")
            .UseStartup<Startup>()
            .Build()
            .Start();

        // my stuff bellow
    }

    protected override void OnStop()
    {
        _application?.Dispose();
    }
}

发布项目后我们有这个文件夹结构:

approot
logs
wwwroot

接下来我从控制台启动我的应用程序

dnx.exe -p "C:\MyProject\approot\src\MyProject" service

但是我们没有使用 "C:\MyProject\wwwroot" 中的 webroot 目录,而是与 project.json 相同,即 "C:\MyProject\approot\src\MyProject"

如果我通过这样的 "web" 命令启动应用程序:

dnx.exe -p "C:\MyProject\approot\src\MyProject" web

然后一切正常,但当然我的入口点被忽略了,我无法执行我的东西,运行 as service

project.json

{
  "version": "1.0.0-*",

  "dependencies": {
    "MicroORM": "1.0.7",
    "Microsoft.ApplicationInsights.AspNet": "1.0.0-rc1",
    "Microsoft.AspNet.Diagnostics": "1.0.0-rc1-final",
    "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
    "Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
    "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final",
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
    "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
    "Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-final",
    "Microsoft.Extensions.Configuration": "1.0.0-rc1-final",
    "Microsoft.Extensions.Configuration.FileProviderExtensions": "1.0.0-rc1-final",
    "Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-final",
    "Microsoft.Extensions.Logging": "1.0.0-rc1-final",
    "Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final",
    "Microsoft.Extensions.Logging.Debug": "1.0.0-rc1-final",
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-rc1-final",
    "Microsoft.AspNet.Authentication.Cookies": "1.0.0-rc1-final",
    "Npgsql": "3.0.5",
    "ObjectPool": "1.0.0"
  },

  "commands": {
    "web": "Microsoft.AspNet.Server.Kestrel --server.urls=http://*:80",
    "service": "MikroBill"
  },

  "frameworks": {
    "dnx46": {
      "frameworkAssemblies": {
        "System.Data": "4.0.0.0",
        "System.ServiceProcess": "4.0.0.0"
      }
    }
  },

  "exclude": [
    "wwwroot",
    "node_modules"
  ],
  "publishExclude": [
    "**.user",
    "**.vspscc"
  ],
  "scripts": {
    "prepublish": [ "npm install", "bower install", "gulp clean", "gulp min" ]
  }
}

更简短的回答

我们可以将 webroot 键添加到我们的 MemoryConfigurationProvider:

configProvider.Add("webroot", "relative-path-to-web-root");

或者我们可以用 ConfigurationBuilder 注册我们的 hosting.json 文件:

config.AddJsonFile("hosting.json", optional: true)

例子

protected override void OnStart(string[] args)
{
    var configProvider = new MemoryConfigurationProvider();
    configProvider.Add("server.urls", "http://localhost:5000");
    configProvider.Add("webroot", "./../../../my-root");

    var config = new ConfigurationBuilder()
        .Add(configProvider)
        .AddJsonFile("hosting.json", optional: true)
        .Build();

    _application = new WebHostBuilder(config)
        .UseServer("Microsoft.AspNet.Server.Kestrel")
        .UseStartup<Program>()
        .Build()
        .Start();
}

更长的答案

当我们将 ConfigurationBuilder 传递给 WebHostBuilder 构造函数时,我们不再免费获得默认设置。这是空的 WebHostBuilder 构造函数。

public WebHostBuilder()
    : this(config: new ConfigurationBuilder().Build()) { }

大概是用了WebHostConfiguration.GetDefault的方法,给我们添加了hosting.json文件。

public static IConfiguration GetDefault(string[] args)
{
    // code omitted for clarity

    var configBuilder = new ConfigurationBuilder()
        .AddInMemoryCollection(defaultSettings)
        .AddJsonFile(WebHostDefaults.HostingJsonFile, optional: true)
        .AddEnvironmentVariables(prefix:
           WebHostDefaults.EnvironmentVariablesPrefix);

    // code omitted for clarity

    return configBuilder.Build();
}

我们可以在我们的代码中做同样的事情。 Here is a sample for good measure.