Reputation: 1775
UPDATE - 26th July 2016
I have added the solution to this in ASP.NET Core 1.0.0
in the answers below.
I have created a simple MVC 6 app and have included the Microsoft.AspNet.WebListener library so I can host outside of IIS.
From project.json:
"dependencies": {
"Microsoft.AspNet.Server.WebListener": "1.0.0-beta4",
"Microsoft.AspNet.Mvc": "6.0.0-beta4"
},
"commands": {
"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000"
}
When I publish this I can run the web.cmd file and get the site running in a console window. Great!
But in OWIN you can use TopShelf to launch your web app from a Console Application. This can then be built as an executable and installed as a Windows Service.
Is there a way to do this with an ASP.NET 5 MVC 6 web app?
Upvotes: 17
Views: 5366
Reputation: 1775
As of the latest ASP.NET Core Version 1.0.0 libraries this is now somewhat simplified.
There is an open discussion on this topic on the ASP.NET GitHub page.
All ASP.NET Core applications are now Console Applications and there is a new library to host as a Windows Service that runs on the full .NET framework (which makes sense as this whole problem assumes a Windows web server).
We need to create a new ASP.NET Core Web Application (.NET Framework)
Check the project.json
file to ensure that the "frameworks" section is as below:
"frameworks": {
"net461": {}
},
We need to then add the service hosting library Microsoft.AspNetCore.Hosting.WindowsServices
and save the project.json
to restore the package.
We then need to edit the program.cs
file and add paths for running in debug and running as a service, the code for this is as follows:
public static void Main(string[] args)
{
var isDebug = Debugger.IsAttached || ((IList)args).Contains("--debug");
string runPath;
if (isDebug)
runPath = Directory.GetCurrentDirectory();
else
{
var exePath = Process.GetCurrentProcess().MainModule.FileName;
runPath = Path.GetDirectoryName(exePath);
}
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(runPath)
.UseStartup<Startup>()
.Build();
if (isDebug)
host.Run();
else
host.RunAsService();
}
The .RunAsService()
method is an extension method provided by the Microsoft.AspNetCore.Hosting.WindowsServices
lib.
To install as a service you just need to run the following command from an Administrator command prompt:
SC Create <service-name> binPath= "[PublishOutputPath]\mvc6-example.exe"
Please clone and view the working version on my GitHub repository.
I hope this helps :)
Upvotes: 6
Reputation: 58494
UPDATE: It seems like there is going to be a Windows Service hosting option coming in with RC2. See this GitHub comment for more info and this answer.
I am afraid the answer is no for this. I have been looking into this as well and the best way to do this is to deploy your project into a known location on disk and have a Windows Service to spin up the process which calls the cmd file. This way, the Windows Service will only act as a watchdog.
I am hoping to get some blog posts and samples on this as I have been looking into this in terms of deployment. There is also an open discussion here: https://github.com/aspnet/Home/issues/465
Upvotes: 5
Reputation: 16983
It is worth looking at https://github.com/aspnet/Hosting/tree/dev/src/Microsoft.AspNet.Hosting.WindowsServices
It seems that ASP.NET team is working on native support for hosting ASP.NET MVC 6 applications within Windows Services.
Here is a simple ServiceBase
hosting an ASP.NET MVC 6 app:
/// <summary>
/// Provides an implementation of a Windows service that hosts ASP.NET.
/// </summary>
public class WebApplicationService : ServiceBase
{
private IWebApplication _application;
private IDisposable _applicationShutdown;
private bool _stopRequestedByWindows;
/// <summary>
/// Creates an instance of <c>WebApplicationService</c> which hosts the specified web application.
/// </summary>
/// <param name="application">The web application to host in the Windows service.</param>
public WebApplicationService(IWebApplication application)
{
_application = application;
}
protected sealed override void OnStart(string[] args)
{
OnStarting(args);
_application
.Services
.GetRequiredService<IApplicationLifetime>()
.ApplicationStopped
.Register(() =>
{
if (!_stopRequestedByWindows)
{
Stop();
}
});
_applicationShutdown = _application.Start();
OnStarted();
}
protected sealed override void OnStop()
{
_stopRequestedByWindows = true;
OnStopping();
_applicationShutdown?.Dispose();
OnStopped();
}
}
Upvotes: 3
Reputation: 131
You can run a DNX app as a Windows service, however, you can't run the CMD file directly. You will get an error saying the following: 'The service did not respond to the start or control request in a timely fashion.' You can point directly to dnx.exe and pass the project folder and command as arguments.
Read this post for a lot more detail: http://taskmatics.com/blog/run-dnx-applications-windows-service/
Once you have your app set up. You can bootstrap ASP.NET from the OnStart method of the service. To do this you can use WebHostBuilder from Microsoft.AspNet.Hosting.
Lastly, you can ensure the app is still runnable in VS by passing an argument (such as 'non-service') to the Main method and check that before calling ServiceBase.Run, and if present, you can call OnStart directly instead. The project's properties gives you the option to pass arguments when running in VS.
UPDATE:
There is a follow up post which builds upon the one above. It shows how to run ASP.NET 5 with static files and MVC 6 in a Windows service. The link is here: http://taskmatics.com/blog/host-asp-net-in-a-windows-service/
Upvotes: 10