如何在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