调试 Visual Studio 扩展时,将使用一个称为实验实例的特殊 Visual Studio 实例在主 Visual Studio IDE 中运行调试器期间托管扩展。 这两个实例并行独立运行。 本文介绍如何在 VS IDE 的实验实例中运行使用 VisualStudio.Extensibility SDK 创建的扩展时调试这些扩展。
扩展处理
调试过程略有不同,具体取决于扩展是在进程内还是进程外运行。 请参阅创建第一个与 VSSDK 兼容的 VisualStudio.Extensibility 扩展。 对于进程外扩展,扩展在 Visual Studio 扩展的专用进程中运行。 此进程称为 Microsoft.ServiceHub.Host.Extensibility
,将中转 Visual Studio 的 IDE 进程与托管扩展的进程之间的所有通信。 使用 F5 启动扩展时,Visual Studio 将启动 Visual Studio 实验实例并连接到托管扩展的进程。 通常不需要关注确切的进程,因为通过在 Visual Studio IDE 中按 F5
从扩展项目启动调试器时,Visual Studio 会找到将调试器连接到的正确进程。
启动调试会话时,不会立即加载扩展程序集及其符号。 在加载扩展之前,Visual Studio 会跟踪可在其中激活扩展的位置。 这是在 VisualStudioContribution
的内部实例中管理的。 即使在扩展加载之前,例如当用户选择特定菜单项、按工具栏按钮或将特定类型的文件加载到编辑器中时,Visual Studio 也包含有关扩展可能的激活位置的信息。 扩展的程序集在 IDE 中激活之前将不会加载。 因此,调试时,首先需要在 Visual Studio IDE 中采取措施来触发要加载的扩展。 例如,你可能需要选择扩展的菜单项或工具栏按钮。 此时,会加载扩展程序集,执行初始化代码,你可以命中断点并单步执行代码。 要在扩展中运行的第一个代码是 Extension
类上的 InitializeAsync
方法,下一个方法是 InitializeServices
。
进程和调用堆栈
如果扩展是进程内扩展,则调用堆栈包括 Visual Studio 堆栈帧以及扩展的堆栈帧。 符号通常不适用于 Visual Studio,但可以你看到 Visual Studio 在其中调用扩展的调用。
对于进程外扩展,你只能看到扩展的调用堆栈;Visual Studio 堆栈帧位于单独的进程中。 Visual Studio 通过与 JsonRpc 兼容的接口调用扩展,ServiceHub 主机将路由此调用,然后在回调过程中,会开始在进程中执行。 回调返回时,控制权将返回给 Visual Studio。
状态会根据需要在各种方法中传递至扩展,并由 IClientContext
实例进行包装,以便能够轻松使用,但请务必考虑到它是状态的快照,在快照时间与从扩展代码中读取快照或在调试器中查看快照时的时间之间,此快照可能会发生更改。
ServiceHub 主机进程中存在一些处理 RPC 代理的内部代码。 如果此层中发生故障,则您发现不了。 此类错误应报告为产品问题。
在 Visual Studio 的实验实例中调试扩展
打开扩展项目。
例如,在派生自
Extension
的主类上扩展的InitializeServices
方法中设置断点。 要在代码行上设置断点,请单击该行,然后按F9
。从主菜单中,选择调试 > 启动调试,或者按
F5
。 Visual Studio 实验实例已启动;同时,ServiceHub 主机进程启动。执行 Visual Studio 实验实例中的步骤,这些步骤会导致扩展激活或重现要调试的方案。
Visual Studio 会在断点处停止。
提示
拥有多个监视器可能很方便,因此,可以在两个不同的监视器上同时看到调试器和实验实例。 你可能想要更改实验实例中的主题,使其更加明显地表明你在任意给定时间使用哪个 IDE。 请参阅在 Visual Studio 中更改字体、颜色和主题。
使用诊断资源管理器调试扩展
有关详细信息,请参阅 VisualStudio.Extensibility 诊断资源管理器。