MVC 6 устанавливается как служба Windows (ASP.NET Core 1.0.0)

ОБНОВЛЕНИЕ - 26 июля 2016 г.

Я добавил решение к этому в 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 для запуска своего веб-приложения из Консольного приложения. Затем он может быть создан как исполняемый файл и установлен как служба Windows.

Есть ли способ сделать это с помощью веб-приложения ASP.NET 5 MVC 6?

Ответы

Ответ 1

По сравнению с последними библиотеками ASP.NET Core Version 1.0.0 это несколько упрощено.

Существует открытая дискуссия по этой теме на странице ASP.NET GitHub.

Все приложения ASP.NET Core теперь являются консольными приложениями, и есть новая библиотека для размещения в качестве службы Windows, которая работает на полной платформе .NET(что имеет смысл, так как вся эта проблема предполагает веб-сервер Windows).

Нам нужно создать новый 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.WindowsServices lib.

Для установки в качестве службы вам просто нужно запустить следующую команду из командной строки администратора:

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

Пожалуйста, клонируйте и просмотрите рабочую версию моего репозитория GitHub.

Надеюсь, это поможет:)

Ответ 2

Вы можете запустить приложение DNX в качестве службы Windows, однако вы не можете напрямую запустить CMD файл. Вы получите сообщение об ошибке: "Служба не ответила на запрос запуска или контроля своевременно". Вы можете напрямую указать dnx.exe и передать папку проекта и команду в качестве аргументов.

Прочитайте это сообщение для более подробной информации: http://taskmatics.com/blog/run-dnx-applications-windows-service/

Как только у вас настроено приложение. Вы можете загружать ASP.NET из метода OnStart службы. Для этого вы можете использовать WebHostBuilder из Microsoft.AspNet.Hosting.

Наконец, вы можете убедиться, что приложение все еще запущено в VS, передав аргумент (например, "не-сервис" ) методу Main и проверьте, что перед вызовом ServiceBase.Run, и если он присутствует, вы можете напрямую позвонить OnStart вместо. Свойства проекта дают вам возможность передавать аргументы при работе в VS.

UPDATE:

Существует следующее сообщение, которое основывается на предыдущем. В нем показано, как запустить ASP.NET 5 со статическими файлами и MVC 6 в службе Windows. Ссылка находится здесь: http://taskmatics.com/blog/host-asp-net-in-a-windows-service/

Ответ 3

ОБНОВЛЕНИЕ: Кажется, что появится версия хоста Windows Service, входящая в RC2. См. этот комментарий GitHub для получения дополнительной информации и этот ответ.

Я боюсь, что для этого нет ответа. Я также изучал это, и лучший способ сделать это - развернуть свой проект в известном месте на диске и иметь службу Windows, чтобы развернуть процесс, который вызывает cmd файл. Таким образом, служба Windows будет действовать только как сторожевой таймер.

Я надеюсь получить некоторые сообщения в блоге и образцы на этом, поскольку я изучал это с точки зрения развертывания. Здесь также открыто обсуждение: https://github.com/aspnet/Home/issues/465

Ответ 4

Стоит посмотреть https://github.com/aspnet/Hosting/tree/dev/src/Microsoft.AspNet.Hosting.WindowsServices

Кажется, что команда ASP.NET работает над собственной поддержкой для размещения приложений ASP.NET MVC 6 в службах Windows.

Вот простой 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();
    }
}