你的位置:首页 > ASP.net教程

[ASP.net教程]如何在Visual Studio中开发自己的代码生成器插件


   Visual Studio是美国微软公司开发的一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具、代码管控工具、集成开发环境(IDE)等等,且所写的目标代码适用于微软支持的所有平台.可以说.NET开发人员离不开它,它可以极大的提高编写软件的效率. Visual Studio作为一个世界级开发工具,当然支持通过插件方式对其功能进行扩展,开发人员可以定制自己的插件来进一步提升Visual Studio的功能.

1 什么是Add In?

  所谓的add-in就是一些被Visual Studio加载到内存中运行的,能给用户提供特定功能的DLL动态链接库. 对于一般的开发情景来说,最常见的add-in用法就是可以通过.NET语言访问 DTE2 对象. DTE2是Visual Studio Automation Model的顶层对象,它具有一组接口和对象可以与 Visual Studio进行交互.DTE2可以做以下这些事情:

  • 访问和调用Visual Studio内置的函数和对象
  • 执行编译
  • 遍历解决方案中的项目
  • 在Visual Studio IDE中定制UI
  • 扩展Visual Studio功能...

2 创建VS Add In项目

  用Visual Studio 2012创建名为MyVisualStudioAddin的项目(根据向导进行设置,这里不赘述),界面如下:

