예제 #1
0
        void CatchUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            _settings.ExceptionCallback?.Invoke((Exception)e.ExceptionObject);

            _log.Fatal("The service threw an unhandled exception", (Exception)e.ExceptionObject);

            HostLogger.Shutdown();

            if (e.IsTerminating)
            {
                _exitCode = TopshelfExitCode.UnhandledServiceException;
                _exit.Set();

#if !NET35
                // it isn't likely that a TPL thread should land here, but if it does let's no block it
                if (Task.CurrentId.HasValue)
                {
                    return;
                }
#endif

                // this is evil, but perhaps a good thing to let us clean up properly.
                int deadThreadId = Interlocked.Increment(ref _deadThread);
                Thread.CurrentThread.IsBackground = true;
                Thread.CurrentThread.Name         = "Unhandled Exception " + deadThreadId.ToString();
                while (true)
                {
                    Thread.Sleep(TimeSpan.FromHours(1));
                }
            }
        }
        public bool RunAsAdministrator()
        {
            if (Environment.OSVersion.Version.Major == 6)
            {
                string commandLine = CommandLine.Replace("--sudo", "");

                var startInfo = new ProcessStartInfo(Assembly.GetEntryAssembly().Location, commandLine)
                {
                    Verb            = "runas",
                    UseShellExecute = true,
                    CreateNoWindow  = true,
                };

                try
                {
                    HostLogger.Shutdown();

                    Process process = Process.Start(startInfo);
                    process.WaitForExit();

                    return(true);
                }
                catch (Win32Exception ex)
                {
                    _log.Debug("Process Start Exception", ex);
                }
            }

            return(false);
        }
예제 #3
0
        public TopshelfExitCode Run()
        {
            Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);

            AppDomain.CurrentDomain.UnhandledException += CatchUnhandledException;

            if (_environment.IsServiceInstalled(_settings.ServiceName))
            {
                if (!_environment.IsServiceStopped(_settings.ServiceName))
                {
                    _log.ErrorFormat("The {0} service is running and must be stopped before running via the console",
                                     _settings.ServiceName);

                    return(TopshelfExitCode.ServiceAlreadyRunning);
                }
            }

            bool started = false;

            try
            {
                _log.Debug("Starting up as a console application");

                _exit = new ManualResetEvent(false);

                Console.Title           = _settings.DisplayName;
                Console.CancelKeyPress += HandleCancelKeyPress;

                if (!_serviceHandle.Start(this))
                {
                    throw new TopshelfException("The service failed to start (return false).");
                }

                started = true;

                _log.InfoFormat("The {0} service is now running, press Control+C to exit.", _settings.ServiceName);

                _exit.WaitOne();
            }
            catch (Exception ex)
            {
                _log.Error("An exception occurred", ex);

                return(TopshelfExitCode.AbnormalExit);
            }
            finally
            {
                if (started)
                {
                    StopService();
                }

                _exit.Close();
                (_exit as IDisposable).Dispose();

                HostLogger.Shutdown();
            }

            return(TopshelfExitCode.Ok);
        }
예제 #4
0
        private void CatchUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            _logWriter.Fatal(string.Format(Resources.UnhandledException, _settings.ServiceName), (Exception)e.ExceptionObject);

            HostLogger.Shutdown();

            if (e.IsTerminating)
            {
                _exitCode = TopshelfExitCode.UnhandledServiceException;

                SetStopSignal();

                // Author Topshelf: it isn't likely that a TPL thread should land here, but if it does let's no block it
                if (!Task.CurrentId.HasValue)
                {
                    // Author Topshelf: this is evil, but perhaps a good thing to let us clean up properly

                    var deadThreadId = Interlocked.Increment(ref _deadThread);

                    Thread.CurrentThread.IsBackground = true;
                    Thread.CurrentThread.Name         = "Unhandled Exception " + deadThreadId;

                    while (true)
                    {
                        Thread.Sleep(TimeSpan.FromHours(1));
                    }
                }
            }
        }
예제 #5
0
        void CatchUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            _log.Fatal("The service threw an unhandled exception", (Exception)e.ExceptionObject);

            HostLogger.Shutdown();

//            // IF not terminating, then no reason to stop the service?
//            if (!e.IsTerminating)
//                return;
//          This needs to be a configuration option to avoid breaking compatibility

            ExitCode            = (int)TopshelfExitCode.UnhandledServiceException;
            _unhandledException = e.ExceptionObject as Exception;

            Stop();


#if !NET35
            // it isn't likely that a TPL thread should land here, but if it does let's no block it
            if (Task.CurrentId.HasValue)
            {
                return;
            }
#endif

            int deadThreadId = Interlocked.Increment(ref _deadThread);
            Thread.CurrentThread.IsBackground = true;
            Thread.CurrentThread.Name         = "Unhandled Exception " + deadThreadId.ToString();
            while (true)
            {
                Thread.Sleep(TimeSpan.FromHours(1));
            }
        }
예제 #6
0
 public TopshelfExitCode Run()
 {
     try
     {
         _log.Debug("Starting application.");
         _exitCode = TopshelfExitCode.Ok;
         if (_serviceHandle.Start(this) == false)
         {
             throw new TopshelfException("The application failed to start (return false).");
         }
         _log.InfoFormat("The {0} application is now running.", _settings.ServiceName);
     }
     catch (Exception ex)
     {
         var exceptionCallback = _settings.ExceptionCallback;
         if (exceptionCallback != null)
         {
             Exception exception = ex;
             exceptionCallback(exception);
         }
         _log.Error("An exception occurred", ex);
         HostLogger.Shutdown();
         return(TopshelfExitCode.AbnormalExit);
     }
     return(_exitCode);
 }
예제 #7
0
        public TopshelfExitCode Run()
        {
            Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
            //			AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(this.CatchUnhandledException);
            if (this._environment.IsServiceInstalled(this._settings.ServiceName) && !this._environment.IsServiceStopped(this._settings.ServiceName))
            {
                this._log.ErrorFormat("The {0} service is running and must be stopped before running as winforms application", new object[]
                {
                    this._settings.ServiceName
                });
                return(TopshelfExitCode.ServiceAlreadyRunning);
            }

            try
            {
                this._log.Debug("Starting up as a winforms application");

                var form = new Form();
                form.Text = this._settings.DisplayName;

                var btn = new Button();

                if (_Autostart)
                {
                    Start();
                }

                btn.Click += (s, e) =>
                {
                    if (_IsRunning == 1)
                    {
                        Stop();
                        btn.Text = "Start";
                    }
                    else
                    {
                        Start();
                        btn.Text = "Stop";
                    }
                };
                btn.Text   = _IsRunning == 1 ? "Stop" : "Start";
                btn.Dock   = DockStyle.Fill;
                btn.Parent = form;

                Application.Run(form);
                return(TopshelfExitCode.Ok);
            }
            catch (Exception exception)
            {
                this._log.Error("An exception occurred", exception);
                return(TopshelfExitCode.AbnormalExit);
            }
            finally
            {
                Stop();
                HostLogger.Shutdown();
            }
        }
예제 #8
0
        /// <summary>
        ///   Configures and runs a new service host, handling any exceptions and writing them to the log.
        /// </summary>
        /// <param name="configureCallback"> Configuration method to call </param>
        /// <returns> Returns the exit code of the process that should be returned by your application's main method </returns>
        public static TopshelfExitCode Run(Action <HostConfigurator> configureCallback)
        {
            try
            {
                return(New(configureCallback).Run());
            }
            catch (Exception ex)
            {
                HostLogger.Get(typeof(HostFactory)).Error("The service terminated abnormally", ex);
                HostLogger.Shutdown();

                return(TopshelfExitCode.AbnormalExit);
            }
        }
