简体   繁体   中英

Unable to access netcore service when registered as windows service

I try to run a simple web api sample using netcore as windows service. However, if I run this as console app it is fine and I can access it through the browser. But after installing the netcore app as service it is not accessible through the browser. Any ideas what I miss here?

This is my code:

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>();
}

As you see… nothing special here. In fact, this is the code generated by Visual Studio when using the asp.netcore skeleton.

    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();
        }
    }

With the generated controller this should return some values as text printout under api/values. So I just call 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)
    {
    }
}

Somehow this works as console but not as service.

I use the command

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

so there is a WebApplication1.exe (according to the test project name) created in the publish folder (together with dependencies).

Then I register this exe as service

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

and then call

sc start "TestService"

It seems to work. However, I get no response when trying to access the service through the url.

What is missing here?

As my test, it seems there is something missing in Host ASP.NET Core in a Windows Service .

First, I suggest you check whether you could access http://localhost:5000/api/values .

For https , it will need to access dev certificate which is normally installed under current user store. If you did not change the Service Account after create the service, it will run under Local System Account which will fail to access the certificate.

For a solution, you could try running the service under your User Account .

For another way, you could try to configure the certificate like below:

        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>();
    }

There is a different way to create service in Aspnet core. IHostedService interface is used to create services like Windows Service .

Use IHostedService in the WebApi project and deploy it as a Web project. As soon as the API project will start your service gets started.

Service Code: Create a Class MyHostedService.cs and put the below code into this class.

Class

public class MyHostedService:IHostedService 
{
  private Timer _timer { get; set; }
}

Start

public Task StartAsync(CancellationToken cancellationToken)
{ 
    _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromMinutes(OrderExportPurgeTimeInterval));
    return Task.CompletedTask;
}   

Stop

public Task StopAsync(CancellationToken cancellationToken)
{
    _timer ?.Change(Timeout.Infinite, 0);
    return Task.CompletedTask;
}

Your DoWork

private void DoWork(object state)
{
    bool hasLock = false;
    try
      {
        Monitor.TryEnter(_locker, ref hasLock);
        if (hasLock)
        {
            PurgeProcessor.ProcessPurge().Wait();
        }
      }
      finally
      {
          if (hasLock) Monitor.Exit(_locker);
      }
 }

Startup.cs

services.AddHostedService<MyHostedService>();

I exhibit this issue when my service runs under the local system account. If I add the administrator under the service as the log-in account everything works.

Seems like a permissions issue to me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM