Fork me on GitHub

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

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

posted @ 2015-11-27 08:10  JackWang-CUMT  阅读(9519)  评论(19编辑  收藏  举报