如何在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         #endregion
13 
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                 try
25  { 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                 try
48  { 49                     switch (connectMode) 50  { 51                         case ext_ConnectMode.ext_cm_UISetup: 52                             // We should never get here, this is temporary UI
53  AddAddInUI(); 54                             break; 55 
56                         case ext_ConnectMode.ext_cm_Startup: 57                             // The add-in was marked to load on startup
58  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 Manager 63                             // Initialize it in the same way that when is loaded on startup
64  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 XML Editor  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 Usings 100                         //Create Private Accessor 101                         //Class View Multi-select Project references Items 102                         //Class View Multi-select Project references members 103                         //Class View Project 104                         //Class View Item 105                         //Class View Folder 106                         //Class View Grouping Folder 107                         //Class View Multi-select 108                         //Class View Multi-select members 109                         //Class View Member 110                         //Class View Grouping Members 111                         //Class View Project References Folder 112                         //Class View Project Reference 113                         //Class View Project Reference Item 114                         //Class View Project Reference Member 115                         //Project 116                         //Solution Folder 117                         //Cross Project Solution Project 118                         //Cross Project Solution Item 119                         //Cross Project Project Item 120                         //Cross Project Multi Project 121                         //Cross Project Multi Item 122                         //Cross Project Multi Solution Folder 123                         //Cross Project Multi Project/Folder 124                         //Item 125                         //Folder 126                         //Reference Root 127                         //Reference Item 128                         //Web Reference Folder 129                         //App Designer Folder 130                         //Web Project Folder 131                         //Web Folder 132                         //Web Item 133                         //Web SubWeb 134                         //References 135                         //Misc Files Project 136                         //Solution 137                         //Code Window 138                         //XAML Editor 139                         //Surface 140                         //DataSourceContext 141                         //DbTableContext 142                         //DataTableContext 143                         //RelationContext 144                         //FunctionContext 145                         //ColumnContext 146                         //QueryContext 147                         //DataAccessorContext 148                         //Context 149                         //Basic Context 150                         //Context 151                         //Context 152                         //Context 153                         //HTML Context 154                         //Script Context 155                         //ASPX Context 156                         //ASAX Context 157                         //ASPX Code Context 158                         //ASAX Code Context 159                         //ASPX VB Code Context 160                         //ASAX VB Code Context 161                         //ASMX Code Context 162                         //ASMX VB Code Context 163                         //Change &View 164                         //Static Node 165                         //Object Node 166                         //Multiple Static Nodes 167                         //Multiple Homogenous Object Nodes 168                         //Multiple Heterogenous Object Nodes 169                         //Multiple Heterogenous Nodes 170                         //Add &New 171                         //Selection 172                         //Container 173                         //TraySelection 174                         //Document Outline 175                         //Component Tray 176                         //Propertysheet 177                         //Configuration 178                         //Project 179                         //Multi-Select 180                         //System Propertysheet 181                         //Topic Menu 182                         //Topic Source Menu 183                         //Favorites Window Context Menu 184                         //Data Sources 185                         //Server Explorer 186                         //Managed Resources Editor Context Menu 187                         //Settings Designer 188                         //My Extensibility 189                         //Class Designer Context Menu 190                         //Class Diagram Context Menu 191                         //Class Details Context Menu 192                         //Selection 193                         //&Zoom 194                         //Page Layout 195                         //Designer Actions 196                         //&Navigation Tools 197                         //Resource View 198                         //Resource Editors 199                         //Resource Dialog Editors 200                         //Binary Editor 201                         //CSSDocOutline 202                         //CSSSource 203                         //Checkin Dialog Context Menu 204                         //Pending Checkin Window Context Menu 205                         //Standard TreeGrid context menu 206                         //GetVersion Dialog Context Menu 207                         //Check Out Dialog Context Menu 208                         //Macro 209                         //Module 210                         //Project 211                         //Root 212                         //TocContext 213                         //ResListContext 214                         //Query Diagram Pane 215                         //Query Diagram Table 216                         //Query Diagram Table Column 217                         //Query Diagram Join Line 218                         //Query Diagram Multi-select 219                         //Query Grid Pane 220                         //Query SQL Pane 221                         //Query Results Pane 222                         //Database Designer 223                         //Database Designer Table 224                         //Database Designer Relationship 225                         //Text Annotation 226                         //Database Project 227                         //DB Project Connection 228                         //DB Project Folder 229                         //Database References Folder 230                         //Folders 231                         //DB Project File 232                         //Query 233                         //Script 234                         //Database Reference Node 235                         //Files 236                         //Multi-select 237                         //PropertyBrowser 238                         //Editor 239                         //Script Outline 240                         //DefaultContext 241                         //ImageContext 242                         //SelectionContext 243                         //AnchorContext 244                         //Step Into Specific 245                         //Autos Window 246                         //Breakpoint 247                         //Load Symbols From 248                         //Breakpoints Window 249                         //Call Stack Window 250                         //Thread Tip Window 251                         //Data Tip Window 252                         //Disassembly Window 253                         //Locals Window 254                         //Memory Window 255                         //Modules Window 256                         //Output Window 257                         //Processes Window 258                         //Registers Window 259                         //Threads Window 260                         //Watch Window 261                         //Script Project 262                         //Thread IP Marker 263                         //Thread IP Markers 264                         //Control 265                         //Report 266                         //Row/Column 267                         //Cell 268                         //Field Chooser 269                         //Row/Column 270                         //Chart 271                         //Registry 272                         //File System 273                         //File System 274                         //File Types 275                         //User Interface 276                         //Launch Conditions 277                         //Custom Actions 278                         //New 279                         //Add 280                         //Add Special Folder 281                         //View 282                         //Project Node 283                         //A&dd 284                         //Cab Project Node 285                         //A&dd 286                         //File nodes 287                         //Dep. file nodes 288                         //Assembly nodes 289                         //Dep. assembly nodes 290                         //MSM nodes 291                         //Dep. MSM nodes 292                         //Output nodes 293                         //Simple file nodes 294                         //Simple output nodes 295                         //Dependency node 296                         //Multiple selections 297                         //Dep. Multiple selections 298                         //View 299                         //Editor 300                         //ORDesigner Context Menu 301                         //ORDesigner Context Menu 302                         //ORDesigner Context Menu 303                         //OTBObjCtxtMenu 304                         //SIDE Left Pane Context Menu 305                         //SIDE CertMgr Context Menu 306                         //Registry 307                         //File System 308                         //File System 309                         //New 310                         //Add 311                         //Add Special Folder 312                         //View 313                         //Project Node 314                         //A&dd 315                         //Cab Project Node 316                         //A&dd 317                         //File nodes 318                         //Dep. file nodes 319                         //Assembly nodes 320                         //Dep. assembly nodes 321                         //MSM nodes 322                         //Dep. MSM nodes 323                         //Output nodes 324                         //Dependency node 325                         //Multiple selections 326                         //Dep. Multiple selections 327                         //View 328                         //AppNet Designer Context 329                         //AppNet Project Node Context 330                         //Exe Project 331                         //Debug 332                         //Test Results Context Menu 333                         //Test List Editor Context Menu 334                         //Test List Context Menu 335                         //Test Run Context Menu 336                         //View Context Menu 337                         //Group 338                         //Database 339                         //Edit Text 340                         //Formula Parameter 341                         //Section 342                         //Default 343                         //Object Selection 344                         //Insert to Report 345                         //SchemaExplorer 346                         //AddNewItem 347                         //MicrosoftDataEntityDesign Context 348                         //MicrosoftDataEntityDesign Context 349                         //Find Checkouts 350                         //Pending Solution Checkins 351                         //Views Folder item context menu 352                         //UCM Project item context menu 353                         //View item context menu 354                         //Solution item context menu 355                         //Deliver 356                         //Rebase 357                         //ClearCase search Context Menus 358                         //System
359 
360             #endregion
361             #endregion
362           //------------------------------Code Window------------------------------------------------------
363             object[] contextUIGuids = new object[] { }; 364             Commands2 commands = (Commands2)_applicationObject.Commands; 365             try
366  { 367                 findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_CodeWindow), -1); 368  } 369             catch
370  { 371                 // command doesn't exist
372  } 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 window 392                 //代码
393                 CommandBar codeWindowCommandBar = cmdBars["Code Window"]; 394                //Project 395                //Solution Folder
396                 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             try
408  { 409                 findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_Project), -1); 410  } 411             catch
412  { 413                 // command doesn't exist
414  } 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 Folder
433                 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             try
444  { 445                 findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_Solution), -1); 446  } 447             catch
448  { 449                 // command doesn't exist
450  } 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             try
479  { 480                 findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_MenuBar), -1); 481  } 482             catch
483  { 484                 // command doesn't exist
485  } 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                 //menubar
502                 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             try
515  { 516                 findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_Files), -1); 517  } 518             catch
519  { 520                 // command doesn't exist
521  } 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                 //menubar
538                 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 project 20         /// </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 文件扩展名的 XML 文件来完成此操作。.addin 文件描述了 Visual Studio 在“外接程序管理器”中显示外接程序所需的信息。 在 Visual Studio 启动时,它会查找 .addin 文件位置,获取任何可用的 .addin 文件。 如果找到相应文件,则会读取 XML 文件并向“外接程序管理器”提供在单击外接程序进行启动时所需的信息。使用外接程序向导创建外接程序时,会自动创建一个 .addin 文件。 你也可以使用本主题中的信息手动创建 .addin 文件。我是用Visual Studio2012 所以将.addin文件和对应的dll拷贝到C:\Users\wangming\Documents\Visual Studio 2012\Addins文件下:

  如果发布没有错误,那么重新启动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,通过定制的代码生成工具来快速生成符合本公司所需的代码,从而从重复机械的劳动中解放出来(虽然完全自动生成的代码不可能直接能用,但是人工在此基础上进行调整,也提升了代码的编写效率,而且减少类似于拼写/标点等人为的错误点等.

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


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM