Alternar “Interrumpir cuando se lanza una excepción” utilizando el método abreviado de teclado o macro

Editar: La nueva ventana de excepción de Visual Studio 2015 es mucho más rápida que el diálogo anterior y ya no me importa tanto usar un atajo de teclado para ella.

¿Existe un método abreviado de macro o teclado que alterne “romper cuando se lanza una excepción” sin usar la GUI?

Abrir el cuadro de diálogo con ctrl + alt + e y marcar el cuadro de “Excepción de Common Language Runtime” “Lanzado” y luego hacer clic en OK es bastante simple, pero esto es algo que hago mucho. Prefiero tener un atajo de teclado para esto.

Esta pregunta es un duplicado de Any tiene un atajo de teclado / macro de Visual Studio para alternar el break en las excepciones manejadas / no manejadas?

Sin embargo, el póster aceptó una respuesta que realmente no funciona, y realmente me gustaría una respuesta que funcione.

La respuesta en la pregunta duplicada no es aceptable porque activa solo una excepción específica, no todo el grupo CLR.

“Bueno, entonces escribe un ciclo”. tu dices. ¡Pero no tan rápido! Alguien ya lo intentó y fue inútilmente lento. (Sí, he verificado que también es lento en mi sistema).

Entonces, el reto es usar una macro para alternar la categoría de excepciones de CLR en menos de 1 o 2 segundos. Esta pregunta es un duplicado de Any tiene un atajo de teclado / macro de Visual Studio para alternar el break en las excepciones manejadas / no manejadas?

Creé una extensión gratuita de Visual Studio que puede hacer eso de manera confiable: Exception Breaker .
Utiliza la llamada IDebugSession2.SetException no IDebugSession2.SetException que es muy rápida: todas las excepciones se establecen / desarman en 20 a 60 milisegundos.

Muy similar a la otra respuesta, pero hay una ExceptionSetting especial para el grupo.

 Dim dbg As EnvDTE90.Debugger3 = DTE.Debugger Dim exSettings As EnvDTE90.ExceptionSettings = dbg.ExceptionGroups.Item("Common Language Runtime Exceptions") Dim exSetting As EnvDTE90.ExceptionSetting Try exSetting = exSettings.Item("Common Language Runtime Exceptions") Catch ex As COMException If ex.ErrorCode = -2147352565 Then exSetting = exSettings.NewException("Common Language Runtime Exceptions", 0) End If End Try If exSetting.BreakWhenThrown Then exSettings.SetBreakWhenThrown(False, exSetting) Else exSettings.SetBreakWhenThrown(True, exSetting) End If 

Aquí está el macro muy útil de Bryce Kahle, que se actualiza a ciegas para ejecutarse en VS2010:

 Sub ToggleExceptions() Dim dbg As EnvDTE100.Debugger5 = DTE.Debugger Dim exSettings As ExceptionSettings = dbg.ExceptionGroups.Item("Common Language Runtime Exceptions") Dim exSetting As ExceptionSetting Try exSetting = exSettings.Item("Common Language Runtime Exceptions") Catch ex As COMException If ex.ErrorCode = -2147352565 Then exSetting = exSettings.NewException("Common Language Runtime Exceptions", 0) End If End Try If exSetting.BreakWhenThrown Then exSettings.SetBreakWhenThrown(False, exSetting) Else exSettings.SetBreakWhenThrown(True, exSetting) End If End Sub 

Primero integré un temporizador y luego llamé al comando Exception.Debug. El temporizador golpea cuando se abre el cuadro de diálogo modal. Si usa Win 7 con UAC SendKeys desactivado con ALT-Key fallará … no sé por qué.

