Visual Studio是美國微軟公司開發的一個基本完整的開發工具集,它包括了整個軟件生命周期中所需要的大部分工具,如UML工具、代碼管控工具、集成開發環境(IDE)等等,且所寫的目標代碼適用于微軟支持的所有平臺.可以說.NET開發人員離不開它,它可以極大的提高編寫軟件的效率. Visual Studio作為一個世界級開發工具,當然支持通過插件方式對其功能進行擴展,開發人員可以定制自己的插件來進一步提升Visual Studio的功能.
所謂的add-in就是一些被Visual Studio加載到內存中運行的,能給用戶提供特定功能的DLL動態鏈接庫. 對于一般的開發情景來說,最常見的add-in用法就是可以通過.NET語言訪問 DTE2 對象. DTE2是Visual Studio Automation Model的頂層對象,它具有一組接口和對象可以與 Visual Studio進行交互.DTE2可以做以下這些事情:
用Visual Studio 2012創建名為MyVisualStudioAddin的項目(根據向導進行設置,這里不贅述),界面如下:
插件入口就是Connect 類,先看一下Connect的類圖:
首先定義一些內部的對象,主要是自定義的命令,如下所示:
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 #endregion13 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 try25 {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 try48 {49 switch (connectMode)50 {51 case ext_ConnectMode.ext_cm_UISetup:52 // We should never get here, this is temporary UI53 AddAddInUI();54 break;55 56 case ext_ConnectMode.ext_cm_Startup:57 // The add-in was marked to load on startup58 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 Manager63 // Initialize it in the same way that when is loaded on startup64 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 Usings100 //Create Private accessor101 //Class View Multi-select Project references Items102 //Class View Multi-select Project references members103 //Class View Project104 //Class View Item105 //Class View Folder106 //Class View Grouping Folder107 //Class View Multi-select108 //Class View Multi-select members109 //Class View Member110 //Class View Grouping Members111 //Class View Project References Folder112 //Class View Project Reference113 //Class View Project Reference Item114 //Class View Project Reference Member115 //Project116 //Solution Folder117 //Cross Project Solution Project118 //Cross Project Solution Item119 //Cross Project Project Item120 //Cross Project Multi Project121 //Cross Project Multi Item122 //Cross Project Multi Solution Folder123 //Cross Project Multi Project/Folder124 //Item125 //Folder126 //Reference Root127 //Reference Item128 //Web Reference Folder129 //App Designer Folder130 //Web Project Folder131 //Web Folder132 //Web Item133 //Web SubWeb134 //References135 //Misc Files Project136 //Solution137 //Code Window138 //XAML Editor139 //Surface140 //DataSourceContext141 //DbTableContext142 //DataTableContext143 //RelationContext144 //FunctionContext145 //ColumnContext146 //QueryContext147 //DataAccessorContext148 //Context149 //Basic Context150 //Context151 //Context152 //Context153 //HTML Context154 //Script Context155 //aspX Context156 //ASAX Context157 //ASPX Code Context158 //ASAX Code Context159 //ASPX VB Code Context160 //ASAX VB Code Context161 //ASMX Code Context162 //ASMX VB Code Context163 //Change &View164 //Static Node165 //Object Node166 //Multiple Static Nodes167 //Multiple Homogenous Object Nodes168 //Multiple Heterogenous Object Nodes169 //Multiple Heterogenous Nodes170 //Add &New171 //Selection172 //Container173 //TraySelection174 //Document Outline175 //Component Tray176 //Propertysheet177 //Configuration178 //Project179 //Multi-Select180 //System Propertysheet181 //Topic Menu182 //Topic Source Menu183 //Favorites Window Context Menu184 //Data Sources185 //Server Explorer186 //Managed Resources Editor Context Menu187 //Settings Designer188 //My Extensibility189 //Class Designer Context Menu190 //Class Diagram Context Menu191 //Class Details Context Menu192 //Selection193 //&Zoom194 //Page Layout195 //Designer Actions196 //&Navigation Tools197 //Resource View198 //Resource Editors199 //Resource Dialog Editors200 //Binary Editor201 //CSSDocOutline202 //CSSSource203 //Checkin Dialog Context Menu204 //Pending Checkin Window Context Menu205 //Standard TreeGrid context menu206 //GetVersion Dialog Context Menu207 //Check Out Dialog Context Menu208 //Macro209 //Module210 //Project211 //Root212 //TocContext213 //ResListContext214 //Query Diagram Pane215 //Query Diagram Table216 //Query Diagram Table Column217 //Query Diagram Join Line218 //Query Diagram Multi-select219 //Query Grid Pane220 //Query SQL Pane221 //Query Results Pane222 //Database Designer223 //Database Designer Table224 //Database Designer Relationship225 //Text Annotation226 //Database Project227 //DB Project Connection228 //DB Project Folder229 //Database References Folder230 //Folders231 //DB Project File232 //Query233 //Script234 //Database Reference Node235 //Files236 //Multi-select237 //PropertyBrowser238 //Editor239 //Script Outline240 //DefaultContext241 //ImageContext242 //SelectionContext243 //AnchorContext244 //Step Into Specific245 //Autos Window246 //Breakpoint247 //Load Symbols From248 //Breakpoints Window249 //Call Stack Window250 //Thread Tip Window251 //Data Tip Window252 //Disassembly Window253 //Locals Window254 //Memory Window255 //Modules Window256 //Output Window257 //Processes Window258 //Registers Window259 //Threads Window260 //Watch Window261 //Script Project262 //Thread IP Marker263 //Thread IP Markers264 //Control265 //Report266 //Row/Column267 //Cell268 //Field Chooser269 //Row/Column270 //Chart271 //Registry272 //File System273 //File System274 //File Types275 //User Interface276 //Launch Conditions277 //Custom Actions278 //New279 //Add280 //Add Special Folder281 //View282 //Project Node283 //A&dd284 //Cab Project Node285 //A&dd286 //File nodes287 //Dep. file nodes288 //Assembly nodes289 //Dep. assembly nodes290 //MSM nodes291 //Dep. MSM nodes292 //Output nodes293 //Simple file nodes294 //Simple output nodes295 //Dependency node296 //Multiple selections297 //Dep. Multiple selections298 //View299 //Editor300 //ORDesigner Context Menu301 //ORDesigner Context Menu302 //ORDesigner Context Menu303 //OTBObjCtxtMenu304 //SIDE Left Pane Context Menu305 //SIDE CertMgr Context Menu306 //Registry307 //File System308 //File System309 //New310 //Add311 //Add Special Folder312 //View313 //Project Node314 //A&dd315 //Cab Project Node316 //A&dd317 //File nodes318 //Dep. file nodes319 //Assembly nodes320 //Dep. assembly nodes321 //MSM nodes322 //Dep. MSM nodes323 //Output nodes324 //Dependency node325 //Multiple selections326 //Dep. Multiple selections327 //View328 //AppNet Designer Context329 //AppNet Project Node Context330 //Exe Project331 //Debug332 //Test Results Context Menu333 //Test List Editor Context Menu334 //Test List Context Menu335 //Test Run Context Menu336 //View Context Menu337 //Group338 //Database339 //Edit Text340 //Formula Parameter341 //Section342 //Default343 //Object Selection344 //Insert to Report345 //SchemaExplorer346 //AddNewItem347 //MicrosoftDataEntityDesign Context348 //MicrosoftDataEntityDesign Context349 //Find Checkouts350 //Pending Solution Checkins351 //Views Folder item context menu352 //UCM Project item context menu353 //View item context menu354 //Solution item context menu355 //Deliver356 //Rebase357 //ClearCase search Context Menus358 //System359 360 #endregion361 #endregion362 //------------------------------Code Window------------------------------------------------------363 object[] contextUIGuids = new object[] { };364 Commands2 commands = (Commands2)_applicationObject.Commands;365 try366 {367 findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_CodeWindow), -1);368 }369 catch370 {371 // command doesn't exist372 }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 window392 //代碼393 CommandBar codeWindowCommandBar = cmdBars["Code Window"];394 //Project395 //Solution Folder396 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 try408 {409 findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_Project), -1);410 }411 catch412 {413 // command doesn't exist414 }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 Folder433 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 try444 {445 findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_Solution), -1);446 }447 catch448 {449 // command doesn't exist450 }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 try479 {480 findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_MenuBar), -1);481 }482 catch483 {484 // command doesn't exist485 }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 //menubar502 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 try515 {516 findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_Files), -1);517 }518 catch519 {520 // command doesn't exist521 }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 //menubar538 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 /// <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 project20 /// </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代碼,可以參加此文章.
創建了外接程序后,必須先向 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外接程序的命令按鈕,如下圖:
代碼生成器(此處用的是yuvalsol的工程,我將其整合到插件中)可以根據用戶選擇的數據庫,選擇對應的表,然后生成表結構對應的C#類:
如果自己定義的插件想卸載怎么辦?可參見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中,卸載完成. 但是要完整去除必須手動刪除插件對應的項目文件(如果你再次調試,可能會再次進行注冊);
通過插件機制可以方便的定制VS IDE, 一般軟件公司都有自己的一套框架,其代碼也有一定的封裝,且各不相同,可以通過擴展VS,通過定制的代碼生成工具來快速生成符合本公司所需的代碼,從而從重復機械的勞動中解放出來(雖然完全自動生成的代碼不可能直接能用,但是人工在此基礎上進行調整,也提升了代碼的編寫效率,而且減少類似于拼寫/標點等人為的錯誤點等.
雖然我們不生產代碼,是代碼的搬運工,但是正確的打開方式是用代碼去幫我們搬運代碼!!!
新聞熱點
疑難解答