Невозможно получить доступ к службе Netcore при регистрации в качестве службы Windows - PullRequest
0 голосов
/ 21 октября 2018

Я пытаюсь запустить простой пример веб-API, используя Netcore в качестве службы Windows.Однако, если я запускаю это как консольное приложение, это нормально, и я могу получить к нему доступ через браузер.Но после установки приложения netcore в качестве службы оно не доступно через браузер.Есть идеи, что мне здесь не хватает?

Это мой код:

public class Program
{
    public static void Main(string[] args)
    {
        // following works if I use Run() and execute on commandline
        // instead of calling RunAsService()
        CreateWebHostBuilder(args).Build().RunAsService();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

Как видите ... ничего особенного здесь нет.Фактически, это код, сгенерированный Visual Studio при использовании скелета asp.netcore.

    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.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

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

            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }

С сгенерированным контроллером это должно вернуть некоторые значения в виде текстовой распечатки в api / values.Поэтому я просто звоню https://localhost:5001/api/values.

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    // GET api/values
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // GET api/values/5
    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
        return "value";
    }

    // POST api/values
    [HttpPost]
    public void Post([FromBody] string value)
    {
    }

    // PUT api/values/5
    [HttpPut("{id}")]
    public void Put(int id, [FromBody] string value)
    {
    }

    // DELETE api/values/5
    [HttpDelete("{id}")]
    public void Delete(int id)
    {
    }
}

Каким-то образом это работает как консоль, но не как служба.

Я использую команду

dotnet publish -c Release -r win10-x64 --self-contained

, поэтому существует WebApplication1.exe (в соответствии с именем тестового проекта), созданный в папке публикации (вместе с зависимостями).

Затем я регистрирую этот exe-файл как службу

sc create "TestService" binPath= "C:\Projects\Playground\WebApplication1\bin\Release\netcoreapp2.1\win10-x64\publish\WebApplication1.exe"

, а затем вызываю

sc start "TestService"

Кажется, работает.Тем не менее, я не получаю ответа при попытке доступа к сервису через URL.

Чего здесь не хватает?

1 Ответ

0 голосов
/ 23 октября 2018

Как показывает мой тест, в Host ASP.NET Core в службе Windows что-то отсутствует.

Сначала я предлагаю вам проверить, можете ли вы получить доступ к http://localhost:5000/api/values.

Для https потребуется доступ к dev-сертификату, который обычно устанавливается в текущем хранилище пользователя.Если вы не изменили учетную запись службы после создания службы, она будет работать под Local System Account, что не приведет к доступу к сертификату.

В качестве решения вы можете попробовать запустить службу под вашим User Account.

Другой способ - попытаться настроить сертификат, как показано ниже:

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

        return WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((context, config) =>
            {
                // Configure the app here.
            })
            .UseKestrel((context, options) =>
            {
                options.ListenAnyIP(5001, listenOptions =>
                {
                    listenOptions.UseHttps(httpsOptions =>
                    {
                        var cert = CertificateLoader.LoadFromStoreCert(
                            "localhost", "My", StoreLocation.LocalMachine,
                            allowInvalid: true);
                        httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
                        {
                            return cert;
                        };
                    });
                });
            })
            .UseContentRoot(pathToContentRoot)
            .UseStartup<Startup>();
    }
...