예제 #9
0
        private static void StartServiceAsync(object state)
        {
            var service = (ServiceProxy)state;

            try
            {
                service.Start();
            }
            catch (Exception ex)
            {
                HostLogger.Get(typeof(Run)).Fatal("Service could not start", ex);
                HostLogger.Shutdown();
                throw;
            }
        }
예제 #10
0
        void CatchUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            _settings.ExceptionCallback?.Invoke((Exception)e.ExceptionObject);

            if (_settings.UnhandledExceptionPolicy == UnhandledExceptionPolicyCode.TakeNoAction)
            {
                return;
            }

            _log.Fatal("The service threw an unhandled exception", (Exception)e.ExceptionObject);

            if (_settings.UnhandledExceptionPolicy == UnhandledExceptionPolicyCode.LogErrorOnly)
            {
                return;
            }

            HostLogger.Shutdown();

//            // IF not terminating, then no reason to stop the service?
//            if (!e.IsTerminating)
//                return;
//          This needs to be a configuration option to avoid breaking compatibility

            ExitCode            = (int)TopshelfExitCode.AbnormalExit;
            _unhandledException = (Exception)e.ExceptionObject;

            Stop();


            // it isn't likely that a TPL thread should land here, but if it does let's no block it
            if (Task.CurrentId.HasValue)
            {
                return;
            }

            int deadThreadId = Interlocked.Increment(ref _deadThread);

            Thread.CurrentThread.IsBackground = true;
            Thread.CurrentThread.Name         = "Unhandled Exception " + deadThreadId;
            while (true)
            {
                Thread.Sleep(TimeSpan.FromHours(1));
            }
        }
예제 #11
0
        public TopshelfExitCode Run()
        {
            Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);

            AppDomain.CurrentDomain.UnhandledException += CatchUnhandledException;

            if (_environment.IsServiceInstalled(_settings.ServiceName))
            {
                _log.ErrorFormat("The {0} service is installed as a service", _settings.ServiceName);
                return(TopshelfExitCode.ServiceAlreadyInstalled);
            }

            try
            {
                _log.Debug("Starting up as a console application");

                _exit = new ManualResetEvent(false);

                Console.CancelKeyPress += HandleCancelKeyPress;

                _serviceHandle.Start(this);

                _log.InfoFormat("The {0} service is now running, press Control+C to exit.", _settings.ServiceName);

                _exit.WaitOne();
            }
            catch (Exception ex)
            {
                _log.Error("An exception occurred", ex);

                return(TopshelfExitCode.AbnormalExit);
            }
            finally
            {
                StopService();

                _exit.Close();
                (_exit as IDisposable).Dispose();

                HostLogger.Shutdown();
            }

            return(TopshelfExitCode.Ok);
        }
예제 #12
0
        public static int Service <TService>()
            where TService : IService, new()
        {
            Type serviceType = typeof(TService);

            _serviceProxy = new ServiceProxy(serviceType);

            ProcessCustomCommand();

            if (!_startService)
            {
                return(0);
            }

            TopshelfExitCode code = RunServiceNormally <TService>(serviceType);

            HostLogger.Shutdown();
            return((int)code);
        }
예제 #13
0
        /// <summary>
        ///   Configures a new service host
        /// </summary>
        /// <param name="configureCallback"> Configuration method to call </param>
        /// <returns> A Topshelf service host, ready to run </returns>
        public static Host New(Action <HostConfigurator> configureCallback)
        {
            try
            {
                if (configureCallback == null)
                {
                    throw new ArgumentNullException("configureCallback");
                }

                var configurator = new HostConfiguratorImpl();

                Type declaringType = configureCallback.Method.DeclaringType;
                if (declaringType != null)
                {
                    string defaultServiceName = declaringType.Namespace;
                    if (!string.IsNullOrEmpty(defaultServiceName))
                    {
                        configurator.SetServiceName(defaultServiceName);
                    }
                }

                configureCallback(configurator);

                configurator.ApplyCommandLine();

                ConfigurationResult result = ValidateConfigurationResult.CompileResults(configurator.Validate());

                if (result.Message.Length > 0)
                {
                    HostLogger.Get(typeof(HostFactory))
                    .InfoFormat("Configuration Result:\n{0}", result.Message);
                }

                return(configurator.CreateHost());
            }
            catch (Exception ex)
            {
                HostLogger.Get(typeof(HostFactory)).Error("An exception occurred creating the host", ex);
                HostLogger.Shutdown();
                throw;
            }
        }
