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 /// 用于实现外接程序的对象。
2 ///
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 ///
2 /// 设置插件UI
3 ///
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 }
获取当前IDE激活项目的路径:
1 ///
2 /// Gets the Active project FullPath
3 ///
4 ///
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 ///
19 /// Gets the Active project
20 ///
21 ///
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 代码生成器
代码生成器(此处用的是 可以根据用户选择的数据库,选择对应的表,然后生成表结构对应的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,通过定制的代码生成工具来快速生成符合本公司所需的代码,从而从重复机械的劳动中解放出来(虽然完全自动生成的代码不可能直接能用,但是人工在此基础上进行调整,也提升了代码的编写效率,而且减少类似于拼写/标点等人为的错误点等.
虽然我们不生产代码,是代码的搬运工,但是正确的打开方式是用代码去帮我们搬运代码!!!