C#在应用程序崩溃时执行最后一个操作

C#在应用程序崩溃时执行最后一个操作,c#,exception,C#,Exception,我不确定是否有一个合适的术语来描述我想要的东西,因为我在谷歌尝试过的任何东西都没有买下来 基本上,在应用程序崩溃时,我希望执行最后一个操作来清除数据库记录锁定 我还想在使用stop按钮停止调试时了解这一点,因为我知道使用stop按钮与通过应用程序中的正常进程退出应用程序非常不同 有没有一种正常的方式来实现我想做的事情?该应用程序是用VS2008编写的C#,.NET3.5Windows窗体应用程序 干杯在它被杀死后,你不能在一个过程中做任何事情 要想达到你的目的,唯一的办法就是进行第二个过程,观察

我不确定是否有一个合适的术语来描述我想要的东西,因为我在谷歌尝试过的任何东西都没有买下来

基本上,在应用程序崩溃时,我希望执行最后一个操作来清除数据库记录锁定

我还想在使用stop按钮停止调试时了解这一点,因为我知道使用stop按钮与通过应用程序中的正常进程退出应用程序非常不同

有没有一种正常的方式来实现我想做的事情?该应用程序是用VS2008编写的C#,.NET3.5Windows窗体应用程序


干杯

在它被杀死后,你不能在一个过程中做任何事情

要想达到你的目的,唯一的办法就是进行第二个过程,观察第一个过程是否死亡,然后代表它进行清理


您必须担心第二个进程崩溃或被杀死,等等。让它在所有可能的情况下都起作用并不容易,但总比没有好得多。

你的第一个要求的答案是(最基本的):

然而,在处理Windows应用程序时,还有其他的考虑因素,正如RichardOD在这里和这里的评论中所指出的那样

您的第二个要求的答案是不,您不能在调试器中捕获正在停止的应用程序(或者至少我没有遇到过这样的方法)。它只是扼杀了这个过程

例如,如果您在断点处停止,然后按stop,代码不会继续执行到终止-它只是退出

如果应用程序由于某些外部因素(如电源关闭)而停止,情况也是如此。在这种情况下,程序无法执行任何代码,无论它是否在finally块中

然而,我刚刚遇到一个问题,这个问题的答案是:

您可以使用DTE(VisualStudio 自动化模型)来编写宏 停止调试时将调用的 如果发生这种情况,下面是 想法

所以,虽然您不能在应用程序中捕获执行的停止,但您可以在VisualStudio中对此采取一些措施


注意:答案不是我提供的

检查上的任何解决方案是否对您有帮助。

您可以在程序启动时,在调用Application.Run之前订阅该事件。如果应用程序抛出异常,这将为您提供一个执行某些操作的机会。但是,当您单击“停止”时,它不会对捕获调试器起任何作用

<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
_
公共共享子主目录()
AddHandler Application.ThreadException,ErrorHandlerForm.Form1\u UIThreadException的地址
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException)
'运行应用程序。
Application.Run(新Form1())
端接头
私有共享子表单1_UIThreadException(ByVal发送方作为对象,ByVal t作为ThreadExceptionEventArgs)
'处理异常
端接头

您的另一个选择是围绕您的应用程序运行。在Try…Catch块中运行,这应该会给您类似的结果。

但是,我认为当用户通过调试器停止进程时,不可能捕获,当应用程序引发任何异常而未捕获时,您可以覆盖事件以捕获。

如果您的目标是Windows Vista(或更高版本),您可能会对RegisterApplicationRecoveryCallback API感兴趣

它不涉及调试场景,但允许您在应用程序即将崩溃时执行某些操作

您可以从C#对这个API进行p/invoke(我已经这样做了),但是请记住,当您调用回调时,您的应用程序已经处于非常糟糕的状态,并且您可以对内存状态进行很少的假设。如果您有任何内存中的数据要在这个例程中使用,我会将它放在一个非常通用的静态范围中,这样您就有可能在回调例程运行时不会“整理”它

还有一些其他有趣的API,与此相关,允许您在出现故障后自动重新启动应用程序等。

实现您正在尝试的功能的正常方法是确保您的应用程序不会崩溃


您还可以提供一个独立的应用程序,该应用程序将允许系统管理员释放由于任何原因(断电等)留下的任何文件锁。这样的应用程序也可以用来解决这个问题。

这只有在您有控制台应用程序时才有效。对于Windows应用程序,必须考虑其他因素-请参阅,宏很接近,但不完全正确。它需要是OnInterDesignMode事件,而不是OnInterBreakMode。(OneInterBreakMode用于断点;OneInterDesignMode显然用于进程终止。)@Joe-干杯,正如我在回答中所说,我“借用”了其他人的答案(希望正确归因)。我会更新它。记住,finally子句不会一直运行。有一个有趣的阅读:@Marcel-是的。我想我应该限定这个7年半的答案:)
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
<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