예제 #14
0
        public TopshelfExitCode Run()
        {
            AppDomain.CurrentDomain.UnhandledException += CatchUnhandledException;
            Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);

            _exitCode = TopshelfExitCode.Ok;

            _signalListener.Listen();

            var started = false;

            try
            {
                StartService();
                started = true;

                WaitStopSignal();
            }
            catch (Exception error)
            {
                _logWriter.Fatal(error);

                _exitCode = TopshelfExitCode.AbnormalExit;
            }
            finally
            {
                if (started)
                {
                    StopService();
                }

                HostLogger.Shutdown();
            }

            return(_exitCode);
        }
예제 #15
0
        public static int Service <TService>(Action <HostConfigurator, TService> options = null)
            where TService : IService, new()
        {
            _serviceProxy = new ServiceProxy(typeof(TService));

            ProcessCustomCommand();

            if (!_startService)
            {
                return(0);
            }

            _serviceProxy.SetupService();

            if (options == null)
            {
                options = (configurator, config) => { };
            }

            TopshelfExitCode code = RunServiceNormally(options);

            HostLogger.Shutdown();
            return((int)code);
        }
예제 #16
0
        public TopshelfExitCode Run()
        {
            Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);

            AppDomain.CurrentDomain.UnhandledException += CatchUnhandledException;

#if NETCORE
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
#endif
            if (_environment.IsServiceInstalled(_settings.ServiceName))
            {
                if (!_environment.IsServiceStopped(_settings.ServiceName))
                {
                    _log.ErrorFormat(
                        "The {0} service is running and must be stopped before running via the console",
                        _settings.ServiceName);

                    return(TopshelfExitCode.ServiceAlreadyRunning);
                }
            }
#if NETCORE
        }
#endif

            bool started = false;
            try
            {
                _log.Debug("Starting up as a console application");

                _exit     = new ManualResetEvent(false);
                _exitCode = TopshelfExitCode.Ok;
                if (
#if NETCORE
                    !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ||
#endif
                    IntPtr.Zero != GetConsoleWindow())
                {
                    try
                    {
                        // It is common to run console applications in windowless mode, this prevents
                        // the process from crashing when attempting to set the title.
                        Console.Title = _settings.DisplayName;
                    }
                    catch (Exception e) when(e is IOException || e is PlatformNotSupportedException)
                    {
                        _log.Info("It was not possible to set the console window title. See the inner exception for details.", e);
                    }
                }
                Console.CancelKeyPress += HandleCancelKeyPress;

                if (!_serviceHandle.Start(this))
                {
                    throw new TopshelfException("The service failed to start (return false).");
                }

                started = true;

                _log.InfoFormat("The {0} service is now running, press Control+C to exit.", _settings.ServiceName);

                _exit.WaitOne();
            }
            catch (Exception ex)
            {
                _settings.ExceptionCallback?.Invoke(ex);

                _log.Error("An exception occurred", ex);

                return(TopshelfExitCode.AbnormalExit);
            }
            finally
            {
                if (started)
                {
                    StopService();
                }

                _exit.Close();
                (_exit as IDisposable).Dispose();

                HostLogger.Shutdown();
            }

            return(_exitCode);
        }
예제 #17
0
 void HostControl.Stop(TopshelfExitCode exitCode)
 {
     _log.Info($"Application Stop requested, exiting with exit code: {exitCode}.");
     StopService();
     HostLogger.Shutdown();
 }