问题描述
我目前正在试验 Visual Studio 扩展。 我需要订阅一个在实际调试器停止之前被调用的事件。 基本上我只是附加到托管进程(不通过 F5 运行)。问题是停止调试只是“分离”了进程,然后进程继续运行。 我打算用这个事件通知我们的进程退出
我有一个实现 IDebugEventCallback2
、IVsDebuggerEvents
和 IVsDebugProcessnotify
的类。
class MyDebugger : IDebugEventCallback2,IVsDebuggerEvents,IVsDebugProcessnotify
在这个类中,有一个成员使用 IVsDebugger
的 AdviseDebugEventCallback()
和 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 次。
我目前正在查看 BeforeStopDebuggingProcess()
中的 IVsDebugProcessnotify
方法。
但是,我不知道如何从此界面“订阅”或“建议”。
任何建议如何?关于这个话题的谷歌搜索结果并不多。
谢谢!
解决方法
我发现了一些问题,如果推荐与否,请发表评论。
我从这篇文章中得到了一些关于 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);
}
}