3 核心 Connect 类

  插件入口就是Connect 类,先看一下Connect的类图:

  • Connect 实现外接程序对象的构造函数。请将您的初始化代码置于此方法内。
  • OnConnection 实现 IDTExtensibility2 接口的 OnConnection 方法。接收正在加载外接程序的通知。
  • OnDisconnection 实现 IDTExtensibility2 接口的 OnDisconnection 方法。接收正在卸载外接程序的通知。
  • OnAddInsUpdate 实现 IDTExtensibility2 接口的 OnAddInsUpdate 方法。当外接程序集合已发生更改时接收通知。
  • OnStartupComplete 实现 IDTExtensibility2 接口的 OnStartupComplete 方法。接收宿主应用程序已完成加载的通知。
  • OnBeginShutdown 实现 IDTExtensibility2 接口的 OnBeginShutdown 方法。接收正在卸载宿主应用程序的通知。
  • QueryStatus 实现 IDTCommandTarget 接口的 QueryStatus 方法。此方法在更新该命令的可用性时调用。
  • Exec 实现 IDTCommandTarget 接口的 Exec 方法。此方法在调用该命令时调用。
  • _applicationObject 是DTE2实例,是宿主应用程序的根对象。
  • _addInInstance是当前插件实例,表示此外接程序的对象。

   首先定义一些内部的对象,主要是自定义的命令,如下所示:

 1   /// <summary>用于实现外接程序的对象。</summary> 2   /// <seealso class='IDTExtensibility2' /> 3   public class Connect : IDTExtensibility2, IDTCommandTarget 4   { 5     #region 命令定义 除了FindInSolutionExplorer外,此处的命令不是根据功能来命令的,而是根据命令所出现的位置来命令的 6     private readonly string MY_COMMAND_FindInSolutionExplorer = "FindInSolutionExplorer"; 7     private readonly string MY_COMMAND_Project = "cmdInProject";//在项目上 8     private readonly string MY_COMMAND_Solution = "cmdInSolution";//在解决方案上 9     private readonly string MY_COMMAND_MenuBar = "cmdInMenuBar";//在菜单栏上10     private readonly string MY_COMMAND_CodeWindow = "cmdInCodeWindow";//代码窗口11     private readonly string MY_COMMAND_Files = "cmdInFiles";12     #endregion13 14     private Command findCommand = null;15     private CommandBarButton findCommandBarButtonButton = null;16     private AddInLogger logger = null;17 18     private DTE2 _applicationObject;19     private EnvDTE.AddIn _addInInstance;20      ......21 }

  初始化插件UI的代码:

 1     public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom) 2     { 3       4       _applicationObject = (DTE2)application; 5       _addInInstance = (AddIn)addInInst; 6       7  8       if (connectMode == ext_ConnectMode.ext_cm_UISetup) 9       {10         object[] contextGUIDS = new object[] { };11         Commands2 commands = (Commands2)_applicationObject.Commands;12         string toolsMenuName = "Tools";13 14         //将此命令置于“工具”菜单上。15         //查找 MenuBar 命令栏,该命令栏是容纳所有主菜单项的顶级命令栏:16         Microsoft.VisualStudio.CommandBars.CommandBar menuBarCommandBar = ((Microsoft.VisualStudio.CommandBars.CommandBars)_applicationObject.CommandBars)["MenuBar"];17 18         //在 MenuBar 命令栏上查找“工具”命令栏:19         CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];20         CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;21 22         //如果希望添加多个由您的外接程序处理的命令,可以重复此 try/catch 块,23         // 只需确保更新 QueryStatus/Exec 方法,使其包含新的命令名。24         try25         {26           //将一个命令添加到 Commands 集合:27           Command command = commands.AddNamedCommand2(_addInInstance, "MyVisualStudioAddin", "MyVS外接程序", "Executes the command for MyVisualStudioAddin", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton);28 29           //将对应于该命令的控件添加到“工具”菜单:30           if ((command != null) && (toolsPopup != null))31           {32             command.AddControl(toolsPopup.CommandBar, 1);33           }34         }35         catch (System.ArgumentException)36         {37           //如果出现此异常,原因很可能是由于具有该名称的命令38           // 已存在。如果确实如此,则无需重新创建此命令,并且39           // 可以放心忽略此异常。40         }41 42 43 44         bool logtoOutputWindow = System.Diagnostics.Debugger.IsAttached;45         logger = new AddInLogger((DTE)_applicationObject, "MyVisualStudioAddin", logtoOutputWindow);46         logger.LogMessage(string.Format("OnConnection() called with connectMode: '{0}'", connectMode));47         try48         {49           switch (connectMode)50           {51             case ext_ConnectMode.ext_cm_UISetup:52               // We should never get here, this is temporary UI53               AddAddInUI();54               break;55 56             case ext_ConnectMode.ext_cm_Startup:57               // The add-in was marked to load on startup58               AddAddInUI();59               break;60 61             case ext_ConnectMode.ext_cm_AfterStartup:62               // The add-in was loaded by hand after startup using the Add-In Manager63               // Initialize it in the same way that when is loaded on startup64               AddAddInUI();65               break;66           }67         }68         catch (Exception ex)69         {70           logger.LogError(ex.ToString());71         }72 73 74       }75     }

View Code
 1     /// <summary> 2     /// 设置插件UI 3     /// </summary> 4     private void AddAddInUI() 5     { 6       #region 获取CommandBars的名称 7       //CommandBars commandBars = (CommandBars)applicationObject.CommandBars; 8       //System.Text.StringBuilder sb = new System.Text.StringBuilder(); 9  10       //foreach (CommandBar cbar in commandBars) 11       //{ 12       //  sb.AppendLine(cbar.Name); 13       //} 14  15       //System.Windows.Forms. Clipboard.SetText(sb.ToString()); 16  17       #region name 18             // MenuBar 19             //Standard 20             //Build 21             //Context Menus 22             //Data Design 23             //Formatting 24             //Style Application 25             //HTML Source Editing 26             //Class Designer Toolbar 27             //Text Editor 28             //Workflow 29             //Dialog Editor 30             //Image Editor 31             //Style Sheet 32             //Source Control 33             //Recorder 34             //Microsoft  35             //Query Designer 36             //View Designer 37             //Database Diagram 38             //Table Designer 39             //Layout 40             //Help 41             //Debug Location 42             //Debug 43             //Report Formatting 44             //Report Borders 45             //Device 46             //Microsoft Office Excel 2007 47             //Microsoft Office Excel 2003 48             //Microsoft Office Word 2007 49             //Microsoft Office Word 2003 50             //Test Tools 51             //CrystalReportMain 52             //CrystalReportInsert 53             //ClearCase - Base 54             //ClearCase - UCM 55             //Error List 56             //Docked Window 57             //Menu Designer 58             //Properties Window 59             //Toolbox 60             //Task List 61             //Results List 62             //Stub Project 63             //No Commands Available 64             //Command Window 65             //AutoHidden Windows 66             //Expansion Manager 67             //Find Regular Expression Builder 68             //Replace Regular Expression Builder 69             //Wild Card Expression Builder 70             //Wild Card Expression Builder 71             //External Tools Arguments 72             //External Tools Directories 73             //Easy MDI Tool Window 74             //Easy MDI Document Window 75             //Easy MDI Dragging 76             //Open Drop Down 77             //Object Browser Objects Pane 78             //Object Browser Members Pane 79             //Object Browser Description Pane 80             //Find Symbol 81             //Drag and Drop 82             //Bookmark Window 83             //Error Correction 84             //EzMDI Files 85             //Ca&ll Browser 86             //Preview Changes 87             //Discover Service References 88             //Smart Tag 89             //Editor Context Menus 90             //Class View Context Menus 91             //Debugger Context Menus 92             //Project and Solution Context Menus 93             //Other Context Menus 94             //Sort By 95             //Show Columns 96             //Implement Interface 97             //Resolve 98             //Refactor 99             //Organize Usings100             //Create Private Accessor101             //Class View Multi-select Project references Items102             //Class View Multi-select Project references members103             //Class View Project104             //Class View Item105             //Class View Folder106             //Class View Grouping Folder107             //Class View Multi-select108             //Class View Multi-select members109             //Class View Member110             //Class View Grouping Members111             //Class View Project References Folder112             //Class View Project Reference113             //Class View Project Reference Item114             //Class View Project Reference Member115             //Project116             //Solution Folder117             //Cross Project Solution Project118             //Cross Project Solution Item119             //Cross Project Project Item120             //Cross Project Multi Project121             //Cross Project Multi Item122             //Cross Project Multi Solution Folder123             //Cross Project Multi Project/Folder124             //Item125             //Folder126             //Reference Root127             //Reference Item128             //Web Reference Folder129             //App Designer Folder130             //Web Project Folder131             //Web Folder132             //Web Item133             //Web SubWeb134             //References135             //Misc Files Project136             //Solution137             //Code Window138             //XAML Editor139             //Surface140             //DataSourceContext141             //DbTableContext142             //DataTableContext143             //RelationContext144             //FunctionContext145             //ColumnContext146             //QueryContext147             //DataAccessorContext148             //Context149             //Basic Context150             //Context151             //Context152             //Context153             //HTML Context154             //Script Context155             //ASPX Context156             //ASAX Context157             //ASPX Code Context158             //ASAX Code Context159             //ASPX VB Code Context160             //ASAX VB Code Context161             //ASMX Code Context162             //ASMX VB Code Context163             //Change &View164             //Static Node165             //Object Node166             //Multiple Static Nodes167             //Multiple Homogenous Object Nodes168             //Multiple Heterogenous Object Nodes169             //Multiple Heterogenous Nodes170             //Add &New171             //Selection172             //Container173             //TraySelection174             //Document Outline175             //Component Tray176             //Propertysheet177             //Configuration178             //Project179             //Multi-Select180             //System Propertysheet181             //Topic Menu182             //Topic Source Menu183             //Favorites Window Context Menu184             //Data Sources185             //Server Explorer186             //Managed Resources Editor Context Menu187             //Settings Designer188             //My Extensibility189             //Class Designer Context Menu190             //Class Diagram Context Menu191             //Class Details Context Menu192             //Selection193             //&Zoom194             //Page Layout195             //Designer Actions196             //&Navigation Tools197             //Resource View198             //Resource Editors199             //Resource Dialog Editors200             //Binary Editor201             //CSSDocOutline202             //CSSSource203             //Checkin Dialog Context Menu204             //Pending Checkin Window Context Menu205             //Standard TreeGrid context menu206             //GetVersion Dialog Context Menu207             //Check Out Dialog Context Menu208             //Macro209             //Module210             //Project211             //Root212             //TocContext213             //ResListContext214             //Query Diagram Pane215             //Query Diagram Table216             //Query Diagram Table Column217             //Query Diagram Join Line218             //Query Diagram Multi-select219             //Query Grid Pane220             //Query SQL Pane221             //Query Results Pane222             //Database Designer223             //Database Designer Table224             //Database Designer Relationship225             //Text Annotation226             //Database Project227             //DB Project Connection228             //DB Project Folder229             //Database References Folder230             //Folders231             //DB Project File232             //Query233             //Script234             //Database Reference Node235             //Files236             //Multi-select237             //PropertyBrowser238             //Editor239             //Script Outline240             //DefaultContext241             //ImageContext242             //SelectionContext243             //AnchorContext244             //Step Into Specific245             //Autos Window246             //Breakpoint247             //Load Symbols From248             //Breakpoints Window249             //Call Stack Window250             //Thread Tip Window251             //Data Tip Window252             //Disassembly Window253             //Locals Window254             //Memory Window255             //Modules Window256             //Output Window257             //Processes Window258             //Registers Window259             //Threads Window260             //Watch Window261             //Script Project262             //Thread IP Marker263             //Thread IP Markers264             //Control265             //Report266             //Row/Column267             //Cell268             //Field Chooser269             //Row/Column270             //Chart271             //Registry272             //File System273             //File System274             //File Types275             //User Interface276             //Launch Conditions277             //Custom Actions278             //New279             //Add280             //Add Special Folder281             //View282             //Project Node283             //A&dd284             //Cab Project Node285             //A&dd286             //File nodes287             //Dep. file nodes288             //Assembly nodes289             //Dep. assembly nodes290             //MSM nodes291             //Dep. MSM nodes292             //Output nodes293             //Simple file nodes294             //Simple output nodes295             //Dependency node296             //Multiple selections297             //Dep. Multiple selections298             //View299             //Editor300             //ORDesigner Context Menu301             //ORDesigner Context Menu302             //ORDesigner Context Menu303             //OTBObjCtxtMenu304             //SIDE Left Pane Context Menu305             //SIDE CertMgr Context Menu306             //Registry307             //File System308             //File System309             //New310             //Add311             //Add Special Folder312             //View313             //Project Node314             //A&dd315             //Cab Project Node316             //A&dd317             //File nodes318             //Dep. file nodes319             //Assembly nodes320             //Dep. assembly nodes321             //MSM nodes322             //Dep. MSM nodes323             //Output nodes324             //Dependency node325             //Multiple selections326             //Dep. Multiple selections327             //View328             //AppNet Designer Context329             //AppNet Project Node Context330             //Exe Project331             //Debug332             //Test Results Context Menu333             //Test List Editor Context Menu334             //Test List Context Menu335             //Test Run Context Menu336             //View Context Menu337             //Group338             //Database339             //Edit Text340             //Formula Parameter341             //Section342             //Default343             //Object Selection344             //Insert to Report345             //SchemaExplorer346             //AddNewItem347             //MicrosoftDataEntityDesign Context348             //MicrosoftDataEntityDesign Context349             //Find Checkouts350             //Pending Solution Checkins351             //Views Folder item context menu352             //UCM Project item context menu353             //View item context menu354             //Solution item context menu355             //Deliver356             //Rebase357             //ClearCase search Context Menus358             //System359 360       #endregion361       #endregion362      //------------------------------Code Window------------------------------------------------------363       object[] contextUIGuids = new object[] { };364       Commands2 commands = (Commands2)_applicationObject.Commands;365       try366       {367         findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_CodeWindow), -1);368       }369       catch370       {371         // command doesn't exist372       }373 374       if (findCommand == null)375       {376         findCommand = commands.AddNamedCommand2(377           _addInInstance,378           MY_COMMAND_CodeWindow,379           MY_COMMAND_CodeWindow,380           MY_COMMAND_CodeWindow,381           false,382           MyVisualStudioAddin.Properties.Resources._default,383           ref contextUIGuids,384           (int)(vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled));385       }386 387       CommandBars cmdBars = (CommandBars)_applicationObject.CommandBars;388 389       if (findCommand != null)390       {391         // Add a button to the code window context window392         //代码393         CommandBar codeWindowCommandBar = cmdBars["Code Window"];394        //Project395        //Solution Folder396         if (codeWindowCommandBar != null)397         {398           findCommandBarButtonButton = (CommandBarButton)findCommand.AddControl(399             codeWindowCommandBar, codeWindowCommandBar.Controls.Count + 1);400           findCommandBarButtonButton.Caption = "Code Window";401         }402       }403 404       //-------------------------------------project---------------------------------------------------------------405       findCommand = null;406       contextUIGuids = new object[] { };407       try408       {409         findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_Project), -1);410       }411       catch412       {413         // command doesn't exist414       }415 416       if (findCommand == null)417       {418         findCommand = commands.AddNamedCommand2(419           _addInInstance,420           MY_COMMAND_Project,421           MY_COMMAND_Project,422           MY_COMMAND_Project,423           false,424           MyVisualStudioAddin.Properties.Resources.man,425           ref contextUIGuids,426           (int)(vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled));427       }428       if (findCommand != null)429       {430         //项目431         CommandBar codeWindowCommandBar2 = cmdBars["Project"];432         //Solution Folder433         if (codeWindowCommandBar2 != null)434         {435           findCommandBarButtonButton = (CommandBarButton)findCommand.AddControl(436             codeWindowCommandBar2, codeWindowCommandBar2.Controls.Count + 1);437           findCommandBarButtonButton.Caption = "生成表结构类";438         }439       }440       //-----------------------------------------解决方案---------------------------------------------------------441       findCommand = null;442       contextUIGuids = new object[] { };443       try444       {445         findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_Solution), -1);446       }447       catch448       {449         // command doesn't exist450       }451 452       if (findCommand == null)453       {454         findCommand = commands.AddNamedCommand2(455           _addInInstance,456           MY_COMMAND_Solution,457           MY_COMMAND_Solution,458           MY_COMMAND_Solution,459           false,460           MyVisualStudioAddin.Properties.Resources.FindHS,461           ref contextUIGuids,462           (int)(vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled));463       }464       if (findCommand != null)465       {466         //解决方案467         CommandBar codeWindowCommandBar3 = cmdBars["Solution"];468         if (codeWindowCommandBar3 != null)469         {470           findCommandBarButtonButton = (CommandBarButton)findCommand.AddControl(471             codeWindowCommandBar3, codeWindowCommandBar3.Controls.Count + 1);472           findCommandBarButtonButton.Caption = "生成表结构类";473         }474       }475       //-------------------------------------------MenuBar-------------------------------------------------------476       findCommand = null;477       contextUIGuids = new object[] { };478       try479       {480         findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_MenuBar), -1);481       }482       catch483       {484         // command doesn't exist485       }486 487       if (findCommand == null)488       {489         findCommand = commands.AddNamedCommand2(490           _addInInstance,491           MY_COMMAND_MenuBar,492           MY_COMMAND_MenuBar,493           MY_COMMAND_MenuBar,494           false,495           MyVisualStudioAddin.Properties.Resources.man,496           ref contextUIGuids,497           (int)(vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled));498       }499       if (findCommand != null)500       {501         //menubar502         CommandBar codeWindowCommandBar4 = cmdBars["MenuBar"];503         if (codeWindowCommandBar4 != null)504         {505           findCommandBarButtonButton = (CommandBarButton)findCommand.AddControl(506             codeWindowCommandBar4, codeWindowCommandBar4.Controls.Count + 1);507           findCommandBarButtonButton.Caption = "JackWang";508         }509 510       }511       //--------------------------Files------------------------------512       findCommand = null;513       contextUIGuids = new object[] { };514       try515       {516         findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_Files), -1);517       }518       catch519       {520         // command doesn't exist521       }522 523       if (findCommand == null)524       {525         findCommand = commands.AddNamedCommand2(526           _addInInstance,527           MY_COMMAND_Files,528           MY_COMMAND_Files,529           MY_COMMAND_Files,530           false,531           MyVisualStudioAddin.Properties.Resources.man,532           ref contextUIGuids,533           (int)(vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled));534       }535       if (findCommand != null)536       {537         //menubar538         CommandBar codeWindowCommandBar4 = cmdBars["Item"];539         if (codeWindowCommandBar4 != null)540         {541           findCommandBarButtonButton = (CommandBarButton)findCommand.AddControl(542             codeWindowCommandBar4, codeWindowCommandBar4.Controls.Count + 1);543           findCommandBarButtonButton.Caption = "生成表结构类";544         }545 546       }547 548 549 550     }

View Code
 1     public void QueryStatus(string commandName, vsCommandStatusTextWanted neededText, ref vsCommandStatus status, ref object commandText) 2     { 3       try 4       { 5         if (neededText == vsCommandStatusTextWanted.vsCommandStatusTextWantedNone) 6         { 7           if (commandName == "MyVisualStudioAddin.Connect.MyVisualStudioAddin") 8           { 9             status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;10             return;11           }12 13           if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_FindInSolutionExplorer))14           {15             Solution solution = _applicationObject.Solution;16             status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;17             return;18           }19           if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_CodeWindow))20           {21             Solution solution = _applicationObject.Solution;22             status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;23             return;24           }25           if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_MenuBar))26           {27             Solution solution = _applicationObject.Solution;28             status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;29             return;30           }31           if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_Project))32           {33             Solution solution = _applicationObject.Solution;34             status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;35             return;36           }37           if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_Solution))38           {39             Solution solution = _applicationObject.Solution;40             status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;41             return;42           }43           if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_Files))44           {45             Solution solution = _applicationObject.Solution;46             status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;47             return;48           }49         }50       }51       catch (Exception ex)52       {53         logger.LogError(ex.ToString());54       }55     }

