如果把.net开发人员比作是行走江湖的侠客,那vs就好比是侠客手中的剑,比武的时候讲究的的一寸长,一寸强,那我们应该如何改善我们的武器呢?铁匠铺的铁匠老软早就为我们做好了准备,他在我们的武器上装了很多环,打了很多洞,我们完全可以在这些环或洞上镶嵌珠宝,让这把剑更加靓丽,也可以在这把剑上装上暗器,增加武器杀伤力,如果您自身还练就了九阳神功,配上这把倚天剑,包你很快就知道无敌真寂寞的滋味。哈哈。不胡诌了,言归正传,本文通过详细的操作步骤讲述一个装饰vs2005的故事。
让我们打开vs2005,选择创建项目,在接下来的向导中选择项目模板:其他项目类型-扩展性-visual studio外接程序,然后给我们的大钻石起个漂亮的名字:RecentProjectCleaner。忘记说了,这个外接程序要完成的任务是在菜单的工具栏创建一个子菜单,点击这个子菜单可以呼出我们的暗器,这个暗器用来清除vs2005起始页中的最近项目列表、 第一个步骤的图示如下:
![](/images/cnblogs_com/jillzhang/tt6644ffd.JPG)
然后,一路next,直到出现选择外接程序选项对话框的时候,选择如下:
![](/images/cnblogs_com/jillzhang/dds3455.JPG)
点击下一步,完成向导后,项目模板会自动生成的文件列表如下:
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 中如下:
![](/Images/OutliningIndicators/ContractedBlock.gif)
OnConnection
1![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//// <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![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
8
_applicationObject = (DTE2)application;
9
_addInInstance = (AddIn)addInInst;
10
if (connectMode == ext_ConnectMode.ext_cm_UISetup)
11![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
12![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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![](/Images/OutliningIndicators/InBlock.gif)
20
//在 MenuBar 命令栏上查找“工具”命令栏:
21
CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];
22
23
24
CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;
25![](/Images/OutliningIndicators/InBlock.gif)
26
//如果希望添加多个由您的外接程序处理的命令,可以重复此 try/catch 块,
27
// 只需确保更新 QueryStatus/Exec 方法,使其包含新的命令名。
28
try
29![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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![](/Images/OutliningIndicators/InBlock.gif)
33
//将对应于该命令的控件添加到“工具”菜单:
34
if ((command != null) && (toolsPopup != null))
35![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
36
command.AddControl(toolsPopup.CommandBar, 10);
37
}
38
}
39
catch (System.ArgumentException)
40![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
41
//如果出现此异常,原因很可能是由于具有该名称的命令
42
// 已存在。如果确实如此,则无需重新创建此命令,并且
43
// 可以放心忽略此异常。
44
}
45
}
46
}
执行命令的操作添加到Exec中,
![](/Images/OutliningIndicators/ContractedBlock.gif)
Exec
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//// <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)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
handled = false;
if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (commandName == "RecentProjectCleaner.Connect.RecentProjectCleaner")
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
DialogResult dr = MessageBox.Show("确定要清除最近项目列表么?", "询问", MessageBoxButtons.YesNo);
if (dr == DialogResult.Yes)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Microsoft.Win32.RegistryKey regisKey = Microsoft.Win32.Registry.CurrentUser;
Microsoft.Win32.RegistryKey key = regisKey.OpenSubKey("Software", true);
if (key != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
key = key.OpenSubKey("Microsoft", true);
if (key != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
key = key.OpenSubKey("VisualStudio", true);
}
if (key != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
key = key.OpenSubKey("8.0", true);
}
if (key != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
key = key.OpenSubKey("ProjectMRUList", true);
}
if (key != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
foreach (string p in key.GetValueNames())
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
key.DeleteValue(p, false);
}
}
MessageBox.Show("清除成功,重新启动vs后生效!");
}
}
handled = true;
return;
}
}
}
在程序卸载的时候,卸载菜单项
![](/Images/OutliningIndicators/ContractedBlock.gif)
OnDisconnection
1![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//// <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![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
7![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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![](/Images/OutliningIndicators/InBlock.gif)
14
//在 MenuBar 命令栏上查找“工具”命令栏:
15
CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];
16![](/Images/OutliningIndicators/InBlock.gif)
17![](/Images/OutliningIndicators/InBlock.gif)
18
CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;
19![](/Images/OutliningIndicators/InBlock.gif)
20
//如果希望添加多个由您的外接程序处理的命令,可以重复此 try/catch 块,
21
// 只需确保更新 QueryStatus/Exec 方法,使其包含新的命令名。
22
try
23![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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![](/Images/OutliningIndicators/InBlock.gif)
27
//将对应于该命令的控件添加到“工具”菜单:
28
if ((command != null) && (toolsPopup != null))
29![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
30
command.Delete();
31
}
32
}
33
catch (System.ArgumentException)
34![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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,如图
![](/images/cnblogs_com/jillzhang/we3443.JPG)
点击外接程序管理器,可以多了一项RecentProjectCleaner
在菜单中点击RecentProjectCleaner,选择清除,重启vs2005,最近列表项就清除了。
这里是源程序,这里只是一个的介绍,大家可以下载下去扩展,很好玩
/Files/jillzhang/RecentProjectCleaner.rar