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

  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         }

 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         }

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

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

时间: 2024-10-26 13:11:34

如何在Visual Studio中开发自己的代码生成器插件的相关文章

Visual Studio中开发

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

如何在Visual Studio中选择C++和C#的编译器版本

博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:如何在Visual Studio中选择C++和C#的编译器版本.

[转]如何在 Visual Studio 中使用 Git 同步代码到 CodePlex

本文转自:http://www.cnblogs.com/stg609/p/3673782.html 开源社区不管在国内还是国外都很火热,微软也曾因为没有开源而倍受指责,但是随着 .Net framework.ASP.Net MVC等框架的逐渐开源,也让大家看到了微软开源的步伐.CodePlex 则是微软自己的一个开源社区,里面聚集了很多开源的项目,那么我们如何才能把自己的开源项目放到这上面呢? 在继续阅读本文前,请确定您已经在 Visual Studio 中安装了 Git 相关的扩展程序,并且大

在Visual Studio中开发Matlab mex文件,生成mexw64/mexw32

csunking贡献,2015-9-22 1712 1.   概述 通过使用C/C++与Matlab混合编程,既可以享受到C代码快速执行的速度,又可以方便的使用Matlab众多的库函数和强大的绘图功能.让Matlab调用C函数是通过DLL文件实现的,而这个DLL的开发过程不仅仅可以使用Matlab自带的mex命令,还可以使用VC++开发环境,使用VC有很多好处,一是让我回到了原来熟悉的开发环境中,二能够使用更加标准的C++编译器,第三点也是最爽的,可以使用VC强大的调试功能. 此次文档更新时使用

如何在Visual studio中修改所使用C#语言的版本

有时候,我们需要在Visual studio里修改当前使用的C#语言的版本,具体修改方法如下:在solution explorer中右键工程->选择属性->切换到Build页->点击'Advanced...'按钮->在弹出的Advanced Build Settings对话框中从Lanuage Version下拉列表框中选择你需要的C#语言版本,请参照下列图示.此外不同版本的VS默认的C#版本如下: Visual Studio 2015: C# 6.0 Visual Studio

在Visual Studio中开发一个C语言程序

→新建一个项目→选择"其他语言","Visual C++",并选择"win32控制台应用程序",并给控制台应用程序起名.→点击"下一步"→点击"完成"→编写如下 #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { printf("Hello C\n"); getchar(); return 0; } →

在Visual Studio 中开发自定义脚手架 Scaffolder

1.官方简单教程 http://blogs.msdn.com/b/webdev/archive/2014/04/03/creating-a-custom-scaffolder-for-visual-studio.aspx 工具支持: 1.安装T4模板引擎(例如:tangibleT4) 2.检查Visual Studio SDK 是否安装 https://msdn.microsoft.com/en-us/library/bb166441 实验环境是Visual Studio 2015,引用的sdk

Visual Studio 中的单元测试 UNIT TEST

原文:Visual Studio 中的单元测试 UNIT TEST 注:本文系作者原创,可随意转载,但请注明出处.如实在不愿注明可留空,强烈反对更改原创出处. TDD(Test-Driven Development) 测试驱动开发是敏捷开发中的一项核心实践和技术,也是一种设计方法论.TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码.单元测试是最基本的测试步骤.位于整个产品开发流程V模型的最底部.大致如图,在各种开发流程中RA&PSD完成后,无需底层基础,

Visual Studio中用于ASP.NET Web项目的Web服务器

当您在 Visual Studio 中开发 Web 项目时,需要 Web 服务器才能测试或运行它们. 利用 Visual Studio,您可以使用不同的 Web 服务器进行测试,包括 IIS Express.Internet Information Services (IIS).外部主机或自定义 Web 服务器. 您可以将其中任何一种 Web 服务器用于基于文件的 Web 应用程序项目. 对于基于文件的网站项目,您可以使用 IIS Express. 本主题介绍每种 Web 服务器以及如何选择要用