tags:

views:

721

answers:

8

I'm not sure if there is a proper term for what I want to because any I've tried in google haven't bought anything up.

Basically, on an application crash I would like to perform a final action to clean up database record locking.

I would also like to catch this when debugging is stopped using the stop button, as I understand it using the stop button is very different to exiting your application by a normal process in your application.

Is there a normal way for achieving what I'm trying to do? The application is a C#, .NET 3.5 Windows Forms Application written in VS2008.

Cheers

+3  A: 

You can't do anything within a process after it's killed.

Your only way to achieve what you want would be to have a second process that watched for the first one dying, and then did the cleanup on its behalf.

You have to worry about the second process crashing, or being killed, and so on. Not easy to make it work in all conceivable cases, but a lot better than nothing.

RichieHindle
+2  A: 

The answer to your first requirement is to have (at it's most basic):

try
{
    // Main application
}
catch // Though you might not want this
{
}
finally
{
    // This code always executed even if application crashes.
}

However there are other considerations when dealing with Windows applications as RichardOD indicates in his comments here - http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx and here http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx

The answer to your second requirement is no you can't trap the application being stopped in the debugger (or at least there's not a way I've come across). It just kills the process.

For instance if you have stopped at a break point and then press stop the code doesn't carry on executing to termination - it just exits.

UPDATE

I've just come across this question http://stackoverflow.com/questions/1033441/visual-studio-executing-clean-up-code-when-debugging-stops which has an answer that states:

You can use the DTE (VisualStudio Automation Model) to write a macro that will be invoked when a stop debug happens, below is a snippet of the idea.

Private Sub DebuggerEvents_OnEnterDesignMode(ByVal Reason As EnvDTE.dbgEventReason, ByRef ExecutionAction As EnvDTE.dbgExecutionAction) Handles DebuggerEvents.OnEnterDesignMode

    If (Reason = dbgEventReason.dbgEventReasonStopDebugging) Then
        // DO YOUR CLEAN UP CODE HERE
    End If
End Sub

So while you can't trap the stopping of the execution in your application you can do something about it in Visual Studio.

NOTE: Answer provided by Shay Erlichmen not me!

ChrisF
This only works if you have a console application. For a Windows Application other things have to be considered- see http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx and http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx
RichardOD
The macro is close, but not quite right. It needs to be the OnEnterDesignMode event, not OnEnterBreakMode. (OnEnterBreakMode is for breakpoints; OnEnterDesignMode is apparently for process termination.)
Joe White
@Joe - cheers, as I said in the answer I "borrowed" the answer from someone else (hopefully properly attributed). I'll update it.
ChrisF
+1  A: 

Check if any of the solution on Handling end process of a windows app helps you.

Rashmi Pandit
A: 

You could subscribe to the Application.ThreadException event when your program starts up, before you call Application.Run. This will give you a chance to do something if your application throws and exception. It will not do anything, however, for catching the debugger when you hit stop.

<SecurityPermission(SecurityAction.Demand, Flags:=SecurityPermissionFlag.ControlAppDomain)> _
Public Shared Sub Main()
  AddHandler Application.ThreadException, AddressOf ErrorHandlerForm.Form1_UIThreadException
  Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException)

   ' Run the application.
  Application.Run(New Form1())
End Sub


Private Shared Sub Form1_UIThreadException(ByVal sender As Object, ByVal t As ThreadExceptionEventArgs)
  ' Handle exception
End Sub

Your other option is to just surround your Application.Run in a Try...Catch block, which should give you similar results.

heavyd
+1  A: 

I don't think its possible to catch when the user stops the process via the debugger, however, you can override the OnUnhandledException event to catch when any exceptions are raised and not caught by your application.

James
A: 

If you're targeting Windows Vista (or above) you might be interested in the RegisterApplicationRecoveryCallback API...

http://msdn.microsoft.com/en-us/library/aa373345.aspx

It doesn't address the debugging scenario, but it does allow you to do something when your app is about to crash.

You can p/invoke to this API from C# (I have done it), but bear in mind that when your callback is invoked your app is already in a very bad state, and you can make very few assumptions about the state of your memory. If you have any in-memory data that you want to use in this routine, I would put it in a static at a very general scope so that you have the best possible chance of it not having been "tidied up" when your callback routine runs.

There are some other interesting APIs, related to this one, that allow you automatically restart your app after a failure, etc.

Martin
A: 

A "normal way for achieving what you're trying" is to make sure your application never crashes.

You can also provide a standalone application which will let system administrator to release any file locks which might be left for whatever reason (power outage, ...). Such application could be used to fix this as well.

Suma
A: 

As for unhandled exceptions that occur in a program, you could check this article out.

kek444