我尝试使用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访问服务时没有响应。
这里缺少什么?
答案 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)
当我的服务在本地系统帐户下运行时,我会出现此问题。如果我在服务下添加管理员作为登录帐户,一切正常。
对我来说似乎是权限问题。