开发Vs2005 Add-ins----用快捷键插入Guid

Vs2005中对add-ins的支持要比2003好的多了,看了一些这方面的文章,忍不住技痒,自己做了一个小东西,用快捷键Alt + G插入 Guid, 希望可以给大家带来些许的方便,也希望可以激发大家的灵感开发出方便好用的add-in来提高我们的开发效率。

闲话少叙,先给大家提供我的这个小工具的程序集和源文件:

程序集下载,源文件下载

你可以将程序集中的两个文件复制到My Documents\Visual Studio 2005\addins 文件夹下面,然后就可以打开Vs 2005随便打开一个代码文件或者html文件,然后按Alt + G看看效果了。

 

注意:程序在vs2005 team edtion中文版上面测试通过,如果大家有用英文版的需要改一下源文件,重新编译一下才可以使用,很简单的。
 

因为要简要的说一下我在开发过程中遇到的问题,所以把源文件贴一下,方便大家看

ContractedBlock.gif ExpandedBlockStart.gif GuidPickerCode
None.gifusing System;
None.gif
using Extensibility;
None.gif
using EnvDTE;
None.gif
using EnvDTE80;
None.gif
using Microsoft.VisualStudio.CommandBars;
None.gif
using System.Resources;
None.gif
using System.Reflection;
None.gif
using System.Globalization;
None.gif
using System.Collections;
None.gif
using System.Windows.Forms;
None.gif
None.gif
None.gif
namespace Yueyar.Tools.AddIns.GuidGeter
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// 用于实现外接程序的对象。
ExpandedSubBlockEnd.gif    
/// 

InBlock.gif    public class Connect : IDTExtensibility2, IDTCommandTarget
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 实现外接程序对象的构造函数。请将您的初始化代码置于此方法内。
InBlock.gif        public Connect()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private ArrayList _controlList = new ArrayList();
InBlock.gif
InBlock.gif        
const string COMMAND_NAME = "Yueyar_InsertGuid";
InBlock.gif        
const string COMMAND_FULLNAME = "Yueyar.Tools.AddIns.GuidGeter.Connect.Yueyar_InsertGuid";
InBlock.gif        
const string TEXT_DOCUMENT = "TextDocument";
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 实现 IDTExtensibility2 接口的 OnConnection 方法。接收正在加载外接程序的通知。
InBlock.gif        
/// 宿主应用程序的根对象。
InBlock.gif        
/// 描述外接程序的加载方式。
InBlock.gif        
/// 表示此外接程序的对象。
ExpandedSubBlockEnd.gif        
/// 

InBlock.gif        public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            _applicationObject 
= (DTE2)application;
InBlock.gif            _addInInstance 
= (AddIn)addInInst;
InBlock.gif
InBlock.gif            
bool isExists = false;
InBlock.gif            
foreach (Command cmd in _applicationObject.Commands)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
if (cmd.Name == COMMAND_FULLNAME)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    isExists 
= true;
InBlock.gif                    
break;
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif            
if (!isExists)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
try
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
object[] contextUIGUIDs = new object[] dot.gif{ };
InBlock.gif                    Command command 
= _applicationObject.Commands.AddNamedCommand(_addInInstance,
InBlock.gif                        COMMAND_NAME,
InBlock.gif                        
"插入Guid",
InBlock.gif                        
"插入Guid",
InBlock.gif                        
true,
InBlock.gif                        
22,
InBlock.gif                        
ref contextUIGUIDs,
InBlock.gif                        (
int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled);
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif                    command.Bindings 
= (object)new object[] dot.gif{ (object)"文本编辑器::Alt+G" };
ExpandedSubBlockEnd.gif                }

