【问题标题】:Toggle "Break when an exception is thrown." using macro or keyboard shortcut切换“抛出异常时中断”。使用宏或键盘快捷键
【发布时间】:2010-10-31 18:37:44
【问题描述】:

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

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

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

这个问题是重复的 Any have a Visual Studio shortcut/macro for toggling break on handled/unhandled exceptions?

但是,发帖人接受了一个不起作用的答案,我真的很想要一个确实起作用的答案。

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

“那就写一个循环吧。”你说。但没那么快! Someone tried that already,它的速度太慢了。 (是的,我已经证实它在我的系统上也很慢。)

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

【问题讨论】:

  • 你使用的是什么版本的 Visual Studio?
  • 我使用的是 Visual Studio 2008,但如果可能的话,最好使用非版本特定的解决方案。
  • @dss539 尽管接受的答案是在 2009 年编写的,但有一个更好的解决方案 (down here) 作为 VS 插件,它允许您轻松地关闭/打开 CLR 异常键盘快捷键。请考虑更改接受的答案...
  • @OferZelig 感谢您提醒我!

标签: visual-studio exception ide visual-studio-macros


【解决方案1】:

与其他答案非常相似,但该组有一个特殊的 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

【讨论】:

  • 这给我一个 VS 2008 的“无效索引”错误。有什么想法吗?
  • 奇数。它对我来说非常有用,但现在我遇到了同样的错误。让我做更多的挖掘。
  • 我已经更新了我的代码。它现在应该可以工作了。更改是在 ExceptionSetting 不存在时添加它。
  • 嗯,好吧,这并没有切换小节的例外情况。我刚刚注意到这一点。 :(
  • 我尝试了这段代码,虽然它成功检查了“例外”对话框中的顶级复选框,但这是唯一被选中的复选框。单个异常的复选框保持未选中状态,因此在抛出异常时调试器不会中断。
【解决方案2】:

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

【讨论】:

  • 很多
【解决方案3】:

这是 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

【讨论】:

  • 我在@PeterMacMurchy 的回答基础上进行了改进。我向菜单栏添加了一个命令并将其分配给上面的宏。然后,我在宏中添加了代码,该代码还更改了命令的 Caption 以反映设置是否打开。见我的answer
  • 很酷,谢谢!虽然这是唯一被选中的复选框,但它确实打破了子树中的异常(无论它们的检查状态如何 - 2010 年验证)。干杯!
【解决方案4】:

首先我初始化了一个计时器,然后我调用了命令 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

'...

【讨论】:

    【解决方案5】:

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

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

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

    祝你好运。

    【讨论】:

    • 感谢您的尝试。我怀疑问题在于切换 1 个设置或切换 386 个设置所花费的时间与将它们作为批处理切换的时间大致相同。但我只找到了一次切换它们 1 的方法,因此它需要的时间是应有的 386 倍。
    • +1 感谢您为此做出的贡献(我之前不想 +1,因为我不希望它被自动接受为答案。)
    • 你有你创建的插件的链接吗,很想在我自己的设置中使用这样的东西
    【解决方案6】:

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

    【讨论】:

    • 想要这样做的部分原因是“例外”对话框需要很长时间才能打开。我的主要目标是速度。减少重复是一个额外的好处,但不是我对此感兴趣的原因。所以,好主意,但 AHK 不太适合我的目标。
    【解决方案7】:

    只是提供一些我在此 (here) 上找到的信息,因为我正在搜寻网络以寻求帮助...

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

    恐怕宏代码不能 操纵上的操作 例外对话框...

    请务必注意,此帖子发布于 2005 年 12 月,因此此回复可能不再准确;不管怎样,我想我会把它扔在那里。

    【讨论】:

    • 感谢您添加信息。顺便说一句,是迈克尔还是加里?在您链接的网站上,他的名字被列为 Gary Chang。
    【解决方案8】:

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

    【讨论】:

    • Ethan,是的,我也注意到了这一点。请参阅我对“已接受的答案”的评论。我的评论默认是隐藏的。您必须“查看所有 cmets”。
    【解决方案9】:

    我的宏在运行时忽略当前的 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
    

    【讨论】:

    • 感谢贡献,有机会我去试试。
    【解决方案10】:

    CTRL + ALT + E ALT + T 输入

    为我工作

    【讨论】:

    • 这确实有效,但启动“例外”对话框的速度非常慢。所以它更像是CTRL + ALT + E [喝一半咖啡] ALT + T Enter
    猜你喜欢
    • 1970-01-01
    • 2011-04-05
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多