Reputation: 5165
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
Upvotes: 1
Views: 6526
Reputation: 137148
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.
The same is true if the application stops due to some external factor like the power being turned off. In scenarios like this there's no way that the program can execute any code whether it's in a finally block or not!
However, I've just come across this question 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!
Upvotes: 1
Reputation: 34403
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.
Upvotes: 0
Reputation: 5452
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.
Upvotes: 0
Reputation: 17721
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.
Upvotes: 0
Reputation: 82096
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.
Upvotes: 1
Reputation: 23808
Check if any of the solution on Handling end process of a windows app helps you.
Upvotes: 1
Reputation: 281495
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.
Upvotes: 5