asp.net-corewindows-servicestopshelf

Create a Windows Service installer using .NET Core and command line


I created an ASP.NET Core Windows Service application using this sample: https://github.com/dotnet/AspNetCore.Docs/tree/master/aspnetcore/host-and-deploy/windows-service/samples/2.x/AspNetCoreService

Now, I want to install my service using command line, like "MyService.exe -install". I know that if I use "sc create" will works, but I want to install using my own application to install and configure the service as I want.

I found a sample using Toshelf package, but I am using WebHostBuilder and I trying to use Custom Service configuration. The service install, but when I start it doesn`t work.

I am using .NET Core 2.2.

My configuration:

HostFactory.Run(x =>
            {
                x.Service<CustomWebHostService>(sc =>
                {
                    sc.ConstructUsing(() => new CustomWebHostService(host));

                    // the start and stop methods for the service
                    sc.WhenStarted(ServiceBase.Run);
                    sc.WhenStopped(s => s.Stop());
                });

                x.RunAsLocalSystem();
                x.StartAutomatically();

                x.SetServiceName("Teste Core");
                x.SetDisplayName("Teste ASP.NET Core Service");
                x.SetDescription("Teste ASP.NET Core as Windows Service.");
            });

My full source code: https://github.com/rkiguti/dotnetcore.windows-service


Solution

  • I changed my code like another sample and my services now runs as console application and as windows services. And it can be installed using command line "MyService.exe install".

    My program.cs file:

    class Program
    {
        public static void Main(string[] args)
        {
            HostFactory.Run(x =>
            {
                x.Service<ApplicationHost>(sc =>
                {
                    sc.ConstructUsing(() => new ApplicationHost());
    
                    // the start and stop methods for the service
                    sc.WhenStarted((svc, control) =>
                    {
                        svc.Start(control is ConsoleRunHost, args);
                        return true;
                    });
                    sc.WhenStopped(s => s.Stop());
                    sc.WhenShutdown(s => s.Stop());
                });
    
                x.UseNLog();
                x.RunAsLocalSystem();
                x.StartAutomatically();
    
                x.SetServiceName("Test Core");
                x.SetDisplayName("Test ASP.NET Core Service");
                x.SetDescription("Test ASP.NET Core as Windows Service.");
            });
        }
    }
    

    My ApplicationHost.cs file:

    public class ApplicationHost
    {
        private IWebHost _webHost;
    
        public void Start(bool launchedFromConsole, string[] args)
        {
            if (!launchedFromConsole)
            {
                var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
                var pathToContentRoot = Path.GetDirectoryName(pathToExe);
                Directory.SetCurrentDirectory(pathToContentRoot);
            }
    
            IWebHostBuilder webHostBuilder = CreateWebHostBuilder(args);
            _webHost = webHostBuilder.Build();
    
            _webHost.Start();
    
            // print information to console
            if (launchedFromConsole)
            {
                var serverAddresses = _webHost.ServerFeatures.Get<IServerAddressesFeature>()?.Addresses;
                foreach (var address in serverAddresses ?? Array.Empty<string>())
                {
                    Console.WriteLine($"Listening on: {address}");
                    Console.WriteLine("Press Ctrl+C to end the application.");
                }
            }
        }
    
        public void Stop()
        {
            _webHost?.Dispose();
        }
    
        private IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .ConfigureLogging((hostingContext, logging) =>
                {
                    logging.AddEventLog();
                })
                .ConfigureAppConfiguration((context, config) =>
                {
                    // Configure the app here.
                })
                .UseUrls("http://+:8000")
                .UseStartup<Startup>();
    }
    

    The full source code: https://github.com/rkiguti/dotnetcore.windows-service