如果把.net开发人员比作是行走江湖的侠客,那vs就好比是侠客手中的剑,比武的时候讲究的的一寸长,一寸强,那我们应该如何改善我们的武器呢?铁匠铺的铁匠老软早就为我们做好了准备,他在我们的武器上装了很多环,打了很多洞,我们完全可以在这些环或洞上镶嵌珠宝,让这把剑更加靓丽,也可以在这把剑上装上暗器,增加武器杀伤力,如果您自身还练就了九阳神功,配上这把倚天剑,包你很快就知道无敌真寂寞的滋味。哈哈。不胡诌了,言归正传,本文通过详细的操作步骤讲述一个装饰vs2005的故事。
让我们打开vs2005,选择创建项目,在接下来的向导中选择项目模板:其他项目类型-扩展性-visual studio外接程序,然后给我们的大钻石起个漂亮的名字:RecentProjectCleaner。忘记说了,这个外接程序要完成的任务是在菜单的工具栏创建一个子菜单,点击这个子菜单可以呼出我们的暗器,这个暗器用来清除vs2005起始页中的最近项目列表、 第一个步骤的图示如下:
然后,一路next,直到出现选择外接程序选项对话框的时候,选择如下:
点击下一步,完成向导后,项目模板会自动生成的文件列表如下:
CommandBar.resx ----------- 这个是命令栏的资源文件
Connect.cs ----------- 是一个继承了IDTExtensibility2, IDTCommandTarget的类,是addins的实现类
RecentProjectCleaner.AddIn -------------------这个是addins进行xcopy部署的配置文件,部署的时候拷贝到C:\Documents and Settings\Administrator\My Documents\Visual Studio 2005\Addins
RecentProjectCleaner - For Testing.AddIn -------------这个是调试运行的的测试类,在调试的时候,这个文件会自动拷贝到C:\Documents and Settings\Administrator\My Documents\Visual Studio 2005\Addins位置
首先介绍最主要的文件Connect.cs ,这个类包含如下的实现方法
OnConnection - 处理外接程序加载的时候触发
OnDisconnection - 在处理外接程序卸载的时候触发
OnAddInsUpdate - 外接程序出现更新的时候触发
OnStartupComplete - 外接程序加载结束时候触发
OnBeginShutdown - 开始卸载的时候触发
QueryStatus - 查询状态
Exec - 执行命令
本例中,我们实现的目的是:在工具菜单上创建一个新的子菜单,点击这个菜单,能够清除启动页最近项目列表,所以我们需要做的是
1) 在外接程序加载的时候,创建菜单
2) 点击菜单,执行删除最近列表项的命令
3) 卸载的时候,删除新增菜单项
所以添加工具子菜单的代码要添加到OnConnection 中如下:
OnConnection
1 /**//// <summary>实现 IDTExtensibility2 接口的 OnConnection 方法。接收正在加载外接程序的通知。</summary>
2 /// <param term='application'>宿主应用程序的根对象。</param>
3 /// <param term='connectMode'>描述外接程序的加载方式。</param>
4 /// <param term='addInInst'>表示此外接程序的对象。</param>
5 /// <seealso class='IDTExtensibility2' />
6 public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
7 {
8 _applicationObject = (DTE2)application;
9 _addInInstance = (AddIn)addInInst;
10 if (connectMode == ext_ConnectMode.ext_cm_UISetup)
11 {
12 object[] contextGUIDS = new object[] { };
13 Commands2 commands = (Commands2)_applicationObject.Commands;
14 string toolsMenuName = "工具";
15
16 //将此命令置于“工具”菜单上。
17 //查找 MenuBar 命令栏,该命令栏是容纳所有主菜单项的顶级命令栏:
18 Microsoft.VisualStudio.CommandBars.CommandBar menuBarCommandBar = ((Microsoft.VisualStudio.CommandBars.CommandBars)_applicationObject.CommandBars)["MenuBar"];
19
20 //在 MenuBar 命令栏上查找“工具”命令栏:
21 CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];
22
23
24 CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;
25
26 //如果希望添加多个由您的外接程序处理的命令,可以重复此 try/catch 块,
27 // 只需确保更新 QueryStatus/Exec 方法,使其包含新的命令名。
28 try
29 {
30 //将一个命令添加到 Commands 集合:
31 Command command = commands.AddNamedCommand2(_addInInstance, "RecentProjectCleaner", "RecentProjectCleaner", "Executes the command for RecentProjectCleaner", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton);
32
33 //将对应于该命令的控件添加到“工具”菜单:
34 if ((command != null) && (toolsPopup != null))
35 {
36 command.AddControl(toolsPopup.CommandBar, 10);
37 }
38 }
39 catch (System.ArgumentException)
40 {
41 //如果出现此异常,原因很可能是由于具有该名称的命令
42 // 已存在。如果确实如此,则无需重新创建此命令,并且
43 // 可以放心忽略此异常。
44 }
45 }
46 }
执行命令的操作添加到Exec中,
Exec
/**//// <summary>实现 IDTCommandTarget 接口的 Exec 方法。此方法在调用该命令时调用。</summary>
/// <param term='commandName'>要执行的命令的名称。</param>
/// <param term='executeOption'>描述该命令应如何运行。</param>
/// <param term='varIn'>从调用方传递到命令处理程序的参数。</param>
/// <param term='varOut'>从命令处理程序传递到调用方的参数。</param>
/// <param term='handled'>通知调用方此命令是否已被处理。</param>
/// <seealso class='Exec' />
public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
{
handled = false;
if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
{
if (commandName == "RecentProjectCleaner.Connect.RecentProjectCleaner")
{
DialogResult dr = MessageBox.Show("确定要清除最近项目列表么?", "询问", MessageBoxButtons.YesNo);
if (dr == DialogResult.Yes)
{
Microsoft.Win32.RegistryKey regisKey = Microsoft.Win32.Registry.CurrentUser;
Microsoft.Win32.RegistryKey key = regisKey.OpenSubKey("Software", true);
if (key != null)
{
key = key.OpenSubKey("Microsoft", true);
if (key != null)
{
key = key.OpenSubKey("VisualStudio", true);
}
if (key != null)
{
key = key.OpenSubKey("8.0", true);
}
if (key != null)
{
key = key.OpenSubKey("ProjectMRUList", true);
}
if (key != null)
{
foreach (string p in key.GetValueNames())
{
key.DeleteValue(p, false);
}
}
MessageBox.Show("清除成功,重新启动vs后生效!");
}
}
handled = true;
return;
}
}
}
在程序卸载的时候,卸载菜单项
OnDisconnection
1 /**//// <summary>实现 IDTExtensibility2 接口的 OnDisconnection 方法。接收正在卸载外接程序的通知。</summary>
2 /// <param term='disconnectMode'>描述外接程序的卸载方式。</param>
3 /// <param term='custom'>特定于宿主应用程序的参数数组。</param>
4 /// <seealso class='IDTExtensibility2' />
5 public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
6 {
7 object[] contextGUIDS = new object[] { };
8 Commands2 commands = (Commands2)_applicationObject.Commands;
9 string toolsMenuName= "工具";
10 //将此命令置于“工具”菜单上。
11 //查找 MenuBar 命令栏,该命令栏是容纳所有主菜单项的顶级命令栏:
12 Microsoft.VisualStudio.CommandBars.CommandBar menuBarCommandBar = ((Microsoft.VisualStudio.CommandBars.CommandBars)_applicationObject.CommandBars)["MenuBar"];
13
14 //在 MenuBar 命令栏上查找“工具”命令栏:
15 CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];
16
17
18 CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;
19
20 //如果希望添加多个由您的外接程序处理的命令,可以重复此 try/catch 块,
21 // 只需确保更新 QueryStatus/Exec 方法,使其包含新的命令名。
22 try
23 {
24 //将一个命令添加到 Commands 集合:
25 Command command = commands.AddNamedCommand2(_addInInstance, "RecentProjectCleaner", "RecentProjectCleaner", "Executes the command for RecentProjectCleaner", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton);
26
27 //将对应于该命令的控件添加到“工具”菜单:
28 if ((command != null) && (toolsPopup != null))
29 {
30 command.Delete();
31 }
32 }
33 catch (System.ArgumentException)
34 {
35 //如果出现此异常,原因很可能是由于具有该名称的命令
36 // 已存在。如果确实如此,则无需重新创建此命令,并且
37 // 可以放心忽略此异常。
38 }
39 }
这样一个非常简单的vs2005addins就制作成功了,接下来您就可以将该程序部署到你的倚天剑上了,部署方法超级简单,和vs03不同的是,05支持xcopy部署,您可以将RecentProjectCleaner.AddIn和生成的RecentProjectCleaner.dll拷贝到C:\Documents and Settings\Administrator\My Documents\Visual Studio 2005\Addins,就完成了addins的部署,值得说下的是RecentProjectCleaner.AddIn,这个文件描述了vs2005应该如何认识新增的伙计,它里面定义了宿主应用程序的信息(名称,版本)和addins的信息(所在程序集,类名,加载方式),如果您想在部署后让addins立即被启用,将LoadBehavior设置为1,还有不知道是我本地项目模板的问题还是其他原因,默认创建的RecentProjectCleaner.AddIn里面的Assembly多了.dll。也就是RecentProjectCleaner.dll,这样的dll显然不存在,去掉一个.dll,就可以了
看下部署后的效果吧:重新启动vs2005,点击工具,菜单就多了一项:RecentProjectCleaner,如图
点击外接程序管理器,可以多了一项RecentProjectCleaner
在菜单中点击RecentProjectCleaner,选择清除,重启vs2005,最近列表项就清除了。
这里是源程序,这里只是一个的介绍,大家可以下载下去扩展,很好玩
/Files/jillzhang/RecentProjectCleaner.rar