如何在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是当前插件实例,表示此外接程序的对象。
首先定义一些内部的对象,主要是自定义的命令,如下所示:
/// <summary>用于实现外接程序的对象。</summary>
/// <seealso class='IDTExtensibility2' />
public class Connect : IDTExtensibility2, IDTCommandTarget
{
#region 命令定义 除了FindInSolutionExplorer外,此处的命令不是根据功能来命令的,而是根据命令所出现的位置来命令的
private readonly string MY_COMMAND_FindInSolutionExplorer = "FindInSolutionExplorer";
private readonly string MY_COMMAND_Project = "cmdInProject";//在项目上
private readonly string MY_COMMAND_Solution = "cmdInSolution";//在解决方案上
private readonly string MY_COMMAND_MenuBar = "cmdInMenuBar";//在菜单栏上
private readonly string MY_COMMAND_CodeWindow = "cmdInCodeWindow";//代码窗口
private readonly string MY_COMMAND_Files = "cmdInFiles";
#endregion private Command findCommand = null;
private CommandBarButton findCommandBarButtonButton = null;
private AddInLogger logger = null; private DTE2 _applicationObject;
private EnvDTE.AddIn _addInInstance;
......
}
初始化插件UI的代码:
public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
{ _applicationObject = (DTE2)application;
_addInInstance = (AddIn)addInInst; if (connectMode == ext_ConnectMode.ext_cm_UISetup)
{
object[] contextGUIDS = new object[] { };
Commands2 commands = (Commands2)_applicationObject.Commands;
string toolsMenuName = "Tools"; //将此命令置于“工具”菜单上。
//查找 MenuBar 命令栏,该命令栏是容纳所有主菜单项的顶级命令栏:
Microsoft.VisualStudio.CommandBars.CommandBar menuBarCommandBar = ((Microsoft.VisualStudio.CommandBars.CommandBars)_applicationObject.CommandBars)["MenuBar"]; //在 MenuBar 命令栏上查找“工具”命令栏:
CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];
CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl; //如果希望添加多个由您的外接程序处理的命令,可以重复此 try/catch 块,
// 只需确保更新 QueryStatus/Exec 方法,使其包含新的命令名。
try
{
//将一个命令添加到 Commands 集合:
Command command = commands.AddNamedCommand2(_addInInstance, "MyVisualStudioAddin", "MyVS外接程序", "Executes the command for MyVisualStudioAddin", true, , ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton); //将对应于该命令的控件添加到“工具”菜单:
if ((command != null) && (toolsPopup != null))
{
command.AddControl(toolsPopup.CommandBar, );
}
}
catch (System.ArgumentException)
{
//如果出现此异常,原因很可能是由于具有该名称的命令
// 已存在。如果确实如此,则无需重新创建此命令,并且
// 可以放心忽略此异常。
} bool logtoOutputWindow = System.Diagnostics.Debugger.IsAttached;
logger = new AddInLogger((DTE)_applicationObject, "MyVisualStudioAddin", logtoOutputWindow);
logger.LogMessage(string.Format("OnConnection() called with connectMode: '{0}'", connectMode));
try
{
switch (connectMode)
{
case ext_ConnectMode.ext_cm_UISetup:
// We should never get here, this is temporary UI
AddAddInUI();
break; case ext_ConnectMode.ext_cm_Startup:
// The add-in was marked to load on startup
AddAddInUI();
break; case ext_ConnectMode.ext_cm_AfterStartup:
// The add-in was loaded by hand after startup using the Add-In Manager
// Initialize it in the same way that when is loaded on startup
AddAddInUI();
break;
}
}
catch (Exception ex)
{
logger.LogError(ex.ToString());
} }
}
/// <summary>
/// 设置插件UI
/// </summary>
private void AddAddInUI()
{
#region 获取CommandBars的名称
//CommandBars commandBars = (CommandBars)applicationObject.CommandBars;
//System.Text.StringBuilder sb = new System.Text.StringBuilder(); //foreach (CommandBar cbar in commandBars)
//{
// sb.AppendLine(cbar.Name);
//} //System.Windows.Forms. Clipboard.SetText(sb.ToString()); #region name
// MenuBar
//Standard
//Build
//Context Menus
//Data Design
//Formatting
//Style Application
//HTML Source Editing
//Class Designer Toolbar
//Text Editor
//Workflow
//Dialog Editor
//Image Editor
//Style Sheet
//Source Control
//Recorder
//Microsoft XML Editor
//Query Designer
//View Designer
//Database Diagram
//Table Designer
//Layout
//Help
//Debug Location
//Debug
//Report Formatting
//Report Borders
//Device
//Microsoft Office Excel 2007
//Microsoft Office Excel 2003
//Microsoft Office Word 2007
//Microsoft Office Word 2003
//Test Tools
//CrystalReportMain
//CrystalReportInsert
//ClearCase - Base
//ClearCase - UCM
//Error List
//Docked Window
//Menu Designer
//Properties Window
//Toolbox
//Task List
//Results List
//Stub Project
//No Commands Available
//Command Window
//AutoHidden Windows
//Expansion Manager
//Find Regular Expression Builder
//Replace Regular Expression Builder
//Wild Card Expression Builder
//Wild Card Expression Builder
//External Tools Arguments
//External Tools Directories
//Easy MDI Tool Window
//Easy MDI Document Window
//Easy MDI Dragging
//Open Drop Down
//Object Browser Objects Pane
//Object Browser Members Pane
//Object Browser Description Pane
//Find Symbol
//Drag and Drop
//Bookmark Window
//Error Correction
//EzMDI Files
//Ca&ll Browser
//Preview Changes
//Discover Service References
//Smart Tag
//Editor Context Menus
//Class View Context Menus
//Debugger Context Menus
//Project and Solution Context Menus
//Other Context Menus
//Sort By
//Show Columns
//Implement Interface
//Resolve
//Refactor
//Organize Usings
//Create Private Accessor
//Class View Multi-select Project references Items
//Class View Multi-select Project references members
//Class View Project
//Class View Item
//Class View Folder
//Class View Grouping Folder
//Class View Multi-select
//Class View Multi-select members
//Class View Member
//Class View Grouping Members
//Class View Project References Folder
//Class View Project Reference
//Class View Project Reference Item
//Class View Project Reference Member
//Project
//Solution Folder
//Cross Project Solution Project
//Cross Project Solution Item
//Cross Project Project Item
//Cross Project Multi Project
//Cross Project Multi Item
//Cross Project Multi Solution Folder
//Cross Project Multi Project/Folder
//Item
//Folder
//Reference Root
//Reference Item
//Web Reference Folder
//App Designer Folder
//Web Project Folder
//Web Folder
//Web Item
//Web SubWeb
//References
//Misc Files Project
//Solution
//Code Window
//XAML Editor
//Surface
//DataSourceContext
//DbTableContext
//DataTableContext
//RelationContext
//FunctionContext
//ColumnContext
//QueryContext
//DataAccessorContext
//Context
//Basic Context
//Context
//Context
//Context
//HTML Context
//Script Context
//ASPX Context
//ASAX Context
//ASPX Code Context
//ASAX Code Context
//ASPX VB Code Context
//ASAX VB Code Context
//ASMX Code Context
//ASMX VB Code Context
//Change &View
//Static Node
//Object Node
//Multiple Static Nodes
//Multiple Homogenous Object Nodes
//Multiple Heterogenous Object Nodes
//Multiple Heterogenous Nodes
//Add &New
//Selection
//Container
//TraySelection
//Document Outline
//Component Tray
//Propertysheet
//Configuration
//Project
//Multi-Select
//System Propertysheet
//Topic Menu
//Topic Source Menu
//Favorites Window Context Menu
//Data Sources
//Server Explorer
//Managed Resources Editor Context Menu
//Settings Designer
//My Extensibility
//Class Designer Context Menu
//Class Diagram Context Menu
//Class Details Context Menu
//Selection
//&Zoom
//Page Layout
//Designer Actions
//&Navigation Tools
//Resource View
//Resource Editors
//Resource Dialog Editors
//Binary Editor
//CSSDocOutline
//CSSSource
//Checkin Dialog Context Menu
//Pending Checkin Window Context Menu
//Standard TreeGrid context menu
//GetVersion Dialog Context Menu
//Check Out Dialog Context Menu
//Macro
//Module
//Project
//Root
//TocContext
//ResListContext
//Query Diagram Pane
//Query Diagram Table
//Query Diagram Table Column
//Query Diagram Join Line
//Query Diagram Multi-select
//Query Grid Pane
//Query SQL Pane
//Query Results Pane
//Database Designer
//Database Designer Table
//Database Designer Relationship
//Text Annotation
//Database Project
//DB Project Connection
//DB Project Folder
//Database References Folder
//Folders
//DB Project File
//Query
//Script
//Database Reference Node
//Files
//Multi-select
//PropertyBrowser
//Editor
//Script Outline
//DefaultContext
//ImageContext
//SelectionContext
//AnchorContext
//Step Into Specific
//Autos Window
//Breakpoint
//Load Symbols From
//Breakpoints Window
//Call Stack Window
//Thread Tip Window
//Data Tip Window
//Disassembly Window
//Locals Window
//Memory Window
//Modules Window
//Output Window
//Processes Window
//Registers Window
//Threads Window
//Watch Window
//Script Project
//Thread IP Marker
//Thread IP Markers
//Control
//Report
//Row/Column
//Cell
//Field Chooser
//Row/Column
//Chart
//Registry
//File System
//File System
//File Types
//User Interface
//Launch Conditions
//Custom Actions
//New
//Add
//Add Special Folder
//View
//Project Node
//A&dd
//Cab Project Node
//A&dd
//File nodes
//Dep. file nodes
//Assembly nodes
//Dep. assembly nodes
//MSM nodes
//Dep. MSM nodes
//Output nodes
//Simple file nodes
//Simple output nodes
//Dependency node
//Multiple selections
//Dep. Multiple selections
//View
//Editor
//ORDesigner Context Menu
//ORDesigner Context Menu
//ORDesigner Context Menu
//OTBObjCtxtMenu
//SIDE Left Pane Context Menu
//SIDE CertMgr Context Menu
//Registry
//File System
//File System
//New
//Add
//Add Special Folder
//View
//Project Node
//A&dd
//Cab Project Node
//A&dd
//File nodes
//Dep. file nodes
//Assembly nodes
//Dep. assembly nodes
//MSM nodes
//Dep. MSM nodes
//Output nodes
//Dependency node
//Multiple selections
//Dep. Multiple selections
//View
//AppNet Designer Context
//AppNet Project Node Context
//Exe Project
//Debug
//Test Results Context Menu
//Test List Editor Context Menu
//Test List Context Menu
//Test Run Context Menu
//View Context Menu
//Group
//Database
//Edit Text
//Formula Parameter
//Section
//Default
//Object Selection
//Insert to Report
//SchemaExplorer
//AddNewItem
//MicrosoftDataEntityDesign Context
//MicrosoftDataEntityDesign Context
//Find Checkouts
//Pending Solution Checkins
//Views Folder item context menu
//UCM Project item context menu
//View item context menu
//Solution item context menu
//Deliver
//Rebase
//ClearCase search Context Menus
//System #endregion
#endregion
//------------------------------Code Window------------------------------------------------------
object[] contextUIGuids = new object[] { };
Commands2 commands = (Commands2)_applicationObject.Commands;
try
{
findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_CodeWindow), -);
}
catch
{
// command doesn't exist
} if (findCommand == null)
{
findCommand = commands.AddNamedCommand2(
_addInInstance,
MY_COMMAND_CodeWindow,
MY_COMMAND_CodeWindow,
MY_COMMAND_CodeWindow,
false,
MyVisualStudioAddin.Properties.Resources._default,
ref contextUIGuids,
(int)(vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled));
} CommandBars cmdBars = (CommandBars)_applicationObject.CommandBars; if (findCommand != null)
{
// Add a button to the code window context window
//代码
CommandBar codeWindowCommandBar = cmdBars["Code Window"];
//Project
//Solution Folder
if (codeWindowCommandBar != null)
{
findCommandBarButtonButton = (CommandBarButton)findCommand.AddControl(
codeWindowCommandBar, codeWindowCommandBar.Controls.Count + );
findCommandBarButtonButton.Caption = "Code Window";
}
} //-------------------------------------project---------------------------------------------------------------
findCommand = null;
contextUIGuids = new object[] { };
try
{
findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_Project), -);
}
catch
{
// command doesn't exist
} if (findCommand == null)
{
findCommand = commands.AddNamedCommand2(
_addInInstance,
MY_COMMAND_Project,
MY_COMMAND_Project,
MY_COMMAND_Project,
false,
MyVisualStudioAddin.Properties.Resources.man,
ref contextUIGuids,
(int)(vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled));
}
if (findCommand != null)
{
//项目
CommandBar codeWindowCommandBar2 = cmdBars["Project"];
//Solution Folder
if (codeWindowCommandBar2 != null)
{
findCommandBarButtonButton = (CommandBarButton)findCommand.AddControl(
codeWindowCommandBar2, codeWindowCommandBar2.Controls.Count + );
findCommandBarButtonButton.Caption = "生成表结构类";
}
}
//-----------------------------------------解决方案---------------------------------------------------------
findCommand = null;
contextUIGuids = new object[] { };
try
{
findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_Solution), -);
}
catch
{
// command doesn't exist
} if (findCommand == null)
{
findCommand = commands.AddNamedCommand2(
_addInInstance,
MY_COMMAND_Solution,
MY_COMMAND_Solution,
MY_COMMAND_Solution,
false,
MyVisualStudioAddin.Properties.Resources.FindHS,
ref contextUIGuids,
(int)(vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled));
}
if (findCommand != null)
{
//解决方案
CommandBar codeWindowCommandBar3 = cmdBars["Solution"];
if (codeWindowCommandBar3 != null)
{
findCommandBarButtonButton = (CommandBarButton)findCommand.AddControl(
codeWindowCommandBar3, codeWindowCommandBar3.Controls.Count + );
findCommandBarButtonButton.Caption = "生成表结构类";
}
}
//-------------------------------------------MenuBar-------------------------------------------------------
findCommand = null;
contextUIGuids = new object[] { };
try
{
findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_MenuBar), -);
}
catch
{
// command doesn't exist
} if (findCommand == null)
{
findCommand = commands.AddNamedCommand2(
_addInInstance,
MY_COMMAND_MenuBar,
MY_COMMAND_MenuBar,
MY_COMMAND_MenuBar,
false,
MyVisualStudioAddin.Properties.Resources.man,
ref contextUIGuids,
(int)(vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled));
}
if (findCommand != null)
{
//menubar
CommandBar codeWindowCommandBar4 = cmdBars["MenuBar"];
if (codeWindowCommandBar4 != null)
{
findCommandBarButtonButton = (CommandBarButton)findCommand.AddControl(
codeWindowCommandBar4, codeWindowCommandBar4.Controls.Count + );
findCommandBarButtonButton.Caption = "JackWang";
} }
//--------------------------Files------------------------------
findCommand = null;
contextUIGuids = new object[] { };
try
{
findCommand = commands.Item(string.Format("{0}.{1}", _addInInstance.ProgID, MY_COMMAND_Files), -);
}
catch
{
// command doesn't exist
} if (findCommand == null)
{
findCommand = commands.AddNamedCommand2(
_addInInstance,
MY_COMMAND_Files,
MY_COMMAND_Files,
MY_COMMAND_Files,
false,
MyVisualStudioAddin.Properties.Resources.man,
ref contextUIGuids,
(int)(vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled));
}
if (findCommand != null)
{
//menubar
CommandBar codeWindowCommandBar4 = cmdBars["Item"];
if (codeWindowCommandBar4 != null)
{
findCommandBarButtonButton = (CommandBarButton)findCommand.AddControl(
codeWindowCommandBar4, codeWindowCommandBar4.Controls.Count + );
findCommandBarButtonButton.Caption = "生成表结构类";
} } }
public void QueryStatus(string commandName, vsCommandStatusTextWanted neededText, ref vsCommandStatus status, ref object commandText)
{
try
{
if (neededText == vsCommandStatusTextWanted.vsCommandStatusTextWantedNone)
{
if (commandName == "MyVisualStudioAddin.Connect.MyVisualStudioAddin")
{
status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
return;
} if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_FindInSolutionExplorer))
{
Solution solution = _applicationObject.Solution;
status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
return;
}
if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_CodeWindow))
{
Solution solution = _applicationObject.Solution;
status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
return;
}
if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_MenuBar))
{
Solution solution = _applicationObject.Solution;
status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
return;
}
if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_Project))
{
Solution solution = _applicationObject.Solution;
status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
return;
}
if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_Solution))
{
Solution solution = _applicationObject.Solution;
status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
return;
}
if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_Files))
{
Solution solution = _applicationObject.Solution;
status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
return;
}
}
}
catch (Exception ex)
{
logger.LogError(ex.ToString());
}
}
public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
{
try
{
handled = false;
if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
{
//命名空间.Connect.命名
if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_FindInSolutionExplorer))
{
FindCurrentActiveDocumentInSolutionExplorer();
handled = true;
return;
}
if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_CodeWindow))
{
string fullpath = this.GetActiveProjectFullPath();
if (fullpath != "")
{
POCOGenerator.ConnectionForm frm = new POCOGenerator.ConnectionForm(fullpath);
frm.Show();
}
handled = true;
return;
}
if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_MenuBar))
{
string fullpath = this.GetActiveProjectFullPath();
if (fullpath != "")
{
POCOGenerator.ConnectionForm frm = new POCOGenerator.ConnectionForm(fullpath);
frm.Show();
}
handled = true;
return;
}
if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_Project))
{
string fullpath = this.GetActiveProjectFullPath();
if (fullpath != "")
{
POCOGenerator.ConnectionForm frm = new POCOGenerator.ConnectionForm(fullpath);
frm.Show();
} handled = true;
return;
}
if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_Solution))
{
string fullpath = this.GetActiveProjectFullPath();
if (fullpath != "")
{
POCOGenerator.ConnectionForm frm = new POCOGenerator.ConnectionForm(fullpath);
frm.Show();
}
handled = true;
return;
}
if (commandName == string.Format("MyVisualStudioAddin.Connect.{0}", MY_COMMAND_Files))
{
string fullpath = this.GetActiveProjectFullPath();
if (fullpath != "")
{
POCOGenerator.ConnectionForm frm = new POCOGenerator.ConnectionForm(fullpath);
frm.Show();
}
handled = true;
return;
} if (commandName == "MyVisualStudioAddin.Connect.MyVisualStudioAddin")
{
string fullpath = this.GetActiveProjectFullPath();
if (fullpath != "")
{
POCOGenerator.ConnectionForm frm = new POCOGenerator.ConnectionForm(fullpath);
frm.Show();
}
handled = true;
return;
} }
}
catch (Exception ex)
{
logger.LogError(ex.ToString());
} }
View Exec Code
获取当前IDE激活项目的路径:
/// <summary>
/// Gets the Active project FullPath
/// </summary>
/// <returns></returns>
public string GetActiveProjectFullPath()
{
// Returns the name of the currently selected project in the solution.
Project proj = getActiveProject();
if (proj!=null)
{
string fullPath = proj.Properties.Item("FullPath").Value.ToString();
return fullPath;
// return proj.FullName;
}
return ""; }
/// <summary>
/// Gets the Active project
/// </summary>
/// <returns></returns>
public Project getActiveProject()
{
Array projects = (Array)_applicationObject.ActiveSolutionProjects;
if (projects != null && projects.Length > )
{
return projects.GetValue() as Project;
}
projects = (Array)_applicationObject.Solution.SolutionBuild.StartupProjects;
if (projects != null && projects.Length >= )
{
return projects.GetValue() as Project;
}
projects = (Array)_applicationObject.Solution.Projects;
if (projects != null && projects.Length > )
{
return projects.GetValue() as Project;
}
return null;
}
关于如何根据数据库结构生成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,通过定制的代码生成工具来快速生成符合本公司所需的代码,从而从重复机械的劳动中解放出来(虽然完全自动生成的代码不可能直接能用,但是人工在此基础上进行调整,也提升了代码的编写效率,而且减少类似于拼写/标点等人为的错误点等.
虽然我们不生产代码,是代码的搬运工,但是正确的打开方式是用代码去帮我们搬运代码!!!
如何在Visual Studio中开发自己的代码生成器插件的更多相关文章
- Visual Studio中开发
如何在Visual Studio中开发自己的代码生成器插件 Visual Studio是美国微软公司开发的一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具.代 ...
- 如何在 Visual Studio 中使用 Git 同步代码到 CodePlex
开源社区不管在国内还是国外都很火热,微软也曾因为没有开源而倍受指责,但是随着 .Net framework.ASP.Net MVC等框架的逐渐开源,也让大家看到了微软开源的步伐.CodePlex 则是 ...
- [转]如何在 Visual Studio 中使用 Git 同步代码到 CodePlex
本文转自:http://www.cnblogs.com/stg609/p/3673782.html 开源社区不管在国内还是国外都很火热,微软也曾因为没有开源而倍受指责,但是随着 .Net framew ...
- 如何在Visual Studio中选择C++和C#的编译器版本
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:如何在Visual Studio中选择C++和C#的编译器版本.
- 使用Xamarin在Visual Studio中开发Android应用
原文:使用Xamarin在Visual Studio中开发Android应用 本文使用的环境是Windows 8 Visual Studio 2012.2 1.下载Xamarin http://xam ...
- [译]如何在visual studio中调试Javascript
本文翻译youtube上的up主kudvenkat的javascript tutorial播放单 源地址在此: https://www.youtube.com/watch?v=PMsVM7rjupU& ...
- 在Visual Studio 中开发Office Add-in
作者:陈希章 发表于2017年7月13日 "Talk is cheap, show me the code",我们就用代码来说话吧.这一篇将给大家介绍如何开始Office Add- ...
- CMake结合Visual Studio中开发Qt应用程序注意事项
Qt工程管理 个人比较偏爱于使用CMake来管理C++工程,因为只要编写一个CMakeLists.txt文件,就可以在Windows和Mac上生成各自的IDE工程.在Windows上, CMake自然 ...
- 在Visual Studio中开发Matlab mex文件,生成mexw64/mexw32
csunking贡献,2015-9-22 1712 1. 概述 通过使用C/C++与Matlab混合编程,既可以享受到C代码快速执行的速度,又可以方便的使用Matlab众多的库函数和强大的绘图功能 ...
随机推荐
- C语言数组空间的初始化详解
数组空间的初始化就是为每一个标签地址赋值.按照标签逐一处理.如果我们需要为每一个内存赋值,假如有一个int a[100];我们就需要用下标为100个int类型的空间赋值.这样的工作量是非常大的,我们就 ...
- CSS3选择器的研究,案例
在上一篇CSS3选择器的研究中列出了几乎所有的CSS3选择器,和伪类选择器,当是并没有做案例的研究,本想在那篇文章里面写,但想想如果把案例都写在那篇文章里面,对于查找来说就不是很方便,所有另开一篇来讲 ...
- 数组的一个强大函数splice,[增,删,改]
// var a = [1,2,3]; // a.splice(0); // console.log(a); >>[] // a.splice(1); // console.log(a); ...
- 了解canvas
目录 [1]HTML属性[2]CSS样式 [3]API 坐标 填充和描边 阴影 绘制矩形 绘制路径 绘制文本 绘制图像 使用图像 变换 合成 [4]DEMO 前面的话 canvas元素是HTML5最受 ...
- Oracle 11gR2静默安装 & 命令行安装
静默安装 经常搭建Oracle测试环境,有时候觉得OUI(即图形界面)方式甚是繁琐,你得一步一步进行确认,所幸,Oracle支持静默安装.在我看来,它主要有两方面的好处:一.极大地提升了效率,尤其是批 ...
- Bootstrap+angularjs+MVC3+分页技术+角色权限验证系统
1.Bootstrap使用教程 相关教程: http://www.bootcss.com/components.html 页面使用代码: <script src="@Url.Conte ...
- 实现iOS图片等资源文件的热更新化(一): 从Images.xcassets导出合适的图片
本文会基于一个已有的脚本工具自动导出所有的图片;最终给出的是一个从 Images.xcassets 到基于文件夹的精简 合适 的图片资源集的完整过程.难点在于从完整图片集到精简图片集,肯定是基于一个定 ...
- 利用grunt-contrib-connect和grunt-connect-proxy搭建前后端分离的开发环境
前后端分离这个词一点都不新鲜,完全的前后端分离在岗位协作方面,前端不写任何后台,后台不写任何页面,双方通过接口传递数据完成软件的各个功能实现.此种情况下,前后端的项目都独立开发和独立部署,在开发期间有 ...
- 歌词文件解析(一):LRC格式文件的解析
LRC是英文lyric(歌词)的缩写,被用做歌词文件的扩展名.以lrc为扩展名的歌词文件可以在各类数码播放器中同步显示.LRC 歌词是一种包含着“*:*”形式的“标签(tag)”的基于纯文本的歌词专用 ...
- 使用 TOP 限制更新的数据
可以使用 TOP 子句来限制 UPDATE 语句中修改的行数.当 TOP (n) 子句与 UPDATE 一起使用时,将针对随机选择的 n 行执行删除操作.例如,假设您要为一位高级销售人员减轻销售负担, ...