Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Windows Service Unhandled Exceptions

Status
Not open for further replies.

Custom24

Programmer
Nov 27, 2001
591
GB
Hi
In ASP.net, we get a global exception handler in the global.asax which I use to e-mail me the details of unhandled exceptions, and to redirect the user to some sort of apology page, and this works fine.

However, I'm writing my first Windows Service now and I'm puzzled.

If I do this

Throw New Exception("This exception was brought to you by the letter e")

Nothing at all happens. The service continues to run quite happily. I expected some sort of entry in the event log, but there is nothing.

What I'd like to do is to use an approach similar to the global.asax. I tried this in the sub main

Dim currentDomain As AppDomain = AppDomain.CurrentDomain
AddHandler currentDomain.UnhandledException, AddressOf MyHandler

With MyHandler writing an entry in the event log, but still nothing happens.

If I attach a debugger to the process, it steps to the line where I throw the exception and then pops up the standard exception dialog alert.

Obviously I don't intend to do all my exception handling globally, but I do need to be notified that an unhandled exception occured.

Does anyone have any ideas?

Thanks

Mark Mark [openup]
 
Services (typically) have no access to the desktop, so popping up a dialog will not work - you'll have to do something like write to the NT Event Log, using code like:
Code:
EventLog.WriteEntry("My message", EventLogEntryType.Error)
Chip H.
 
Chip H. That is what I was doing. There is no entry in the event log. I never had any dialog popup.
Mark [openup]
 
Sorry - didn't see that part of your post.

I'm at a loss - exceptions work fine in my services.

What .NET framework service pack are you on?

Chip H.
 
I presume that you mean which version of the framework is running? v1.0.3705 Which version are you running?
Thanks Mark [openup]
 
This may be a stupid question but are you looking in the 'application' section of the event log? Also, another thought - have you tried setting the autolog property to true? Durkin
 
ChipH - thanks for that link. My version is identical to yours.

Durkin - looking in application section, and autolog is true.

This is my code for the timer event, to prove that I'm not just going mad!
Code:
        Static j As Integer
        If j = 0 Then
            j = 1
        Else
            j = 0
        End If
        Me.EventLog.WriteEntry("The value of j is " & j.ToString)
        Dim i As Integer, k As Double
        i = 1
        k = CDbl(i / j)
        i = CInt(k)
        Me.EventLog.WriteEntry("Completed Elapsed Event")

What I see in the event log are the usual messages when the service is started and stopped, and then the messages when the timer fires

When the value of j is 1, everything is fine, and I see the Completed Elapsed Event message

However, when the value of j is 0, I only see the message about the value of j.

But the service keeps running, and there is no indication that anything went wrong.

I really need to be able to detect that an exception has occured, as in real life I cannot just have my service continue running if something goes wrong.

What exactly do you guys see if an exception occurs? Mark [openup]
 
Try something like this:
Code:
Dim i As Integer, j as Integer
j = 0
Me.EventLog.WriteEntry("The value of j is " & j.ToString)
Try
   i = 5 / j   ' divide by zero
   Me.EventLog.WriteEntry("Shouldn't get this")
Catch Exception ex
   Me.EventLog.WriteEntry(ex.Message + Chr(13) + Chr(10) + ex.Stacktrace)
End Try

Chip H.
 
Hi Chip
I've run what you suggested
1. The service still keeps running - is this what happens with you?
2. I'm not so good at coding that I can surround everything with try catch. My style is to keep weeding out exceptions until they don't happen, to reserve try catch for situations where something I've thought of might go wrong, and just to let the program crash if something I've not thought of happens! I know you'll probably balk at this, but it's how I like it. But that's getting more into the philosophy of exception handling anyway....

But thanks for your input.

Mark [openup]
 
I guess my point was for you to make sure that when an exception occurs that a message makes it to the event log. By intentially causing a divide-by-zero error this should show the stack trace in the NT event log. Did it show up?

So far as catching exceptions - The idea would be to have a final try..catch block at the entry point into your service to ensure that in the unlikely event that an exception is skipped in the guts of your program, it will be caught here. You don't want an unhandled exception - makes you look bad when a customer calls up asking what this stack trace is that appeared on their PC.

Chip H.
 
As far as I can see, your executable can crash and die a horrible death and the service control manager won't know anything about it and will still insist that it is started. Unhandled exceptions don't get automatically reported to the event log unfortunately so you will have to put a vague try...catch around the entire worker thread or timer event that just does a
Code:
Me.EventLog.WriteEntry(Exception.Message)
. That's where it gets tricky because if you want to shut down the service after the error and have it shown as stopped in the service control manager you have to jump through a few hoops because you can't control a service's status from within itself, not using a property of the ServiceBase class nor using the ServiceController class. Durkin
 
ChipH - yep using this method, the exception stack trace does show up in the event log.

Durkin - However, when I said that the service keeps running, I meant that timed messages continue to appear even after the exception has occured, regardless of whether we've handled it or not. I don't understand how the exe just keeps going, does a new thread get spawned by the service control manager or something?

Anyway, thanks to both of you for your time

Mark [openup]
 
Hello again.
I worked it out, kind of. As far as I can tell, though I can't find any information on this, the Windows service control manager must somehow keep a service alive even when it has an unhandled exception. It seems that you have to kill your own service, and this is how I did it.

I was right about the global exception idea - you just need this code in the onstart sub of the service (I was putting it in main, but this does not work - main is shared)

Code:
        'we want the service to do something in the event of an unhandled exception - this is how we do it
        Static blnAddedHandler As Boolean
        If Not blnAddedHandler Then
            Dim currentDomain As AppDomain = AppDomain.CurrentDomain
            AddHandler currentDomain.UnhandledException, AddressOf MyHandler
            blnAddedHandler = True
        End If

and then the MyHandler sub just looks like this

[/code]
Sub MyHandler(ByVal sender As Object, ByVal e As System.UnhandledExceptionEventArgs)
Me.EventLog.WriteEntry("Error Occured")
Dim scMe As New ServiceController("MyServiceName", ".")
scMe.Stop()
End Sub
Code:
here, we are just stopping the service MyServiceName on the local machine.

I am much happier with this method.

Thanks to both of you for your ideas!
 Mark [openup]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top