17

更新 - 2016 年 7 月 26 日

我在ASP.NET Core 1.0.0下面的答案中添加了解决方案。


我创建了一个简单的 MVC 6 应用程序并包含了 Microsoft.AspNet.WebListener 库,因此我可以在 IIS 之外托管。

来自 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"
}

当我发布它时,我可以运行 web.cmd 文件并让站点在控制台窗口中运行。伟大的!

但在 OWIN 中,您可以使用 TopShelf 从控制台应用程序启动您的 Web 应用程序。然后可以将其构建为可执行文件并作为 Windows 服务安装。

有没有办法使用 ASP.NET 5 MVC 6 Web 应用程序来做到这一点?

4

4 回答 4

10

您可以将 DNX 应用程序作为 Windows 服务运行,但是不能直接运行 CMD 文件。您将收到一条错误消息:“服务未及时响应启动或控制请求。” 您可以直接指向 dnx.exe 并将项目文件夹和命令作为参数传递。

阅读这篇文章了解更多详情:http ://taskmatics.com/blog/run-dnx-applications-windows-service/

一旦你设置了你的应用程序。您可以从服务的 OnStart 方法引导 ASP.NET。为此,您可以使用 Microsoft.AspNet.Hosting 中的 WebHostBuilder。

最后,您可以通过将参数(例如“非服务”)传递给 Main 方法并在调用 ServiceBase.Run 之前检查它,如果存在,您可以直接调用 OnStart,以确保应用程序仍然可以在 VS 中运行。项目的属性让您可以选择在 VS 中运行时传递参数。

更新:

有一个后续帖子建立在上述帖子的基础上。它展示了如何在 Windows 服务中运行带有静态文件的 ASP.NET 5 和 MVC 6。链接在这里:http ://taskmatics.com/blog/host-asp-net-in-a-windows-service/

于 2015-08-14T13:32:19.373 回答
6

从最新的 ASP.NET Core 版本 1.0.0 库开始,这现在有所简化。

ASP.NET GitHub 页面上有关于此主题的公开讨论。

所有 ASP.NET Core 应用程序现在都是控制台应用程序,并且有一个新库可以作为 Windows 服务托管,该服务在完整的 .NET 框架上运行(这是有道理的,因为整个问题都假设一个 Windows Web 服务器)。

我们需要创建一个新的ASP.NET Core Web Application (.NET Framework)

检查project.json文件以确保“框架”部分如下:

"frameworks": {
    "net461": {}
},

然后我们需要添加服务托管库Microsoft.AspNetCore.Hosting.WindowsServices并保存project.json以恢复包。

然后我们需要编辑program.cs文件并添加在调试中运行和作为服务运行的路径,代码如下:

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

.RunAsService()方法是Microsoft.AspNetCore.Hosting.WindowsServiceslib提供的扩展方法。

要安装为服务,您只需从管理员命令提示符处运行以下命令:

SC Create <service-name> binPath= "[PublishOutputPath]\mvc6-example.exe"

请在我的GitHub 存储库中克隆并查看工作版本。

我希望这有帮助 :)

于 2016-07-26T07:44:16.433 回答
5

更新: RC2似乎将提供一个 Windows 服务托管选项。有关更多信息和此答案,请参阅此 GitHub 评论

恐怕答案是否定的。我也一直在研究这个问题,最好的方法是将您的项目部署到磁盘上的已知位置,并使用 Windows 服务来启动调用 cmd 文件的进程。这样,Windows 服务将仅充当看门狗。

我希望得到一些关于此的博客文章和示例,因为我一直在研究这方面的部署。这里还有一个公开讨论:https ://github.com/aspnet/Home/issues/465

于 2015-05-16T19:25:11.193 回答
3

值得一看https://github.com/aspnet/Hosting/tree/dev/src/Microsoft.AspNet.Hosting.WindowsServices

似乎 ASP.NET 团队正在为在 Windows 服务中托管 ASP.NET MVC 6 应用程序提供本地支持。

这是一个简单ServiceBase的托管 ASP.NET MVC 6 应用程序:

/// <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();
    }
}
于 2016-01-02T15:47:28.343 回答