Jugué un poco … prueba esto (VS2010 EN):

 Imports System Imports EnvDTE Imports EnvDTE80 Imports EnvDTE90 Imports EnvDTE90a Imports EnvDTE100 Imports System.Diagnostics Imports System.Runtime.InteropServices '... Private WithEvents t As Timers.Timer Private Sub t_Elapsed(ByVal ee As Object, ByVal dd As Timers.ElapsedEventArgs) Handles t.Elapsed t.Stop() ' Tastatureingaben simulieren System.Windows.Forms.SendKeys.SendWait("{DOWN}") System.Threading.Thread.Sleep(1500) ' Pause wichtig zum Laden des Exceptionbaums System.Windows.Forms.SendKeys.SendWait("%t") System.Windows.Forms.SendKeys.SendWait("{ENTER}") End Sub Public Sub toggleCLRExceptions() If DTE.Solution.Count <= 0 Then MsgBox("Nicht ohne geöffnete Solution!") Exit Sub End If ' Timer wird benötigt, da der Dialog Modal ist ' und weitere Befehle im Macro werden erst nach beenden des Dialogs ausgeführt t = New Timers.Timer() t.Interval = 0.5 t.Start() DTE.ExecuteCommand("Debug.Exceptions") 'System.Windows.Forms.SendKeys.SendWait("^%e") ' alternativ: STRG+ALT+e System.Threading.Thread.Sleep(200) If isCLRExceptionsActive() Then MsgBox("BREAK @CLR-Exception", MsgBoxStyle.Information, "Info") Else MsgBox("NO BREAK @CLR-Exception", MsgBoxStyle.Information, "Info") End If End Sub Function isCLRExceptionsActive() As Boolean ' prüft, ob Setting Debug CLR-Exceptions aktiviert/deaktivert ist Dim dbg As EnvDTE100.Debugger5 = DTE.Debugger Dim exSettings As ExceptionSettings = dbg.ExceptionGroups.Item("Common Language Runtime Exceptions") Dim exSetting As ExceptionSetting Try exSetting = exSettings.Item("Common Language Runtime Exceptions") Catch ex As COMException If ex.ErrorCode = -2147352565 Then exSetting = exSettings.NewException("Common Language Runtime Exceptions", 0) End If End Try Return exSetting.BreakWhenThrown End Function '... 

Bueno, escribí un complemento basado en VS2008 C # que alterna las 386 excepciones, y se tarda aproximadamente 1 segundo por estado alternar. Supongo que se debe a COM interoperacional.

Esto se basó en el código VB / macro en uno de sus enlaces. No pude encontrar un método C ++ más fácil (pero no descartarlo).

El siguiente nivel sería hacer un complemento que tenga un enlace de teclado, que luego abra la IU de Excepciones y luego haga “clic” en la checkbox correcta.

Buena suerte.

Puede usar una herramienta como AutoHotKey para crear un guión grabado (clics del mouse o presionar teclas) y luego asignarle una tecla de acceso directo que lo reproducirá cuando se presione …

Solo ofrezco información que encontré en este ( aquí ) mientras recorría la red en mi vano bash de ayudar …

Alguien más hizo la misma pregunta y fue respondida por Gary Chang de MS Support, aquí está la respuesta citada:

Me temo que el código de macro no puede manipular las operaciones en el cuadro de diálogo Excepciones …

Es importante tener en cuenta que esta publicación es de diciembre de 2005, por lo que esta respuesta puede no ser precisa; de cualquier manera, pensé en tirarlo allí.

La sugerencia de establecer la ExceptionSetting especial para el grupo allana el estado de la checkbox de nivel superior. Sin embargo, no parece alternar las Excepciones individuales debajo de él en el árbol, y además, mi proceso no se detiene cuando se lanzan tales excepciones como lo hace si verifico manualmente la checkbox de nivel superior. ¿Ves un comportamiento diferente?

