public static int Run(string[] args, string name, IService service, ServiceHostingControl hostingControl = null)
        {
            Directory.SetCurrentDirectory(AppContext.BaseDirectory);

            var selfLogger = false;

            if (Log.Logger == Logger.None)
            {
                Log.Logger = BuildConfiguration(args).CreateNewLogger(name);
                selfLogger = true;
            }

            Log.Logger.Information($"Using current directory: {Directory.GetCurrentDirectory()}");

            var result = -1;

            try
            {
                result = CanRunToshelf()
                    ? RunTopshelf(args, name, service, hostingControl)
                    : RunPlainConsole(name, service, hostingControl);
            }
            catch (Exception e)
            {
                Log.Logger.Error(e, "Failure running service {name}", name);
            }

            if (selfLogger)
            {
                Log.CloseAndFlush();
            }

            return(result);
        }
        private static int RunPlainConsole(string name, IService service, ServiceHostingControl hostingControl)
        {
            Log.Information("Using plain console to run service");

            try
            {
                Console.Title = name;

                service.Start();
            }
            catch (Exception e)
            {
                Log.ForContext(typeof(ServiceHost)).Fatal(e, "Failed to run service");
                return(-1);
            }

            var stop = new AutoResetEvent(false);

            if (hostingControl != null)
            {
                hostingControl.HostControl = new ConsoleHostControl(stop);
            }

            Console.CancelKeyPress += (sender, eventArgs) =>
            {
                stop.Set();
            };

            stop.WaitOne();

            try
            {
                service.Stop();
            }
            catch (Exception e)
            {
                Log.ForContext(typeof(ServiceHost)).Error(e, "Failed to properly stop service");
                return(-2);
            }

            return(0);
        }
        private static int RunTopshelf(IReadOnlyList <string> args, string name, IService service, ServiceHostingControl hostingControl)
        {
            Log.Information("Using Topshelf to run service");

            var rc = HostFactory.Run(x =>
            {
                if (hostingControl?.CustomConfiguration == null)
                {
                    ValidateCommandLine(x, args);
                }
                else
                {
                    hostingControl.CustomConfiguration.Invoke(x);
                }
                x.Service <IService>(sc =>
                {
                    sc.ConstructUsing(() => service);

                    sc.WhenStarted((s, c) =>
                    {
                        if (hostingControl != null)
                        {
                            hostingControl.HostControl = c;
                        }

                        try
                        {
                            s.Start();
                        }
                        catch (Exception e)
                        {
                            Log.ForContext(typeof(ServiceHost)).Fatal(e, "Failed to start service");
                            throw;
                        }

                        return(true);
                    });

                    sc.WhenStopped(tc => tc.Stop());
                });

                x.UseSerilog();
                x.SetDisplayName(name);
                x.SetServiceName(name);

                x.EnableServiceRecovery(r =>
                {
                    r.SetResetPeriod(1);
                    r.RestartService(0);
                    r.TakeNoAction();
                });
            });

            return((int)Convert.ChangeType(rc, rc.GetTypeCode()));
        }