如何在 Debug > Windows 菜单中添加仅在断点显示的菜单命令?
How to add menu command in Debug > Windows menu showing only in breakpoint?
我正在创建一个包含工具 Window 的 VSIX。我想将打开它的菜单项移动到 Debug > Windows,而不是 View > Other Windows。我还想仅在目标项目处于调试模式时显示它(例如调用堆栈菜单项)。
我设法在“调试”菜单中显示了菜单项,但在“调试”> Windows 中却没有。在我的 .vsct 中,我使用了:
<!-- ... -->
<Extern href="VSDbgCmd.h"/>
<Extern href="VsDebugGuids.h"/>
<!-- ... -->
<Parent guid="guidVSDebugGroup" id="IDM_DEBUG_WINDOWS"/>
<!-- ... -->
关于仅在调试模式下显示它,我没有任何想法,也找不到任何有用的东西。
所以我的问题是:如何让我的菜单项表现得像调用堆栈菜单项(在调试 > Window 中并且仅在调试模式下显示)?
虽然有一个 UI“调试”上下文,但似乎没有用于调试器实际进入中断模式的上下文。 (提示,我使用 https://marketplace.visualstudio.com/items?itemName=PaulHarrington.ComponentDiagnostics 扩展来监视活动的 UI 上下文)
因此您需要向按钮添加 DynamicVisibility 和 DefaultInvisible 命令标志:
<Extern href="stdidcmd.h"/>
<Extern href="vsshlids.h"/>
<Extern href="VSDbgCmd.h"/>
<Extern href="VsDebugGuids.h"/>
<Commands package="guidIaxToolWindowPackage">
<Buttons>
<Button guid="guidIaxToolWindowPackageCmdSet" id="IaxToolWindowCommandId" priority="0x0002" type="Button">
<Parent guid="guidVSDebugGroup" id="IDG_DEBUG_WINDOWS_GENERAL"/>
<Icon guid="guidImages" id="bmpPic1" />
<CommandFlag>DynamicVisibility</CommandFlag>
<CommandFlag>DefaultInvisible</CommandFlag>
<Strings>
<ButtonText>Show IaxToolWindow</ButtonText>
</Strings>
</Button>
</Buttons>
然后,通过使用下面的 ProvideAutoLoad 属性修饰 AsyncPackage class,确保在调试器附加到或启动进程时加载包:
namespace IaxToolwindow
{
// use Debugging UI Context to ensure package get loaded when debugging starts
[ProvideAutoLoad(VSConstants.UICONTEXT.Debugging_string, PackageAutoLoadFlags.BackgroundLoad)]
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
[InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] // Info on this package for Help/About
[ProvideMenuResource("Menus.ctmenu", 1)]
[ProvideToolWindow(typeof(IaxToolWindow))]
[Guid(IaxToolWindowPackage.PackageGuidString)]
public sealed class IaxToolWindowPackage : AsyncPackage
{
public const string PackageGuidString = "256ca1a6-6b6d-4329-a7f9-15ee5bbf8114";
然后为您的菜单命令添加一个 BeforeQueryStatus 命令处理程序,使菜单项在 IVSDebugger.GetMode returns DBGMODE_BREAK 时可见。例如:
private IaxToolWindowCommand(AsyncPackage package, OleMenuCommandService commandService)
{
this.package = package ?? throw new ArgumentNullException(nameof(package));
commandService = commandService ?? throw new ArgumentNullException(nameof(commandService));
var menuCommandID = new CommandID(CommandSet, CommandId);
var menuItem = new OleMenuCommand(this.Execute, menuCommandID);
menuItem.BeforeQueryStatus += IAxToolWindowCommand_BeforeQueryStatus;
commandService.AddCommand(menuItem);
}
private void IAxToolWindowCommand_BeforeQueryStatus(object sender, EventArgs e)
{
ThreadHelper.JoinableTaskFactory.Run(async delegate
{
await Microsoft.VisualStudio.Shell.ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
OleMenuCommand menuItem = (OleMenuCommand)sender;
IVsDebugger vsDebugger = await ServiceProvider.GetServiceAsync(typeof(IVsDebugger)) as IVsDebugger;
Assumes.Present(vsDebugger);
DBGMODE[] dbgmode = new DBGMODE[1];
int hr = vsDebugger.GetMode(dbgmode);
// show menu item when debugger is in break mode
menuItem.Visible = (dbgmode[0] == DBGMODE.DBGMODE_Break);
});
}
这是基于向导生成的 AsyncToolwindow 项目构建的。但请注意,我将 MenuCommand 更改为 OleMenuCommand,因此我们可以添加并使用 BeforeQueryStatus 处理程序来控制菜单项的可见性。
ProvideAutoLoad 用于确保在启动调试会话时加载包,因此它会及时启动以使菜单项可见(当调试器处于中断模式时)。
如果在调试器进入中断模式时激活了一个 UIContext guid,我们可以向 .vsct 添加一个 VisbilityConstraint。但是由于缺少特定于中断模式的 UIContext,您需要执行与上述类似的操作,使菜单项仅在中断模式下可见。
此致,
我正在创建一个包含工具 Window 的 VSIX。我想将打开它的菜单项移动到 Debug > Windows,而不是 View > Other Windows。我还想仅在目标项目处于调试模式时显示它(例如调用堆栈菜单项)。
我设法在“调试”菜单中显示了菜单项,但在“调试”> Windows 中却没有。在我的 .vsct 中,我使用了:
<!-- ... -->
<Extern href="VSDbgCmd.h"/>
<Extern href="VsDebugGuids.h"/>
<!-- ... -->
<Parent guid="guidVSDebugGroup" id="IDM_DEBUG_WINDOWS"/>
<!-- ... -->
关于仅在调试模式下显示它,我没有任何想法,也找不到任何有用的东西。
所以我的问题是:如何让我的菜单项表现得像调用堆栈菜单项(在调试 > Window 中并且仅在调试模式下显示)?
虽然有一个 UI“调试”上下文,但似乎没有用于调试器实际进入中断模式的上下文。 (提示,我使用 https://marketplace.visualstudio.com/items?itemName=PaulHarrington.ComponentDiagnostics 扩展来监视活动的 UI 上下文)
因此您需要向按钮添加 DynamicVisibility 和 DefaultInvisible 命令标志:
<Extern href="stdidcmd.h"/>
<Extern href="vsshlids.h"/>
<Extern href="VSDbgCmd.h"/>
<Extern href="VsDebugGuids.h"/>
<Commands package="guidIaxToolWindowPackage">
<Buttons>
<Button guid="guidIaxToolWindowPackageCmdSet" id="IaxToolWindowCommandId" priority="0x0002" type="Button">
<Parent guid="guidVSDebugGroup" id="IDG_DEBUG_WINDOWS_GENERAL"/>
<Icon guid="guidImages" id="bmpPic1" />
<CommandFlag>DynamicVisibility</CommandFlag>
<CommandFlag>DefaultInvisible</CommandFlag>
<Strings>
<ButtonText>Show IaxToolWindow</ButtonText>
</Strings>
</Button>
</Buttons>
然后,通过使用下面的 ProvideAutoLoad 属性修饰 AsyncPackage class,确保在调试器附加到或启动进程时加载包:
namespace IaxToolwindow
{
// use Debugging UI Context to ensure package get loaded when debugging starts
[ProvideAutoLoad(VSConstants.UICONTEXT.Debugging_string, PackageAutoLoadFlags.BackgroundLoad)]
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
[InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] // Info on this package for Help/About
[ProvideMenuResource("Menus.ctmenu", 1)]
[ProvideToolWindow(typeof(IaxToolWindow))]
[Guid(IaxToolWindowPackage.PackageGuidString)]
public sealed class IaxToolWindowPackage : AsyncPackage
{
public const string PackageGuidString = "256ca1a6-6b6d-4329-a7f9-15ee5bbf8114";
然后为您的菜单命令添加一个 BeforeQueryStatus 命令处理程序,使菜单项在 IVSDebugger.GetMode returns DBGMODE_BREAK 时可见。例如:
private IaxToolWindowCommand(AsyncPackage package, OleMenuCommandService commandService)
{
this.package = package ?? throw new ArgumentNullException(nameof(package));
commandService = commandService ?? throw new ArgumentNullException(nameof(commandService));
var menuCommandID = new CommandID(CommandSet, CommandId);
var menuItem = new OleMenuCommand(this.Execute, menuCommandID);
menuItem.BeforeQueryStatus += IAxToolWindowCommand_BeforeQueryStatus;
commandService.AddCommand(menuItem);
}
private void IAxToolWindowCommand_BeforeQueryStatus(object sender, EventArgs e)
{
ThreadHelper.JoinableTaskFactory.Run(async delegate
{
await Microsoft.VisualStudio.Shell.ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
OleMenuCommand menuItem = (OleMenuCommand)sender;
IVsDebugger vsDebugger = await ServiceProvider.GetServiceAsync(typeof(IVsDebugger)) as IVsDebugger;
Assumes.Present(vsDebugger);
DBGMODE[] dbgmode = new DBGMODE[1];
int hr = vsDebugger.GetMode(dbgmode);
// show menu item when debugger is in break mode
menuItem.Visible = (dbgmode[0] == DBGMODE.DBGMODE_Break);
});
}
这是基于向导生成的 AsyncToolwindow 项目构建的。但请注意,我将 MenuCommand 更改为 OleMenuCommand,因此我们可以添加并使用 BeforeQueryStatus 处理程序来控制菜单项的可见性。
ProvideAutoLoad 用于确保在启动调试会话时加载包,因此它会及时启动以使菜单项可见(当调试器处于中断模式时)。
如果在调试器进入中断模式时激活了一个 UIContext guid,我们可以向 .vsct 添加一个 VisbilityConstraint。但是由于缺少特定于中断模式的 UIContext,您需要执行与上述类似的操作,使菜单项仅在中断模式下可见。
此致,