现在的位置: 首页 > 综合 > 正文

VS2008插件开发(开发过程中菜单的添加和删除)

2013年09月02日 ⁄ 综合 ⁄ 共 3667字 ⁄ 字号 评论关闭

前置背景

         VS带有菜单的插件具体如何开发请参照:http://blog.csdn.net/zgke/article/details/3041630。在我的工程中为了叙述方便(因为我用我的工程中的代码为例子),我把上述网站的例子中的父菜单——代码生成更改为Iava。

硬件环境

         VS2008 + xp sp3 

背景

         最近正在开发一个VS2008的插件(带有菜单),具体什么功能我就不叙述了。在开发过程中遇到这样的一个问题:我无法卸载我的插件菜单。本片文章是记录我在开发过程中该如何去卸载我的插件菜单。

问题描述

现在假设我们开始开发菜单插件,

1.      当前系统有且仅有一个VS2008实例(插件工程,工程名称为IavaMenu),此时是没有安装插件,当前菜单(部分)如下图:

图一

注:因为安装了VAssistX插件,所有有这个菜单项,对本例子中无影响。

2.      用以下的代码来制作插件菜单(代码一):

public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
		{
            BeginData.ApplicationObject = (DTE2)application;
            BeginData.AddInInstance = (AddIn)addInInst;
            if (connectMode == ext_ConnectMode.ext_cm_UISetup)
            {
                Commands2 commands = (Commands2)BeginData.ApplicationObject.Commands;
                string toolsMenuName = "Iava";//父菜单项的名称
                Microsoft.VisualStudio.CommandBars.CommandBar menuBarCommandBar = ((Microsoft.VisualStudio.CommandBars.CommandBars)BeginData.ApplicationObject.CommandBars)["MenuBar"];
                CommandBarControl toolsControl = null;
                try
                {
                    ////这个是删除备份用的,也就是说当不想要此菜单的时候,可以通过这个方法给删除掉.
                    //toolsControl = menuBarCommandBar.Controls[toolsMenuName];
                    //if (toolsControl != null)
                    //{
                    //    toolsControl.Delete(null);
                    //}
                    //return;

                    //如果当前没有toolsMenuName菜单项,不会返回null,直接报错
                    toolsControl = menuBarCommandBar.Controls[toolsMenuName];
                }
                catch
                {
                    
                    CommandBar menuObj = (CommandBar)BeginData.ApplicationObject.Commands.AddCommandBar("Iava(&I)",
                         vsCommandBarType.vsCommandBarTypeMenu,
                        ((Microsoft.VisualStudio.CommandBars.CommandBars)BeginData.ApplicationObject.CommandBars)["MenuBar"], 4);
                    //4表示是第四个菜单项

                    toolsControl = menuBarCommandBar.Controls[toolsMenuName];
                }

                CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;
                Factory.AddMenu(commands, toolsPopup);
            }
}

3.      按F5运行后会启动第二个VS2008实例,该VS2008的菜单的效果是:

图二

4.      终止插件工程,第二个VS2008实例将会自动结束。(3,4步可以重复操作)(这里必须要点击菜单中的按钮,让它激活,否则在第六步的时候不能正确的显示图二的效果,以下的类似步骤都需要有这个操作)

5.      关闭IavaMenu工程,此时系统中没有任何VS2008工程

6.      重新打开IavaMenu工程,此时VS2008的菜单的效果跟第三步中的图片一模一样。并且如果你修改代码中的任何地方,重新生成的时候,将会出现以下的错误:

无法将文件“obj\Debug\IavaMenu.dll”复制到“bin\IavaMenu.dll”。文件“bin\IavaMenu.dll”正由另一进程使用,因此该进程无法访问该文件。

 

为什么会出现这样了?我想主要是因为在第三步的时候,就相当于已经安装了我们自己开发的插件了,所以你再次启动任何一个VS2008的时候,就会加载我们自己的插件。实际上我们希望的是重新打开IavaMenu工程(或者启动一个VS2008实例)的菜单效果跟第一步是一样的,并且该IavaMenu正在被VS2008使用才导致上述的错误。这里有人会要疑惑为什么会有第5,6两个连续的步骤,可以不关闭工程,继续开发菜单,然后调试。实际的开发过程中,有可能我们需要花费数天去开发插件,而不是一天就能开发完成。所以5,6两步可以看成是第五步:当天关闭;第六步:第二天打开。

 

解决方法

目前我只有一个比较麻烦的解决方法,如果有人有好的解决方法请不吝赐教,谢谢。因为已经进行了问题描述中的前5步,我们从第六步开始重新描述,并且步骤序号从1重新开始:

1.      打开IavaMenu工程,详细描述见上述第六步

2.      关闭IavaMenu工程,找到IavaMenu\bin目录下的IavaMenu.dll,并删除掉,这个时候为什么可以删除?因为我已经把所有的VS2008实例关闭了。

3.      重新打开IavaMenu工程,此时的菜单项,依然是跟上述的第三步的菜单项一模一样,但是此时我们先不运行(编译)IavaMenu工程,我们把OnConnection函数修改如下(代码二):

public void OnConnection(object application,ext_ConnectMode connectMode,object addInInst,ref Array custom)
{
            if (connectMode == ext_ConnectMode.ext_cm_UISetup)
            {
                Commands2commands = (Commands2)BeginData.ApplicationObject.Commands;
                stringtoolsMenuName = "Iava";//父菜单项的名称
                Microsoft.VisualStudio.CommandBars.CommandBar menuBarCommandBar= ((Microsoft.VisualStudio.CommandBars.CommandBars)BeginData.ApplicationObject.CommandBars)["MenuBar"];
                CommandBarControltoolsControl = null;
                try
                {
                    //这个是删除备份用的,也就是说当不想要此菜单的时候,可以通过这个方法给删除掉.
                    toolsControl = menuBarCommandBar.Controls[toolsMenuName];
                    if(toolsControl != null)
                    {
                        toolsControl.Delete(null);
                    }
                    return;
                }
                catch
                {
                }
            }
           }

         然后按F5运行。启动第二个VS2008实例,该VS2008的菜单的效果是图一

Iava菜单消失了(上述代码的功劳)。这个时候为什么可以运行?因为我已经在第二步吧IavaMenu.dll给删除了。

4.      暂停IavaMenu工程,第二个VS2008实例将会自动关闭。

5.      关闭IavaMenu工程。

6.      重新打开IavaMenu工程。这个时候的菜单项如图一。这个是我们想要的菜单结果。但是如果我们在代码中作任何的修改,运行(编译)会出现上述问题第六步中的那个错误。

7.      操作同第二步

8.      重新打开IavaMenu工程,菜单是我们想要的结果,这个时候也可以进行正常的编译和运行了

 

注意:千万不能在第五步中就删除IavaMenu.dll,如果在第五步就删除dll文件时,在第六步将不会加载我们修改后的插件(删除菜单),所以依然会出现图二,而不能正确的得到图一的结果。

 

其他问题

在上述的2个执行顺序期间中,我没有启动第三个VS2008实例,如果启动第三个VS2008实例,有可能会出现其他的问题,有兴趣的朋友可以自己去观察观察。

抱歉!评论已关闭.