InBlock.gif                
catch (Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    MessageBox.Show(ex.Message);
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 实现 IDTExtensibility2 接口的 OnDisconnection 方法。接收正在卸载外接程序的通知。
InBlock.gif        
/// 描述外接程序的卸载方式。
InBlock.gif        
/// 特定于宿主应用程序的参数数组。
ExpandedSubBlockEnd.gif        
/// 

InBlock.gif        public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (_controlList != null && _controlList.Count > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                CommandBarButton button 
= _controlList[0as CommandBarButton;
InBlock.gif                
object obj = null;
InBlock.gif                button.Delete(obj);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 实现 IDTExtensibility2 接口的 OnAddInsUpdate 方法。当外接程序集合已发生更改时接收通知。
InBlock.gif        
/// 特定于宿主应用程序的参数数组。
ExpandedSubBlockEnd.gif        
///         

InBlock.gif        public void OnAddInsUpdate(ref Array custom)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 实现 IDTExtensibility2 接口的 OnStartupComplete 方法。接收宿主应用程序已完成加载的通知。
InBlock.gif        
/// 特定于宿主应用程序的参数数组。
ExpandedSubBlockEnd.gif        
/// 

InBlock.gif        public void OnStartupComplete(ref Array custom)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 实现 IDTExtensibility2 接口的 OnBeginShutdown 方法。接收正在卸载宿主应用程序的通知。
InBlock.gif        
/// 特定于宿主应用程序的参数数组。
ExpandedSubBlockEnd.gif        
/// 

InBlock.gif        public void OnBeginShutdown(ref Array custom)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 实现 IDTCommandTarget 接口的 QueryStatus 方法。此方法在更新该命令的可用性时调用
InBlock.gif        
/// 要确定其状态的命令的名称。
InBlock.gif        
/// 该命令所需的文本。
InBlock.gif        
/// 该命令在用户界面中的状态。
InBlock.gif        
/// neededText 参数所要求的文本。
ExpandedSubBlockEnd.gif        
/// 

InBlock.gif        public void QueryStatus(string commandName, vsCommandStatusTextWanted neededText, ref vsCommandStatus status, ref object commandText)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (neededText == vsCommandStatusTextWanted.vsCommandStatusTextWantedNone)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
if (commandName == COMMAND_FULLNAME)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    status 
= (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
InBlock.gif                    
return;
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 实现 IDTCommandTarget 接口的 Exec 方法。此方法在调用该命令时调用。
InBlock.gif        
/// 要执行的命令的名称。
InBlock.gif        
/// 描述该命令应如何运行。
InBlock.gif        
/// 从调用方传递到命令处理程序的参数。
InBlock.gif        
/// 从命令处理程序传递到调用方的参数。
InBlock.gif        
/// 通知调用方此命令是否已被处理。
ExpandedSubBlockEnd.gif        
/// 

InBlock.gif        public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            handled 
= false;
InBlock.gif            
if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
if (commandName == COMMAND_FULLNAME)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    Document activeDoc 
= _applicationObject.DTE.ActiveDocument;
InBlock.gif                    
if (activeDoc == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        MessageBox.Show(
"没有活动文档。");
InBlock.gif                        
return;
ExpandedSubBlockEnd.gif                    }

InBlock.gif
InBlock.gif                    TextDocument textDoc 
= activeDoc.Object(TEXT_DOCUMENT) as TextDocument;
InBlock.gif                    
if (textDoc == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        MessageBox.Show(
"请选择要插入Guid的文档。");
InBlock.gif                        
return;
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    EditPoint editPoint 
= textDoc.Selection.ActivePoint.CreateEditPoint();
InBlock.gif                    
string copiedText = Clipboard.GetText();
InBlock.gif                    
if (!textDoc.Selection.IsEmpty) textDoc.Selection.Cut();
InBlock.gif                    editPoint.Insert(Guid.NewGuid().ToString());
InBlock.gif                    Clipboard.SetText(copiedText);
InBlock.gif                    handled 
= true;
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
private DTE2 _applicationObject;
InBlock.gif        
private AddIn _addInInstance;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

 

 

我在开发中遇到的问题:

1_applicationObject.Commands.AddNamedCommand方法抛出 Value does not fall within the expected range.”的异常,但是没有提示哪一个参数有问题,这个问题困扰了我好长时间,原因是CommandName参数中不能包含“.”,因为这个方法在创建Command的时候会在command的名字的前面加上命名空间的名字和Connect的类名,所以大家在开发的时候要记得不能给此方法的CommandName参数赋予包含“.”的值。

2.由于第1点中提到的原因我们在判断IDE中是否已经有了这个命令的时候记得要用全名,而不能用第1点中的CommandName

3.注意Vs2005是英文版的还是中文版,因为add-ins中的CommandBarControl都是通过Caption来取的,而Caption不同的语言版本是不一样的,所以你看了老外的资料中对工具菜单的引用用的名字是Tool时,如果你也用Tool的话就会出问题,这时候我们中文版的用户应该使用“工具(&T)”。

4.同样是因为多语言的原因我们在使用键盘快捷键的时候也有不同,中文的键盘设置可能是这样子的:全局::Ctrl+Shift+7,类关系图::Shift+Alt+B而英文版的就不同了。

5textDoc.Selection.Delete(count)方法总是不能按照理想的效果执行,总是会多删除一些字符,大家可以看到源文件中我用的是Cut方法,这个问题我现在也不知道是什么原因,如果大家知道,请告诉我,谢谢。

希望这些能够对大家有所帮助。

 

你可能感兴趣的:(开发Vs2005 Add-ins----用快捷键插入Guid)