View Code
 1     public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled) 2     { 3       try 4       { 5         handled = false; 6         if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault) 7         { 8           //命名空间.Connect.命名 9           if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_FindInSolutionExplorer))10           {11             FindCurrentActiveDocumentInSolutionExplorer();12             handled = true;13             return;14           }15           if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_CodeWindow))16           {17             string fullpath = this.GetActiveProjectFullPath();18             if (fullpath != "")19             {20               POCOGenerator.ConnectionForm frm = new POCOGenerator.ConnectionForm(fullpath);21               frm.Show();22             }23             handled = true;24             return;25           }26           if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_MenuBar))27           {28             string fullpath = this.GetActiveProjectFullPath();29             if (fullpath != "")30             {31               POCOGenerator.ConnectionForm frm = new POCOGenerator.ConnectionForm(fullpath);32               frm.Show();33             }34             handled = true;35             return;36           }37           if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_Project))38           {39             string fullpath = this.GetActiveProjectFullPath();40             if (fullpath != "")41             {42               POCOGenerator.ConnectionForm frm = new POCOGenerator.ConnectionForm(fullpath);43               frm.Show();44             }45            46             handled = true;47             return;48           }49           if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_Solution))50           {51             string fullpath = this.GetActiveProjectFullPath();52             if (fullpath != "")53             {54               POCOGenerator.ConnectionForm frm = new POCOGenerator.ConnectionForm(fullpath);55               frm.Show();56             }57             handled = true;58             return;59           }60           if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_Files))61           {62             string fullpath = this.GetActiveProjectFullPath();63             if (fullpath != "")64             {65               POCOGenerator.ConnectionForm frm = new POCOGenerator.ConnectionForm(fullpath);66               frm.Show();67             }68             handled = true;69             return;70           }71          72           if (commandName == "MyVisualStudioAddin.Connect.MyVisualStudioAddin")73           {74             string fullpath = this.GetActiveProjectFullPath();75             if (fullpath != "")76             {77               POCOGenerator.ConnectionForm frm = new POCOGenerator.ConnectionForm(fullpath);78               frm.Show();79             }80             handled = true;81             return;82           }83 84         85         }86       }87       catch (Exception ex)88       {89         logger.LogError(ex.ToString());90       }91     92     }

View Exec Code

   获取当前IDE激活项目的路径:

 1    /// <summary> 2     /// Gets the Active project FullPath 3     /// </summary> 4     /// <returns></returns> 5     public string GetActiveProjectFullPath() 6     { 7      // Returns the name of the currently selected project in the solution. 8       Project proj = getActiveProject(); 9       if (proj!=null)10       {11         string fullPath = proj.Properties.Item("FullPath").Value.ToString();12         return fullPath;13        // return proj.FullName;14       }15       return "";16       17     }18     /// <summary>19     /// Gets the Active project20     /// </summary>21     /// <returns></returns>22     public Project getActiveProject()23     {24       Array projects = (Array)_applicationObject.ActiveSolutionProjects;25       if (projects != null && projects.Length > 0)26       {27         return projects.GetValue(0) as Project;28       }29       projects = (Array)_applicationObject.Solution.SolutionBuild.StartupProjects;30       if (projects != null && projects.Length >= 1)31       {32         return projects.GetValue(0) as Project;33       }34       projects = (Array)_applicationObject.Solution.Projects;35       if (projects != null && projects.Length > 0)36       {37         return projects.GetValue(0) as Project;38       }39       return null;40     }

  关于如何根据数据库结构生成C# Code代码,可以参加此文章.

4 插件发布

  创建了外接程序后,必须先向 Visual Studio 注册此外接程序,然后才能在“外接程序管理器”中激活它。 使用具有 .addin 文件扩展名的

  如果发布没有错误,那么重新启动Visual Studio2012后,在项目文件上右击弹出菜单,可以看到下面的界面:

  同时在菜单栏创建了一个JackWang的命令按钮和工具菜单下还添加了一个MyVS外接程序的命令按钮,如下图:

5 代码生成器

  代码生成器(此处用的是yuvalsol的工程,我将其整合到插件中)可以根据用户选择的数据库,选择对应的表,然后生成表结构对应的C#类:

 6 插件卸载

  如果自己定义的插件想卸载怎么办?可参见https://msdn.microsoft.com/en-us/library/ms228765.aspx.

  • 删除插件对应的.addin文件. 默认路径为..\Users\username\My Documents\Visual Studio 2012\Addins\(请根据实际情况查看具体路径)

  • 在 Visual Studio开发人员命令行中, 输入devenv /resetaddin MyVisualStudioAddin.Connect  进行卸载(MyVisualStudioAddin.Connect 是MyVisualStudioAddin.AddIn文件中的FullClassName;

  • 至此, add-in 不会出现在IDE中,卸载完成. 但是要完整去除必须手动删除插件对应的项目文件(如果你再次调试,可能会再次进行注册);

 7 总结

  通过插件机制可以方便的定制VS IDE, 一般软件公司都有自己的一套框架,其代码也有一定的封装,且各不相同,可以通过扩展VS,通过定制的代码生成工具来快速生成符合本公司所需的代码,从而从重复机械的劳动中解放出来(虽然完全自动生成的代码不可能直接能用,但是人工在此基础上进行调整,也提升了代码的编写效率,而且减少类似于拼写/标点等人为的错误点等.

  虽然我们不生产代码,是代码的搬运工,但是正确的打开方式是用代码去帮我们搬运代码!!!