Mi macro ignora la excepción actual de CLR en tiempo de ejecución. Funciona como un botón ‘desactivar la captura de este tipo de excepción’ cuando aparece una excepción en el momento de la depuración.

 Imports System Imports EnvDTE Imports EnvDTE80 Imports EnvDTE90 Imports EnvDTE90a Imports EnvDTE100 Imports System.Diagnostics Imports Microsoft.VisualBasic Imports Microsoft.VisualBasic.ControlChars ' execute Macros.MyMacros.VSDebuggerExceptions.IgnoreCurrentExceptionWhenThrown from VS Command Window Public Module VSDebuggerExceptions Sub BreakWhenThrown(Optional ByVal strException As String = "") Dim dbg As Debugger3 = DTE.Debugger Dim eg As ExceptionSettings = _ dbg.ExceptionGroups.Item("Common Language Runtime Exceptions") eg.SetBreakWhenThrown(True, eg.Item(strException)) End Sub ' copied from Utilities module (samples) Function GetOutputWindowPane(ByVal Name As String, Optional ByVal show As Boolean = True) As OutputWindowPane Dim window As Window Dim outputWindow As OutputWindow Dim outputWindowPane As OutputWindowPane window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput) If show Then window.Visible = True outputWindow = window.Object Try outputWindowPane = outputWindow.OutputWindowPanes.Item(Name) Catch e As System.Exception outputWindowPane = outputWindow.OutputWindowPanes.Add(Name) End Try outputWindowPane.Activate() Return outputWindowPane End Function Private WithEvents t As Timers.Timer ' Adds the current exception to ignore list Sub IgnoreCurrentExceptionWhenThrown() Dim commandWin As EnvDTE.CommandWindow commandWin = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindCommandWindow).Object Select Case DTE.Debugger.CurrentMode Case dbgDebugMode.dbgDesignMode commandWin.OutputString("This macro is not enabled in Design Mode. Run it in Break Mode." + vbCrLf) Return Case dbgDebugMode.dbgRunMode commandWin.OutputString("This macro is not enabled in Run Mode. Run it in Break Mode." + vbCrLf) Return End Select commandWin.OutputString(Environment.NewLine) commandWin.OutputString("Trying to get the information about current exception.." + Environment.NewLine) Dim dbg As Debugger3 = DTE.Debugger Dim currentExpression As Expression = dbg.GetExpression("$exception", False) Try Dim currentExceptionTypeString As String = currentExpression.DataMembers.Item(1).Type commandWin.OutputString("Detected current exception type is : " + currentExceptionTypeString + Environment.NewLine) Dim flag As Boolean = True Dim eg As ExceptionSettings = dbg.ExceptionGroups.Item("Common Language Runtime Exceptions") Try eg.SetBreakWhenThrown(False, eg.Item(currentExceptionTypeString)) Catch exc As Exception commandWin.OutputString("Cannot find this exception, trying to create.." + currentExceptionTypeString + Environment.NewLine) ' eg.NewException(currentExceptionTypeString, New Random().Next) eg.SetBreakWhenThrown(False, eg.Item(currentExceptionTypeString)) eg.SetBreakWhenUserUnhandled(True, eg.Item(currentExceptionTypeString)) flag = False End Try commandWin.OutputString(Environment.NewLine) commandWin.OutputString("Exception '" + currentExceptionTypeString + "' added to ignore list.") commandWin.OutputString(Environment.NewLine) t = New Timers.Timer() ' small interval to send keys after DTE will start to exec command t.Interval = 0.1 t.Start() DTE.ExecuteCommand("Debug.Exceptions") Catch exc As Exception commandWin.OutputString("Error occured") End Try End Sub Private Sub t_Elapsed(ByVal ee As Object, ByVal dd As Timers.ElapsedEventArgs) Handles t.Elapsed t.Stop() ' only press Ok to apply changed exceptions settings to debugger System.Windows.Forms.SendKeys.SendWait("%t") System.Windows.Forms.SendKeys.SendWait("{ENTER}") End Sub End Module 

CTRL + ALT + E ALT + T Entrar

funciona para mi