我们为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配置,但按钮显示在那里。
欢迎任何有关此主题的提示!
答案 0 :(得分:1)
由于Visual Studio 2008中有多个名为Project
的命令栏,因此您需要找到要插入按钮的正确命令栏。幸运的是,这是一种绝对简单,合理和直观的方法。
<强> 1。查找命令栏的唯一ID
打开注册表编辑器并导航到HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\General
。创建名为EnableVSIPLogging
的新DWORD值,并将值设置为1
。
通过右键单击要在按下SHIFT和CTRL修改器的同时插入控件的控件,可以确定命令栏的唯一GUID和命令ID。这将打开一个这样的消息框:
按CTRL + C复制邮件内容,然后将其粘贴到文本框中。记下Guid
和CmdID
值。
<强> 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"];
}