如何在VisualStudio中开发自己的代码生成器插件
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的项目(根据向导进行设置,这里不赘述),界面如下:
[flash=500,400]http://s1.knowsky.com/20160211/bfv4t32xluc55.jpg[/flash]
3 核心 Connect 类插件入口就是Connect 类,先看一下Connect的类图:
[flash=500,400]http://s1.knowsky.com/20160211/fpujpvuz4zf55.jpg[/flash]
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' />3publicclassConnect : IDTExtensibility2, IDTCommandTarget4{5#region命令定义 除了FindInSolutionExplorer外,此处的命令不是根据功能来命令的,而是根据命令所出现的位置来命令的6PRivatereadonlystringMY_COMMAND_FindInSolutionExplorer ="FindInSolutionExplorer";7privatereadonlystringMY_COMMAND_Project ="cmdInProject";//在项目上8privatereadonlystringMY_COMMAND_Solution ="cmdInSolution";//在解决方案上9privatereadonlystringMY_COMMAND_MenuBar ="cmdInMenuBar";//在菜单栏上10privatereadonlystringMY_COMMAND_CodeWindow ="cmdInCodeWindow";//代码窗口11privatereadonlystringMY_COMMAND_Files ="cmdInFiles";12#endregion1314privateCommand findCommand =null;15privateCommandBarButton findCommandBarButtonButton =null;16privateAddInLogger logger =null;1718privateDTE2 _applicationObject;19privateEnvDTE.AddIn _addInInstance;20......21}
初始化插件UI的代码:
[flash=500,400]http://s1.knowsky.com/20160211/h2o5rokr4b455.gif[/flash][flash=500,400]http://s1.knowsky.com/20160211/shrxykrnbd255.gif[/flash]1publicvoidOnConnection(objectapplication, ext_ConnectMode connectMode,objectaddInInst,refArray custom)2{34_applicationObject =(DTE2)application;5_addInInstance =(AddIn)addInInst;678if(connectMode ==ext_ConnectMode.ext_cm_UISetup)9{10object[] contextGUIDS =newobject[] { };11Commands2 commands =(Commands2)_applicationObject.Commands;12stringtoolsMenuName ="Tools";1314//将此命令置于“工具”菜单上。15//查找 MenuBar 命令栏,该命令栏是容纳所有主菜单项的顶级命令栏:16Microsoft.VisualStudio.CommandBars.CommandBar menuBarCommandBar = ((Microsoft.VisualStudio.CommandBars.CommandBars)_applicationObject.CommandBars)["MenuBar"];1718//在 MenuBar 命令栏上查找“工具”命令栏:19CommandBarControl toolsControl =menuBarCommandBar.Controls[toolsMenuName];20CommandBarPopup toolsPopup =(CommandBarPopup)toolsControl;2122//如果希望添加多个由您的外接程序处理的命令,可以重复此 try/catch 块,23//只需确保更新 QueryStatus/Exec 方法,使其包含新的命令名。24try25{26//将一个命令添加到 Commands 集合:27Command command = commands.AddNamedCommand2(_addInInstance,"MyVisualStudioAddin","MyVS外接程序","Executes the command for MyVisualStudioAddin",true,59,refcontextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton);2829//将对应于该命令的控件添加到“工具”菜单:30if((command !=null) && (toolsPopup !=null))31{32command.AddControl(toolsPopup.CommandBar,1);33}34}35catch(System.ArgumentException)36{37//如果出现此异常,原因很可能是由于具有该名称的命令38//已存在。如果确实如此,则无需重新创建此命令,并且39//可以放心忽略此异常。40}41424344boollogtoOutputWindow =System.Diagnostics.Debugger.IsAttached;45logger =newAddInLogger((DTE)_applicationObject,"MyVisualStudioAddin", logtoOutputWindow);46logger.LogMessage(string.Format("OnConnection() called with connectMode: '{0}'", connectMode));47try48{49switch(connectMode)50{51caseext_ConnectMode.ext_cm_UISetup:52//We should never get here, this is temporary UI53AddAddInUI();54
break;5556caseext_ConnectMode.ext_cm_Startup:57//The add-in was marked to load on startup58AddAddInUI();59
break;6061caseext_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 startup64AddAddInUI();65
break;66}67}68catch(Exception ex)69{70logger.LogError(ex.ToString());71}727374}75}
View Code
[flash=500,400]http://s1.knowsky.com/20160211/h2o5rokr4b455.gif[/flash][flash=500,400]http://s1.knowsky.com/20160211/shrxykrnbd255.gif[/flash]1///<summary>2///设置插件UI3///</summary>4privatevoidAddAddInUI()5{6#region获取CommandBars的名称7//CommandBars commandBars = (CommandBars)applicationObject.CommandBars;8//System.Text.StringBuilder sb = new System.Text.StringBuilder();910//foreach (CommandBar cbar in commandBars)11//{12//sb.AppendLine(cbar.Name);13//}1415//System.Windows.Forms. Clipboard.SetText(sb.ToString());1617#regionname18//MenuBar19//Standard20//Build21//Context Menus22//Data Design23//Formatting24//Style Application25//HTML Source Editing26//Class Designer Toolbar27//Text Editor28//Workflow29//Dialog Editor30//Image Editor31//Style Sheet32//Source Control33//Recorder34//MicrosoftxmlEditor35//Query Designer36//View Designer37//Database Diagram38//Table Designer39//Layout40//Help41//Debug Location42//Debug43//Report Formatting44//Report Borders45//Device46//Microsoft OfficeExcel200747//Microsoft Office Excel 200348//Microsoft OfficeWord200749//Microsoft Office Word 200350//Test Tools51//CrystalReportMain52//CrystalReportInsert53//ClearCase - Base54//ClearCase - UCM55//Error List56//Docked Window57//Menu Designer58//Properties Window59//Toolbox60//Task List61//Results List62//Stub Project63//No Commands Available64//Command Window65//AutoHidden Windows66//Expansion Manager67//Find Regular Expression Builder68//Replace Regular Expression Builder69//Wild Card Expression Builder70//Wild Card Expression Builder71//External Tools Arguments72//External Tools Directories73//Easy MDI Tool Window74//Easy MDI Document Window75//Easy MDI Dragging76//Open Drop Down77//Object Browser Objects Pane78//Object Browser Members Pane79//Object Browser Description Pane80//Find Symbol81//Drag and Drop82//Bookmark Window83//Error Correction84//EzMDI Files85//Ca&ll Browser86//Preview Changes87//Discover Service References88//Smart Tag89//Editor Context Menus90//Class View Context Menus91//Debugger Context Menus92//Project and Solution Context Menus93//Other Context Menus94//Sort By95//Show Columns96//Implement Interface97//Resolve98//Refactor99//Organize Usings100//Create Privateaccessor101//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//System359360#endregion361#endregion362//------------------------------Code Window------------------------------------------------------363object[] contextUIGuids =newobject[] { };364Commands2 commands =(Commands2)_applicationObject.Commands;365try366{367findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_CodeWindow), -1);368}369catch370{371//command doesn't exist372}373374if(findCommand ==null)375{376findCommand =commands.AddNamedCommand2(377_addInInstance,378MY_COMMAND_CodeWindow,379MY_COMMAND_CodeWindow,380MY_COMMAND_CodeWindow,381false,382MyVisualStudioAddin.Properties.Resources._default,383refcontextUIGuids,384(int)(vsCommandStatus.vsCommandStatusSupported |vsCommandStatus.vsCommandStatusEnabled));385}386387CommandBars cmdBars =(CommandBars)_applicationObject.CommandBars;388389if(findCommand !=null)390{391//Add a button to the code window context window392//代码393CommandBar codeWindowCommandBar = cmdBars["Code Window"];394//Project395//Solution Folder396if(codeWindowCommandBar !=null)397{398findCommandBarButtonButton =(CommandBarButton)findCommand.AddControl(399codeWindowCommandBar, codeWindowCommandBar.Controls.Count +1);400findCommandBarButtonButton.Caption ="Code Window";401}402}403404//-------------------------------------project---------------------------------------------------------------405findCommand =null;406contextUIGuids =newobject[] { };407try408{409findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_Project), -1);410}411catch412{413//command doesn't exist414}415416if(findCommand ==null)417{418findCommand =commands.AddNamedCommand2(419_addInInstance,420MY_COMMAND_Project,421MY_COMMAND_Project,422MY_COMMAND_Project,423false,424MyVisualStudioAddin.Properties.Resources.man,425refcontextUIGuids,426(int)(vsCommandStatus.vsCommandStatusSupported |vsCommandStatus.vsCommandStatusEnabled));427}428if(findCommand !=null)429{430//项目431CommandBar codeWindowCommandBar2 = cmdBars["Project"];432//Solution Folder433if(codeWindowCommandBar2 !=null)434{435findCommandBarButtonButton =(CommandBarButton)findCommand.AddControl(436codeWindowCommandBar2, codeWindowCommandBar2.Controls.Count +1);437findCommandBarButtonButton.Caption ="生成表结构类";438}439}440//-----------------------------------------解决方案---------------------------------------------------------441findCommand =null;442contextUIGuids =newobject[] { };443try444{445findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_Solution), -1);446}447catch448{449//command doesn't exist450}451452if(findCommand ==null)453{454findCommand =commands.AddNamedCommand2(455_addInInstance,456MY_COMMAND_Solution,457MY_COMMAND_Solution,458MY_COMMAND_Solution,459false,460MyVisualStudioAddin.Properties.Resources.FindHS,461refcontextUIGuids,462(int)(vsCommandStatus.vsCommandStatusSupported |vsCommandStatus.vsCommandStatusEnabled));463}464if(findCommand !=null)465{466//解决方案467CommandBar codeWindowCommandBar3 = cmdBars["Solution"];468if(codeWindowCommandBar3 !=null)469{470findCommandBarButtonButton =(CommandBarButton)findCommand.AddControl(471codeWindowCommandBar3, codeWindowCommandBar3.Controls.Count +1);472findCommandBarButtonButton.Caption ="生成表结构类";473}474}475//-------------------------------------------MenuBar-------------------------------------------------------476findCommand =null;477contextUIGuids =newobject[] { };478try479{480findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_MenuBar), -1);481}482catch483{484//command doesn't exist485}486487if(findCommand ==null)488{489findCommand =commands.AddNamedCommand2(490_addInInstance,491MY_COMMAND_MenuBar,492MY_COMMAND_MenuBar,493MY_COMMAND_MenuBar,494false,495MyVisualStudioAddin.Properties.Resources.man,496refcontextUIGuids,497(int)(vsCommandStatus.vsCommandStatusSupported |vsCommandStatus.vsCommandStatusEnabled));498}499if(findCommand !=null)500{501//menubar502CommandBar codeWindowCommandBar4 = cmdBars["MenuBar"];503if(codeWindowCommandBar4 !=null)504{505findCommandBarButtonButton =(CommandBarButton)findCommand.AddControl(506codeWindowCommandBar4, codeWindowCommandBar4.Controls.Count +1);507findCommandBarButtonButton.Caption ="JackWang";508}509510}511//--------------------------Files------------------------------512findCommand =null;513contextUIGuids =newobject[] { };514try515{516findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_Files), -1);517}518catch519{520//command doesn't exist521}522523if(findCommand ==null)524{525findCommand =commands.AddNamedCommand2(526_addInInstance,527MY_COMMAND_Files,528MY_COMMAND_Files,529MY_COMMAND_Files,530false,531MyVisualStudioAddin.Properties.Resources.man,532refcontextUIGuids,533(int)(vsCommandStatus.vsCommandStatusSupported |vsCommandStatus.vsCommandStatusEnabled));534}535if(findCommand !=null)536{537//menubar538CommandBar codeWindowCommandBar4 = cmdBars["Item"];539if(codeWindowCommandBar4 !=null)540{541findCommandBarButtonButton =(CommandBarButton)findCommand.AddControl(542codeWindowCommandBar4, codeWindowCommandBar4.Controls.Count +1);543findCommandBarButtonButton.Caption ="生成表结构类";544}545546}547548549550}
View Code
[flash=500,400]http://s1.knowsky.com/20160211/h2o5rokr4b455.gif[/flash][flash=500,400]http://s1.knowsky.com/20160211/shrxykrnbd255.gif[/flash]1publicvoidQueryStatus(stringcommandName, vsCommandStatusTextWanted neededText,refvsCommandStatus status,refobjectcommandText)2{3try4{5if(neededText ==vsCommandStatusTextWanted.vsCommandStatusTextWantedNone)6{7if(commandName =="MyVisualStudioAddin.Connect.MyVisualStudioAddin")8{9status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported |vsCommandStatus.vsCommandStatusEnabled;10return;11}1213if(commandName ==string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_FindInSolutionExplorer))14{15Solution solution =_applicationObject.Solution;16status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported |vsCommandStatus.vsCommandStatusEnabled;17return;18}19if(commandName ==string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_CodeWindow))20{21Solution solution =_applicationObject.Solution;22status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported |vsCommandStatus.vsCommandStatusEnabled;23return;24}25if(commandName ==string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_MenuBar))26{27Solution solution =_applicationObject.Solution;28status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported |vsCommandStatus.vsCommandStatusEnabled;29return;30}31if(commandName ==string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_Project))32{33Solution solution =_applicationObject.Solution;34status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported |vsCommandStatus.vsCommandStatusEnabled;35return;36}37if(commandName ==string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_Solution))38{39Solution solution =_applicationObject.Solution;40status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported |vsCommandStatus.vsCommandStatusEnabled;41return;42}43if(commandName ==string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_Files))44{45Solution solution =_applicationObject.Solution;46status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported |vsCommandStatus.vsCommandStatusEnabled;47return;48}49}50}51catch(Exception ex)52{53logger.LogError(ex.ToString());54}55}
View Code
[flash=500,400]http://s1.knowsky.com/20160211/h2o5rokr4b455.gif[/flash][flash=500,400]http://s1.knowsky.com/20160211/shrxykrnbd255.gif[/flash]1publicvoidExec(stringcommandName, vsCommandExecOption executeOption,refobjectvarIn,refobjectvarOut,refboolhandled)2{3try4{5handled =false;6if(executeOption ==vsCommandExecOption.vsCommandExecOptionDoDefault)7{8//命名空间.Connect.命名9if(commandName ==string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_FindInSolutionExplorer))10{11FindCurrentActiveDocumentInSolutionExplorer();12handled =true;13return;14}15if(commandName ==string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_CodeWindow))16{17stringfullpath =this.GetActiveProjectFullPath();18if(fullpath !="")19{20POCOGenerator.ConnectionForm frm =newPOCOGenerator.ConnectionForm(fullpath);21frm.Show();22}23handled =true;24return;25}26if(commandName ==string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_MenuBar))27{28stringfullpath =this.GetActiveProjectFullPath();29if(fullpath !="")30{31POCOGenerator.ConnectionForm frm =newPOCOGenerator.ConnectionForm(fullpath);32frm.Show();33}34handled =true;35return;36}37if(commandName ==string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_Project))38{39stringfullpath =this.GetActiveProjectFullPath();40if(fullpath !="")41{42POCOGenerator.ConnectionForm frm =newPOCOGenerator.ConnectionForm(fullpath);43frm.Show();44}4546handled =true;47return;48}49if(commandName ==string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_Solution))50{51stringfullpath =this.GetActiveProjectFullPath();52if(fullpath !="")53{54POCOGenerator.ConnectionForm frm =newPOCOGenerator.ConnectionForm(fullpath);55frm.Show();56}57handled =true;58return;59}60if(commandName ==string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_Files))61{62stringfullpath =this.GetActiveProjectFullPath();63if(fullpath !="")64{65POCOGenerator.ConnectionForm frm =newPOCOGenerator.ConnectionForm(fullpath);66frm.Show();67}68handled =true;69return;70}7172if(commandName =="MyVisualStudioAddin.Connect.MyVisualStudioAddin")73{74stringfullpath =this.GetActiveProjectFullPath();75if(fullpath !="")76{77POCOGenerator.ConnectionForm frm =newPOCOGenerator.ConnectionForm(fullpath);78frm.Show();79}80handled =true;81return;82}838485}86}87catch(Exception ex)88{89logger.LogError(ex.ToString());90}9192}
View Exec Code
获取当前IDE激活项目的路径:
1///<summary>2///Gets the Active project FullPath3///</summary>4///<returns></returns>5publicstringGetActiveProjectFullPath()6{7//Returns the name of the currently selected project in the solution.8Project proj =getActiveProject();9if(proj!=null)10{11stringfullPath = proj.Properties.Item("FullPath").Value.ToString();12returnfullPath;13//return proj.FullName;14}15return"";1617}18///<summary>19///Gets the Active project20///</summary>21///<returns></returns>22publicProject getActiveProject()23{24Array projects =(Array)_applicationObject.ActiveSolutionProjects;25if(projects !=null&& projects.Length >0)26{27returnprojects.GetValue(0)asProject;28}29projects =(Array)_applicationObject.Solution.SolutionBuild.StartupProjects;30if(projects !=null&& projects.Length >=1)31{32returnprojects.GetValue(0)asProject;33}34projects =(Array)_applicationObject.Solution.Projects;35if(projects !=null&& projects.Length >0)36{37returnprojects.GetValue(0)asProject;38}39returnnull;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文件下:
[flash=500,400]http://s1.knowsky.com/20160211/qfgwwfsck3z56.jpg[/flash]
如果发布没有错误,那么重新启动Visual Studio2012后,在项目文件上右击弹出菜单,可以看到下面的界面:
[flash=500,400]http://s1.knowsky.com/20160211/2pxxfzfqtt256.jpg[/flash]
同时在菜单栏创建了一个JackWang的命令按钮和工具菜单下还添加了一个MyVS外接程序的命令按钮,如下图:
[flash=500,400]http://s1.knowsky.com/20160211/ombklxynwzd56.jpg[/flash]
5 代码生成器代码生成器(此处用的是yuvalsol的工程,我将其整合到插件中)可以根据用户选择的数据库,选择对应的表,然后生成表结构对应的C#类:
[flash=500,400]http://s1.knowsky.com/20160211/ccuhbiekd4d56.jpg[/flash]
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中,卸载完成. 但是要完整去除必须手动删除插件对应的项目文件(如果你再次调试,可能会再次进行注册);
[flash=500,400]http://s1.knowsky.com/20160211/s3xwkn22bd457.jpg[/flash]
7 总结通过插件机制可以方便的定制VS IDE, 一般软件公司都有自己的一套框架,其代码也有一定的封装,且各不相同,可以通过扩展VS,通过定制的代码生成工具来快速生成符合本公司所需的代码,从而从重复机械的劳动中解放出来(虽然完全自动生成的代码不可能直接能用,但是人工在此基础上进行调整,也提升了代码的编写效率,而且减少类似于拼写/标点等人为的错误点等.
虽然我们不生产代码,是代码的搬运工,但是正确的打开方式是用代码去帮我们搬运代码!!!
[flash=500,400]http://s1.knowsky.com/20160211/nekrfsi5tfu57.gif[/flash]