2012-01-16 33 views
0

我们为Visual Studio 2008开发了一个AddIn,它在“项目”上下文菜单中(右键单击解决方案资源管理器中的项目)安装命令栏项目。下面,简化代码(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

由于在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