注册为Windows服务后无法访问Netcore服务

时间:2018-10-20 22:55:44

标签: c# asp.net-core .net-core windows-services

我尝试使用netcore作为Windows服务运行一个简单的Web api示例。但是,如果我将其作为控制台应用程序运行,则可以,并且可以通过浏览器访问它。但是在将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

因此,在publish文件夹(以及相关性)中创建了一个WebApplication1.exe(根据测试项目名称)。

然后我将此exe注册为服务

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

然后致电

sc start "TestService"

似乎可行。但是,尝试通过url访问服务时没有响应。

这里缺少什么?

3 个答案:

答案 0 :(得分:0)

作为我的测试,似乎Host ASP.NET Core in a Windows Service中缺少某些内容。

首先,我建议您检查是否可以访问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>();
    }

答案 1 :(得分:0)

在Aspnet核心中有另一种创建服务的方式。 IHostedService 界面用于创建诸如 Windows服务之类的服务。

在WebApi项目中使用 IHostedService 并将其部署为Web项目。 API项目启动后,您的服务就会开始。

服务代码: 创建一个 MyHostedService.cs 类,并将以下代码放入此类。

课程

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

开始

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

停止

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

您的工作

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

答案 2 :(得分:0)

当我的服务在本地系统帐户下运行时,我会出现此问题。如果我在服务下添加管理员作为登录帐户,一切正常。

对我来说似乎是权限问题。