命令栏控件不会显示

时间:2012-01-16 12:48:10

标签: visual-studio-2008 add-in

我们为Visual Studio 2008开发了一个AddIn,它在“Project”上下文菜单中安装了一个命令栏项(右键单击解决方案资源管理器中的项目)。以下简化代码(在Connect.cs中)适用于我们所有的机器,除了一个:

object[] contextGUIDS = new object[] { };

string commandName = "My_Command";
string tooltip = "My tooltip";

Command projectCommand = applicationObject.Commands.AddNamedCommand(addInInstance, commandName, commandName, tooltip, false, 1, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled);

CommandBars commandBars = (CommandBars)(fApplicationObject.CommandBars);

CommandBar projectCommandBar = commandBars["Project"];

CommandBarControl projectButton = (CommandBarControl)(projectCommand.AddControl(projectCommandBar, projectCommandBar.Controls.Count + 1));

projectButton.Caption = "My caption";
projectButton.TooltipText = tooltip;

在一台计算机上,代码将无异常运行,但按钮不会显示。再次调用安装代码将因为已存在的命令栏项而引发异常。但是,应安装并正确显示另一个应位于“工具”菜单中的项目。

即使已重新安装操作系统和Visual Studio,问题仍然存在(Windows 7 x86 SP1德语版,Visual Studio开发版SP1英文版)。我们有其他机器具有相同的操作系统和VS配置,但按钮显示在那里。

欢迎任何有关此主题的提示!

1 个答案:

答案 0 :(得分:1)

由于Visual Studio 2008中有多个名为Project的命令栏,因此您需要找到要插入按钮的正确命令栏。幸运的是,这是一种绝对简单,合理和直观的方法。

<强> 1。查找命令栏的唯一ID

打开注册表编辑器并导航到HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\General。创建名为EnableVSIPLogging的新DWORD值,并将值设置为1

通过右键单击要在按下SHIFT和CTRL修改器的同时插入控件的控件,可以确定命令栏的唯一GUID和命令ID。这将打开一个这样的消息框:

Visual Studio 2008 Debugging Message

按CTRL + C复制邮件内容,然后将其粘贴到文本框中。记下GuidCmdID值。

<强> 2。通过Guid和CmdID获取命令栏

您可以使用以下代码段从上面确定的值中获取命令栏:

private CommandBar FindCommandBar(Guid guidCmdGroup, uint menuID)
{
  IOleServiceProvider sp = (IOleServiceProvider)fApplicationObject;
  Guid guidSvc = typeof(IVsProfferCommands).GUID;
  Object objService;
  sp.QueryService(ref guidSvc, ref guidSvc, out objService);
  IVsProfferCommands vsProfferCmds = (IVsProfferCommands)objService;
  return vsProfferCmds.FindCommandBar(IntPtr.Zero, ref guidCmdGroup, menuID) as CommandBar;
}

[ComImport, Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IOleServiceProvider
{

  [PreserveSig]
  int QueryService([In]ref Guid guidService, [In]ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out System.Object obj);

}

确保在调用FindCommandBar方法之前正确初始化了命令栏,否则调用将失败并显示ComException(HResult E_FAIL)。简单的方法:

private void EnsureInitialized()
{
  var menuBar = ((CommandBars)fApplicationObject.CommandBars)["MenuBar"];
}

来源:http://blogs.msdn.com/b/dr._ex/archive/2007/04/17/using-ivsproffercommands-to-retrieve-a-visual-studio-commandbar.aspx