public static int Run(Action <HostConfigurator <SERVICE> > runAction)
        {
            Directory.SetCurrentDirectory(PlatformServices.Default.Application.ApplicationBasePath);

            var innerConfig = new HostConfiguration <SERVICE>();

            innerConfig.Action = ActionEnum.RunInteractive;
            innerConfig.Name   = typeof(SERVICE).FullName;

            innerConfig.ExtraArguments = Parser.Parse(config =>
            {
                config.AddParameter(new CmdArgParam()
                {
                    Key         = "username",
                    Description = "Username for the service account",
                    Value       = val =>
                    {
                        innerConfig.Username = val;
                    }
                });
                config.AddParameter(new CmdArgParam()
                {
                    Key         = "password",
                    Description = "Password for the service account",
                    Value       = val =>
                    {
                        innerConfig.Password = val;
                    }
                });
                config.AddParameter(new CmdArgParam()
                {
                    Key         = "name",
                    Description = "Service name",
                    Value       = val =>
                    {
                        innerConfig.Name = val;
                    }
                });
                config.AddParameter(new CmdArgParam()
                {
                    Key         = "description",
                    Description = "Service description",
                    Value       = val =>
                    {
                        innerConfig.Description = val;
                    }
                });
                config.AddParameter(new CmdArgParam()
                {
                    Key         = "displayName",
                    Description = "Service display name",
                    Value       = val =>
                    {
                        innerConfig.DisplayName = val;
                    }
                });
                config.AddParameter(new CmdArgParam()
                {
                    Key         = "action",
                    Description = "Installs the service. It's run like console application otherwise",
                    Value       = val =>
                    {
                        switch (val)
                        {
                        case "install":
                            innerConfig.Action = ActionEnum.Install;
                            break;

                        case "start":
                            innerConfig.Action = ActionEnum.Start;
                            break;

                        case "stop":
                            innerConfig.Action = ActionEnum.Stop;
                            break;

                        case "uninstall":
                            innerConfig.Action = ActionEnum.Uninstall;
                            break;

                        case "run":
                            innerConfig.Action = ActionEnum.Run;
                            break;

                        case "run-interactive":
                            innerConfig.Action = ActionEnum.RunInteractive;
                            break;

                        default:
                            Console.WriteLine("{0} is unrecognized, will run the app as console application instead");
                            innerConfig.Action = ActionEnum.RunInteractive;
                            break;
                        }
                    }
                });

                config.UseDefaultHelp();
                config.UseAppDescription("Sample microservice application");
            });

            if (string.IsNullOrEmpty(innerConfig.Name))
            {
                innerConfig.Name = typeof(SERVICE).FullName;
            }

            if (string.IsNullOrEmpty(innerConfig.DisplayName))
            {
                innerConfig.DisplayName = innerConfig.Name;
            }

            if (string.IsNullOrEmpty(innerConfig.Description))
            {
                innerConfig.Description = "No description";
            }

            var hostConfiguration = new HostConfigurator <SERVICE>(innerConfig);

            try
            {
                runAction(hostConfiguration);
                if (innerConfig.Action == ActionEnum.Run)
                {
                    innerConfig.Service = innerConfig.ServiceFactory(innerConfig.ExtraArguments,
                                                                     new MicroServiceController(() =>
                    {
                        var task = Task.Factory.StartNew(() =>
                        {
                            UsingServiceController(innerConfig, (sc, cfg) => StopService(cfg, sc));
                        });
                    }
                                                                                                ));
                }
                else if (innerConfig.Action == ActionEnum.RunInteractive)
                {
                    var consoleService = new InnerService(innerConfig.Name, () => Start(innerConfig), () => Stop(innerConfig));
                    var consoleHost    = new ConsoleServiceHost <SERVICE>(consoleService, innerConfig);

                    innerConfig.Service = innerConfig.ServiceFactory(innerConfig.ExtraArguments,
                                                                     new MicroServiceController(() =>
                    {
                        var task = Task.Factory.StartNew(() =>
                        {
                            consoleHost.StopService();
                        });
                    }
                                                                                                ));

                    // Return the console host run result, so we get some idea what failed if result is not OK
                    return((int)consoleHost.Run());
                }

                ConfigureService(innerConfig);

                return(0);
            }
            catch (Exception e)
            {
                Error(innerConfig, e);
                return(-1);
            }
        }
        public static int Run(Action <HostConfigurator <SERVICE> > runAction)
        {
            var innerConfig = new HostConfiguration <SERVICE>();

            innerConfig.Action = ActionEnum.RunInteractive;
            innerConfig.Name   = typeof(SERVICE).FullName;

            innerConfig.ExtraArguments = Parser.Parse(config =>
            {
                config.AddParameter(new CmdArgParam()
                {
                    Key         = "username",
                    Description = "Username for the service account",
                    Value       = val =>
                    {
                        innerConfig.Username = val;
                    }
                });
                config.AddParameter(new CmdArgParam()
                {
                    Key         = "password",
                    Description = "Password for the service account",
                    Value       = val =>
                    {
                        innerConfig.Password = val;
                    }
                });
                config.AddParameter(new CmdArgParam()
                {
                    Key         = "name",
                    Description = "Service name",
                    Value       = val =>
                    {
                        innerConfig.Name = val;
                    }
                });
                config.AddParameter(new CmdArgParam()
                {
                    Key         = "description",
                    Description = "Service description",
                    Value       = val =>
                    {
                        innerConfig.Description = val;
                    }
                });
                config.AddParameter(new CmdArgParam()
                {
                    Key         = "displayName",
                    Description = "Service display name",
                    Value       = val =>
                    {
                        innerConfig.DisplayName = val;
                    }
                });
                config.AddParameter(new CmdArgParam()
                {
                    Key         = "action",
                    Description = "Installs the service. It's run like console application otherwise",
                    Value       = val =>
                    {
                        switch (val)
                        {
                        case "install":
                            innerConfig.Action = ActionEnum.Install;
                            break;

                        case "start":
                            innerConfig.Action = ActionEnum.Start;
                            break;

                        case "stop":
                            innerConfig.Action = ActionEnum.Stop;
                            break;

                        case "uninstall":
                            innerConfig.Action = ActionEnum.Uninstall;
                            break;

                        case "run":
                            innerConfig.Action = ActionEnum.Run;
                            break;

                        case "run-interactive":
                            innerConfig.Action = ActionEnum.RunInteractive;
                            break;

                        default:
                            Console.WriteLine("{0} is unrecognized, will run the app as console application instead");
                            innerConfig.Action = ActionEnum.RunInteractive;
                            break;
                        }
                    }
                });

                config.UseDefaultHelp();
                config.UseAppDescription("Sample microservice application");
            });

            if (string.IsNullOrEmpty(innerConfig.Name))
            {
                innerConfig.Name = typeof(SERVICE).FullName;
            }

            if (string.IsNullOrEmpty(innerConfig.DisplayName))
            {
                innerConfig.DisplayName = innerConfig.Name;
            }

            if (string.IsNullOrEmpty(innerConfig.Description))
            {
                innerConfig.Description = "No description";
            }

            var hostConfiguration = new HostConfigurator <SERVICE>(innerConfig);

            try
            {
                runAction(hostConfiguration);
                if (innerConfig.Action == ActionEnum.Run || innerConfig.Action == ActionEnum.RunInteractive)
                {
                    innerConfig.Service = innerConfig.ServiceFactory(innerConfig.ExtraArguments);
                }
                ConfigureService(innerConfig);
                return(0);
            }
            catch (Exception e)
            {
                Error(innerConfig, e);
                return(-1);
            }
        }
        public static int Run(Action <HostConfigurator <SERVICE> > runAction)
        {
            var innerConfiguration = new HostConfiguration <SERVICE>(_trace)
            {
                Action = ActionEnum.RunInteractive,
                Name   = typeof(SERVICE).FullName
            };

            innerConfiguration.ExtraArguments = Parser.Parse(config =>
            {
                config.AddParameter(new CmdArgParam
                {
                    Key         = "username",
                    Description = "Username for the service account",
                    Value       = val =>
                    {
                        innerConfiguration.Username = val;
                    }
                });
                config.AddParameter(new CmdArgParam
                {
                    Key         = "password",
                    Description = "Password for the service account",
                    Value       = val =>
                    {
                        innerConfiguration.Password = val;
                    }
                });
                config.AddParameter(new CmdArgParam
                {
                    Key         = "name",
                    Description = "Service name",
                    Value       = val =>
                    {
                        innerConfiguration.Name = val;
                    }
                });
                config.AddParameter(new CmdArgParam
                {
                    Key         = "description",
                    Description = "Service description",
                    Value       = val =>
                    {
                        innerConfiguration.Description = val;
                    }
                });
                config.AddParameter(new CmdArgParam
                {
                    Key         = "displayName",
                    Description = "Service display name",
                    Value       = val =>
                    {
                        innerConfiguration.DisplayName = val;
                    }
                });
                config.AddParameter(new CmdArgParam
                {
                    Key         = "action",
                    Description = "Installs the service. It's run like console application otherwise",
                    Value       = val =>
                    {
                        switch (val)
                        {
                        case "install":
                            innerConfiguration.Action = ActionEnum.Install;
                            break;

                        case "start":
                            innerConfiguration.Action = ActionEnum.Start;
                            break;

                        case "stop":
                            innerConfiguration.Action = ActionEnum.Stop;
                            break;

                        case "uninstall":
                            innerConfiguration.Action = ActionEnum.Uninstall;
                            break;

                        case "run":
                            innerConfiguration.Action = ActionEnum.Run;
                            break;

                        case "run-interactive":
                            innerConfiguration.Action = ActionEnum.RunInteractive;
                            break;

                        default:
                            Console.WriteLine("{0} is unrecognized, will run the app as console application instead");
                            _trace.TraceEvent(TraceEventType.Warning, 2, "{0} is unrecognized, will run the app as console application instead");
                            innerConfiguration.Action = ActionEnum.RunInteractive;
                            break;
                        }
                    }
                });

                config.UseDefaultHelp();
                config.UseAppDescription("Sample microservice application");
            });

            if (string.IsNullOrEmpty(innerConfiguration.Name))
            {
                innerConfiguration.Name = typeof(SERVICE).FullName;
            }

            if (string.IsNullOrEmpty(innerConfiguration.DisplayName))
            {
                innerConfiguration.DisplayName = innerConfiguration.Name;
            }

            if (string.IsNullOrEmpty(innerConfiguration.Description))
            {
                innerConfiguration.Description = "No description";
            }

            var hostConfiguration = new HostConfigurator <SERVICE>(innerConfiguration);

            try
            {
                runAction?.Invoke(hostConfiguration);
                if (innerConfiguration.Action == ActionEnum.Run || innerConfiguration.Action == ActionEnum.RunInteractive)
                {
                    var controller = new MicroServiceController(
                        () =>
                    {
                        var task = Task.Factory.StartNew(() =>
                        {
                            UsingServiceController(innerConfiguration, (sc, cfg) => StopService(cfg, sc));
                        });
                        //task.Wait();
                    }
                        );
                    innerConfiguration.Service = innerConfiguration.ServiceFactory(innerConfiguration.ExtraArguments, controller);
                }
                ConfigureService(innerConfiguration);
                return(0);
            }
            catch (Exception e)
            {
                Error(innerConfiguration, e);
                return(-1);
            }
        }