【问题标题】:Visual Studio Extension capturing event before stopping the Debug Process ( IVsDebugProcessNotify BeforeStopDebuggingProcess)Visual Studio Extension 在停止调试进程之前捕获事件 (IVsDebugProcessNotify BeforeStopDebuggingProcess)
【发布时间】:2021-07-21 10:19:00
【问题描述】:

我目前正在尝试使用 Visual Studio 扩展。 我需要订阅一个在实际调试器停止之前被调用的事件。 基本上我只是附加到托管进程(不通过 F5 运行)。问题是停止调试只是“分离”进程,然后进程继续运行。 我打算用这个事件来通知我们的进程退出

我有一个实现IDebugEventCallback2IVsDebuggerEventsIVsDebugProcessNotify 的类。

class MyDebugger : IDebugEventCallback2, IVsDebuggerEvents, IVsDebugProcessNotify

在这个类中,有一个成员使用IVsDebuggerAdviseDebugEventCallback()AdviseDebuggerEvents() 事件订阅调试器事件。

_debugger = Package.GetGlobalService(typeof(SVsShellDebugger)) as IVsDebugger;
if (_debugger != null)
{
    _debugger.AdviseDebugEventCallback(this);
    _debugger.AdviseDebuggerEvents(this, out _debuggerEventsCookie);
}

然而,我注意到从AdviseDebugEventCallback 的 Event() 处理程序触发的事件并不总是在实际停止调试之前被调用(在我单击停止调试后,断点之后的下几行仍然执行)。大约 4 次或 5 次,来自IDebugCustomEvent110 的事件(2615D9BC-1948-4D21-81EE-7A963F20CF59 的 riidEvent)在附加进程的任何行被进一步执行之前被调用。我仍然需要消化 Event() 处理程序中触发的事件的详细信息,但是查看断点,似乎我不能依赖它,因为它只能按照我的预期工作,大约 5 次中有 4 次。

我目前正在查看IVsDebugProcessNotify 中的BeforeStopDebuggingProcess() 方法。 但是,我不知道如何从此界面“订阅”或“建议”。 有什么建议吗?关于这个主题的谷歌搜索结果并不多。 谢谢!

【问题讨论】:

    标签: visual-studio vsix visual-studio-addins vs-extensibility


    【解决方案1】:

    我发现了一些 hacky,请评论是否推荐。 我从这篇文章中得到了一些关于CommandEvents 的提示: How do I know from my VSIX that a build will be followed by a Debug session?

    首先,我订阅了 DTE 的 commandEvents。

    DTE dte = await serviceProvider.GetServiceAsync(typeof(DTE)) as DTE;
    if (dte != null)
    {
        events = dte.Events;
        commandEvents = events.CommandEvents;
        commandEvents.BeforeExecute += OnBeforeExecute;
    }
    

    然后,在OnBeforeExecute 中,我对这个特定的 GUID 和 ID 进行硬编码,我观察到它在单击停止调试时被触发(在许多其他事件中)。 如果我将 30 秒的 Thread.Sleep() 放入此处理程序中,Visual Studio 的停止按钮会冻结 30 秒(最终是整个 Visual Studio):-) 代码将在等待 30 秒后恢复。

    private void OnBeforeExecute(string Guid, int ID, object CustomIn, object CustomOut, ref bool CancelDefault)
    {
        if (Guid == "{5EFC7975-14BC-11CF-9B2B-00AA00573819}" && ID == 179)
        {
            // Stop command is detected
            Trace.WriteLine($"[OnBeforeExecute] {Guid} --- {ID} Stop Command Detected");
            System.Threading.Thread.Sleep(30000);
        }
    }
    

    【讨论】:

    • 你也可以使用EnvDTE.DebuggerEvents.OnEnterDesignMode,虽然我不知道它是否会为你想要完成的事情太晚。
    • @Cameron 谢谢你的回答。不过,对于我的场景来说,OnEnterDesignMode 触发得太晚了。我刚刚使用了上面发布的解决方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-21
    • 1970-01-01
    • 1970-01-01
    • 2014-01-16
    • 1970-01-01
    • 2018-12-05
    • 1970-01-01
    相关资源
    最近更新 更多