【问题标题】:Visual Studio Automation - Debugger exit event and status codeVisual Studio 自动化 - 调试器退出事件和状态代码
【发布时间】:2015-08-19 09:37:31
【问题描述】:

在一个Visual Studio 2013自动化项目(即Visual Studio Package项目)中,当被调试进程退出时,如何让事件处理程序运行,如何找出被调试进程的退出代码是什么?

我正在像这样启动调试器(C#):

var dte = ...;
foreach (EnvDTE.Project proj in dte.Solution.Projects)
{
    if (proj.Name == "blahblah")
    {
        dte.Solution.Properties.Item("StartupProject").Value = proj.Name;
        dte.Debugger.Go(false);
        break;
    }
}

我希望在被调试进程退出时运行更多代码,并且该代码需要知道被调试进程的退出状态。能做到吗?

【问题讨论】:

  • 是的,可以做到。您需要订阅dte.Debugger.Events(或dte.DebugEvents?)中的适当事件,并保留对DTE 事件对象的引用,以便在触发实际事件之前不会收集垃圾。此外,您对项目的循环可能已损坏 - 它会跳过解决方案文件夹中的所有项目,并将解决方案文件夹视为项目......老实说,如果你可以做你想做的事情没有丑陋的 EnvDTE 界面(即通过真正的 COM 接口),你可能会更好,但它更多的代码/工作。
  • 感谢有关解决方案文件夹等的指针。我所拥有的将用于我的目的,但我会考虑正确修复它。
  • 我猜dte.Events.DebugEvents.OnEnterDesignMode 是您正在考虑的事件吗?但是那我怎样才能得到被调试进程的退出码呢?
  • 奇怪,我找不到通过 EnvDTE 访问退出代码的方法。不过,可以直接通过 VS 接口进行操作——请参阅我的回答。

标签: c# visual-studio visual-studio-2013 envdte


【解决方案1】:

您可以通过 COM 接口完成此操作(绕过 EnvDTE 自动化层,它主要只是一个精美的包装器)。

class ExitEventListener : IDebugEventCallback2
{
    private IVsDebugger _debugger;

    public ExitEventListener()
    {
        _debugger = Package.GetGlobalService(typeof(SVsShellDebugger)) as IVsDebugger;
        if (_debugger != null)
            _debugger.AdviseDebugEventCallback(this);
    }

    public int Event(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
    {
        if (pEvent is IDebugProgramDestroyEvent2)
        {
            // The process has exited

            uint exitCode;
            if (((IDebugProgramDestroyEvent2)pEvent).GetExitCode(out exitCode) == VSConstants.S_OK)
            {
                // We got the exit code!
            }

            // Stop listening for future exit events
            _debugger.UnadviseDebugEventCallback(this);
            _debugger = null;
        }
        return VSConstants.S_OK;
    }
}

【讨论】:

  • 如果您有时间,能否进一步解释一下您的“EnvDTE 主要是一个花哨的包装器”评论?问候。
  • @Sabuncu:VS 内部是 C++(大量遗留代码,如调试器子系统)和 C#(大量“现代”代码,如编辑器子系统)的混合体,它们公开了 COM 接口.这些 COM 接口用于内部和可扩展性(在公共接口的情况下)。 EnvDTE 是一个遗留的自动化接口,最初是为了允许更容易地扩展 IDE,主要通过 VB6 宏系统(但也包括早期扩展)。现代扩展仍然可以使用 EnvDTE 接口,但它只包装了可用 COM 接口的子集。
  • @Sabuncu 因此,EnvDTE 仅涵盖可用扩展点的一个子集,而 COM 接口提供实际的较低级别的实现。由于 EnvDTE 可能很麻烦,尤其是在键入和错误处理方面,因此没有理由更喜欢它而不是 COM 接口,即使它们公开的共同特性也是如此。最后,更新的可扩展性功能(特别是与编辑器相关)通常通过 MEF 提供,它与 COM 或 EnvDTE 无关,并公开了现有 EnvDTE/COM 接口未涵盖的更多可扩展性功能。
  • 这很有帮助,谢谢。 EnvDTE 和 VSPackage 非常令人困惑。这些似乎不是相互排斥的,我还没有找到关于如何进行的明确指导。如果您有时间,我还有一个最近发布的未回答问题:stackoverflow.com/questions/62555122/… 再次感谢您。
  • VSPackage 又完全是另一回事了。 VS 可扩展性基于挂钩到扩展点和/或暴露由 IDE 的其他部分拾取的 MEF 组件的“包”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-27
  • 2023-01-30
  • 2013-04-11
  • 2015-08-04
  • 1970-01-01
  • 2016-08-16
  • 1970-01-01
相关资源
最近更新 更多