Aaron M
Aaron M

Reputation: 2563

Restart Service when Exception is thrown

I am writing a windows service that needs to be running 24/7. It is a pretty simple service that monitors a directory where files are dropped into and processes those files. I need to restart the service if an unhandled exception is thrown.

Is there a way for a service to restart itself in the event of an unhandled exception?

Upvotes: 3

Views: 3999

Answers (6)

CoreTech
CoreTech

Reputation: 2433

As suggested by "John Saunders" and "theGecko", you can monitor the service and restart it when it fails. The builtin Windows Service Recovery functionality will get you a long way, but if you find that you need some more advanced features (for example, CPU hogging and hang detection) then please check out Service Protector. It is designed to keep your important Windows Services operating 24x7.

Good luck!

Upvotes: 0

Mike Z
Mike Z

Reputation: 96

This is able to be done programatically if you wanted, this code was not written by me. I am posting the link to the Authors CodeProject page that contains the source / binaries. Below the link I have explained how I implemented the authors code.

http://www.codeproject.com/KB/install/sercviceinstallerext.aspx

  1. Add a reference to the DLL.

  2. Open ProjectInstaller.Designer.vb in notepad
    In the InitializeComponent Sub
    CHANGE
    Me.ServiceProcessInstaller1 = New System.ServiceProcess.ServiceProcessInstaller
    Me.ServiceInstaller1 = New System.ServiceProcess.ServiceInstaller
    TO
    Me.ServiceProcessInstaller1 = New System.ServiceProcess.ServiceProcessInstaller
    Me.ServiceInstaller1 = New Verifide.ServiceUtils.ServiceInstallerEx

  3. With the Friend Declarations in the ProjectInstaller.Designer.vb
    CHANGE
    Friend WithEvents ServiceProcessInstaller1 As System.ServiceProcess.ServiceProcessInstaller
    Friend WithEvents ServiceInstaller1 As System.ServiceProcess.ServiceInstaller
    TO
    Friend WithEvents ServiceProcessInstaller1 As System.ServiceProcess.ServiceProcessInstaller
    Friend WithEvents ServiceInstaller1 As Verifide.ServiceUtils.ServiceInstallerEx

  4. CHANGE
    Me.Installers.AddRange(New System.Configuration.Install.Installer() {Me.ServiceProcessInstaller1, Me.ServiceInstaller1})
    TO
    Me.Installers.AddRange(New System.Configuration.Install.Installer() {Me.ServiceInstaller1, Me.ServiceProcessInstaller1})

  5. Import The Namespace On ProjectInstaller.vb

  6. In ProjectInstaller.vb in the Public Sub New Function After Initialize component function has been called
    ADD
    'Set Reset Time Count - This Is 4 Days Before Count Is Reset
    ServiceInstaller1.FailCountResetTime = 60 * 60 * 24 * 4
    'ServiceInstaller1.FailRebootMsg = "Houston! We have a problem"

    'Add Failure Actions
    ServiceInstaller1.FailureActions.Add(New FailureAction(RecoverAction.Restart, 60000))
    ServiceInstaller1.FailureActions.Add(New FailureAction(RecoverAction.Restart, 60000))
    ServiceInstaller1.FailureActions.Add(New FailureAction(RecoverAction.None, 3000))

    ServiceInstaller1.StartOnInstall = True

  7. Build installer and install. Voila

Upvotes: 1

John Saunders
John Saunders

Reputation: 161831

The Services applet has many different recovery features:

Services Recovery

It can take different actions on the first, second, and subsequent failures:

  • Restart the service, after a configurable delay
  • Run a Program (passing command line parameters, possibly including the failure count)
  • Restart the Computer (after a configurable delay, and with a particular message being sent)

The program that runs should be able to look in the event log and see the reason for failure (especially if you log it), and should therefore be able to disable the service if the exception is one that is not recoverable.

And, of course, in the meantime, the service should be logging what's going on, which should enable any management tool to notify Operations of what's going on.

I agree that you should probably not configure "third and subsequent" to be "restart service", or you could wind up in a loop.

Upvotes: 2

Dan Diplo
Dan Diplo

Reputation: 25359

The best way is to wrap Try / Catch blocks around the methods in the service you can afford to let throw exceptions.

However, there may be serious exceptions thrown that should result in the service being stopped immediately. Don't ignore these! In these cases, handle the exception, log it, email it and then rethrow it. That way you will be informed that the exception has occurred and will know what went wrong. You can then fix the problem and re-start the service manually.

Just ignoring it could cause a major failure in your system which you would not know about. It could also be very expensive on CPU/RAM if the service stops then restarts then stops ad infinitum.

Upvotes: 0

theGecko
theGecko

Reputation: 1021

Wrap your service code in a runner which can catch any errors and restart your service.

Upvotes: 0

JustinD
JustinD

Reputation: 1676

Have you tried using the Recovery tab of the Service entry - you can set rules for failures, including "Restart the Service" - by default this is on "No Action"

Upvotes: 2

Related Questions