44

编辑:Visual Studio 2015 的新异常窗口比旧对话框快得多,我不再关心为它使用键盘快捷键。

是否有一个宏或键盘快捷键可以在不使用 GUI 的情况下切换“抛出异常时中断”?

使用 ctrl+alt+e 打开对话框并检查“Common Language Runtime Exceptions”“Thrown”框,然后单击 OK 很简单,但这是我经常做的事情。我宁愿为此使用键盘快捷键。

此问题与 Any have a Visual Studio shortcut/macro for toggling break onhandled/unhandled exceptions 的重复?

但是,张贴者接受了一个不起作用的答案,我真的很想要一个有效的答案。

重复问题中的答案是不可接受的,因为它只切换一个特定的异常,而不是整个 CLR 组。

“那就写个循环吧。” 你说。但没那么快!有人已经尝试过了,而且速度很慢。(是的,我已经证实它在我的系统上也很慢。)

因此,挑战在于使用宏在 1 或 2 秒内切换整个 CLR 异常类别。此问题与 Any have a Visual Studio shortcut/macro for toggling break onhandled/unhandled exceptions 的重复?

4

10 回答 10

18

与其他答案非常相似,但该组有一个特殊的 ExceptionSetting。

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
于 2009-06-11T14:58:37.743 回答
14

我创建了一个可以可靠地做到这一点的免费 Visual Studio 扩展:Exception Breaker
它使用IDebugSession2.SetException非常快的未记录调用:所有异常都在 20 到 60 毫秒内设置/取消设置。

于 2013-04-01T00:39:17.420 回答
4

这是 Bryce Kahle 的非常有用的宏,盲目更新以在 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
于 2010-04-19T20:26:20.330 回答
2

首先我初始化了一个计时器,然后我调用了命令 Exception.Debug。当模态对话框打开时,计时器命中。如果您将 Win 7 与停用的 UAC SendKeys 与 ALT-Key 一起使用将失败...我不知道为什么。

我玩了一点...试试这个(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

'...
于 2011-10-26T13:12:36.417 回答
1

好吧,我写了一个基于 VS2008 C# 的插件,可以切换 386 个异常,每个状态切换大约需要 1 秒。我假设这是由于 COM 互操作。

这是基于您的链接之一中的 VB/宏代码。我找不到更简单的 C++ 方法(但不排除它)。

下一个级别是制作一个具有键盘绑定的插件,然后打开异常 UI,然后为您“单击”正确的复选框。

祝你好运。

于 2009-06-11T09:38:27.260 回答
1

您可以使用AutoHotKey之类的工具来创建录制的脚本(鼠标单击或按键),然后为其分配一个热键,按下时将播放它...

于 2009-06-17T05:14:45.643 回答
1

只是提供一些我在这个(这里)上找到的信息,因为我正在搜寻网络以帮助我徒劳无功......

其他人提出了同样的问题,MS Support 的 Gary Chang 对此作出了回应,以下是引用的回应:

恐怕宏代码无法操作异常对话框上的操作...

需要注意的是,这个帖子是 2005 年 12 月发布的,所以这个回复可能不再准确;不管怎样,我想我会把它扔在那里。

于 2009-06-17T12:29:22.700 回答
1

为组设置特殊 ExceptionSetting 的建议确实切换了顶级复选框的状态。但是,它似乎并没有在树中切换它下面的单个异常,而且,当我手动检查顶级复选框时,当抛出此类异常时,我的进程不会停止。你看到不同的行为吗?

于 2009-10-16T19:59:15.627 回答
1

我的宏在运行时忽略当前的 CLR 异常。当在调试时弹出异常时,它就像一个按钮“禁用捕获此异常类型”。

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
于 2012-01-25T11:18:06.937 回答
1

CTRL + ALT + E ALT + T 回车

为我工作

于 2013-08-12T15:50:57.637 回答