c# - 无法使用 VS Debugger Interop 执行语句

标签 c# debugging visual-studio-2013 visual-studio-extensions envdte

我正在编写一个调试器扩展 VSPackage,我想在遇到断点时在调试进程中执行一条语句。在我的扩展代码中,我有这个:

void Initialize()
{
    // ...standard vspackage init code omitted...

    Globals.Init((DTE2)GetService(typeof(DTE)));              
    Globals.DebuggerEvents.OnEnterBreakMode += (dbgEventReason reason, ref dbgExecutionAction action) =>
    {
        try
        {
           var e1 = Globals.Application.Debugger.GetExpression("1+2");
           Debug.WriteLine(e1.Value);     // Prints "3"

           Globals.Application.Debugger.ExecuteStatement("x = 1+2", 1000);
           Debug.WriteLine("OK");         // Never prints this                          
        } 
        catch (Exception ex)
        {
           Debug.WriteLine("Error: "+ex); // Nor this
        }
    }             
}

在 VS 实例中调试此扩展时,我加载了一个看起来像这样的普通程序

static void Main()
{
   int x = 5;
   Console.WriteLine("X is "+x); // Breakpoint on this line
}

当在调试进程中遇到断点时,将调用处理程序并且扩展的输出窗口显示“3”,因此评估表达式 有效,但它永远不会成功执行语句。没有更多内容打印到输出窗口。没有发生异常或超时,我无法继续调试该过程,调试器似乎已崩溃。

全局类只包含 DTE 和 DebuggerEvents

public static class Globals
{
   public static void Init(DTE2 dte)
   {
      Application = dte;
      DebuggerEvents = dte.Events.DebuggerEvents;    
   }

   public static DTE2 Application { get; private set; }
   public static DebuggerEvents DebuggerEvents { get; private set; }
}

我做错了什么,或者误解了什么?

最佳答案

这是一个老问题,但谷歌上关于这些问题的资料太少了,我想我会提供一些帮助。一些重要的考虑因素:

  1. 如果可能,请使用 GetExpression3(TreatAsStatement:=True) 而不是 ExecuteStatement(我无法让 ExecuteStatement 正常工作)。
  2. 调用您的委托(delegate) (OnEnterBreakMode) 的线程与将需要再次运行以执行您的表达式或语句的线程相同。因此,在新线程 (Task.Run..) 上调用您的 GetExpression 方法
  3. 您必须监控和管理 OnEnterBreakMode 的 Reason 值。对于实际未处理的异常,初始 Reason 是 UnwindFromException。然后,预计您要设置一个变量,例如 tempStack = New System.Diagnostics.StackTrace(True)。执行此语句后将再次调用 OnEnterBreakMode,但这次使用 Evaluation for the Reason。此时,您现在可以调用所有 GetExpressions 来收集所有数据,而无需额外调用 OnEnterBreakMode。

    Dim dte2 As EnvDTE80.DTE2 = GetGlobalService(GetType(EnvDTE.DTE))

    将 debugger5 调暗为 EnvDTE100.Debugger5 = Dte2.Debugger

有趣的设计观察:System.Diagnostics.StackTrace 在 .NET 框架的其余部分的上下文中是一个设计非常奇怪的类,直到您必须处理这个项目,在该项目中您通过这种技术提取 StackTrace 并看到其原本奇怪的设计的好处。

关于c# - 无法使用 VS Debugger Interop 执行语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28514884/

相关文章:

c# - 什么都不做的最优雅的 lambda 表达式( Action )是什么?

java - 使用eclipse进行xslt远程调试

c++ - Visual Studios - C++ 控制台立即打开和关闭

delphi - 如何在Delphi中安装和使用另一个调试器?

windows - 有没有办法在没有 IE 11 的情况下安装 VS 2013?

visual-studio - 创建托管 PowerShell 的 Visual Studio 2013 扩展

c# - 为什么这个 "finally"会执行呢?

c# xamarin 圆形进度条 - Android

c# - 如何从控制台读取多行用户输入?

node.js - Nodejs调试-自动生成错误信息