`
pcajax
  • 浏览: 2103432 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Visual Studio 插件的开发

 
阅读更多

Visual Studio 插件的开发

起因

在做项目的时候,经常需要根据表结构create一些实体类,写多了,实在是觉得无趣,于是就琢磨着做个代码生成工具。当然现在有很多现成的,拿来用就好,可是总想自己弄个出来玩玩,一来是当初用DataSet,VS可以根据一个xsd文件生成那么多代码,可以拖拖拽拽就搞定,一直没闹明白是怎么做的,不甘心,总想弄明白,二来,公司里,数据库的脚本大多是根据一个xml配置文件生成的,这样,我拿到这个xml生成代码也是挺方便的。

学习

有了这个想法,可完全没头绪该怎么开发VS add-in, 无奈,只能仰仗Google大神了,“VS 插件”, “自动代码生成 vs site:cnblogs.com” … 等等,一顿狂搜,了解到了相关的技术有:VS Add-in, CodeDom, T4, Template, Visual Designer, Domain-Specific Languages, Custom tools, etc.

VS Add-in: 可以使用任何.Net语言开发VS的插件,可以操作开发环境中的任何元素:解决方案,项目,文件,菜单,Solution Explorer, Output window…

CodeDom: 代码文档对象模型。类似Xml的Dom操作,CodeDom将代码转换成一种数据结构,通过操作这种数据结构可以实现生成代码,修改代码,动态编译等等各种功能。

T4: Text Templating Transformation Toolkit, 通过模板加代码的方式产生代码,可以想象下aspx页面,里面有html代码,也有.Net代码,通过转换,最后呈现出html页面。

Template: 模板,在添加新项的时候,在对话框中的那些就是模板。

Visual Designer: 像类型化DataSet,它有一个可视化的编辑界面,通过拖拽,点几下鼠标等等操作就可以设计出我们想要的DataSet类型。

Domain-Specific Languages: 特定领域模型语言,通过它,我们可以设计出Visual Designer。

Custom Tools: 自定义工具,通过一个文件生成另一个文件。

实践

CodeDom太复杂,用来生成代码如果杀鸡用牛刀,Visual Designer, Domain-Specific Languages,嗯,也用不到,暂时我不需要做个可视化的界面去设计我的代码,等我哪天要实现个类似类型化DataSet那样的插件的时候再考虑吧。去掉那些复杂的东西,我现在要用到的技术有:VS Add-in,用来实现VS的插件,使代码生成工具集成进VS;T4, 用来产生代码; Template,定义一个模板。

先说T4,看个简单的列子:

首先创建一个项目,然后添加新项,选择文本模板

image

文件里包含如下代码

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".txt" #>

在文本模板中,<#@ #>中是指令,定义了模板的一些行为,如第二行,output extension=”.txt”,意思是说,该模板最后转换生成的文件的后缀是.txt的。当然,我需要的代码文件,所以将其改为.cs即可。将文本修改成下面这个样子:

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
using System;

namespace T4
{
    public class T4Test
    {
    }
}

保存后,可以看到Solution Explorer里面多了一个.cs文件

image

打开cs文件,可以看到里面包含如下代码,跟我在模板文件里的内容一样。

using System;

namespace T4
{
    public class T4Test
    {
    }
}

关于T4的语法,cnBlogs里有太多解释,这里就不更进一步的描述了。

可是,这样一个模板文件产生的代码是固定的,而我需要的是输入一段xml,根据xml来生成相应的代码文件。要使模板文件知道xml里的内容,则需要将其内容作为参数传递到模板里,这个时候就需要用到参数指令:

<#@ parameter type="" name="" #>

然后再将之前的模板修改为:

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#@ parameter type="System.String" name="className" #>
using System;

namespace T4
{
    public class <#= className #>
    {
    }
}

如果这个时候,点击保存,VS会提示你转换失败,因为输入的参数为空。这个时候,需要修改模板文件的属性,在自定义工具里,我们可以看到显示的是TextTemplatingFileGenerator,它负责将模板文件转换成目标文件。但是在这里,我需要的是将模板转换成代码生成类,将该属性修改为:TextTemplatingFilePreprocessor。这个时候再保存,就会发现原来的cs文件里的内容变成了一段长的代码:

namespace Test
{
    using System;
   
   
    #line 1 "E:\My Files\Documents\Visual Studio 2010\Projects\MStarGATDataEntityGenerator\NUTest.GAT.Common\TextTemplate1.tt"
    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "10.0.0.0")]
    public partial class TextTemplate1 : TextTemplate1Base
    {

… …

记得原来用VS2003的时候,还没有T4技术,那个时候也写了一个代码生成工具,那个幸苦啊,一行行的WriteLine,又要控制输出代码的缩进,长长的一大段代码。现在TextTemplatingFilePreprocessor工具将模板自动的生成了那个类,工作强度上轻松多了。在这个TextTemplate1类里有个TransformText的方法,调用它,就会根据模板输出代码。不过现在还不能直接去调用,否则还是会出现跟使用TextTemplatingFileGenerator工具时一样的错误。因为,我们还是没有设置className变量的值。可是找遍整个TextTemplate1类,既没有在构造函数里发现参数可以设置,也没发现公共属性,也没方法,只有一个私有的_classNameField变量。好在生成的TextTemplate1类是partial的,我们可以自己定义一个属性去设置className,然后再调用TransformText方法。比如设置className为“Table”,我们将得到代码:

using System;

namespace T4
{
    public class Table
    {
    }
}

好了,到此,关于T4要用到的知识就这些了。

下面就是VS Add-in了。前面说了,我想当在VS里添加了一个新文件,然后将一段xml复制到文件里,然后保存,最后就能得到代码文件。前面T4已经可以帮助我实现生成代码文件,现在我需要的是可以让我在保存文件的时候将文件的内容传递给TextTemplate1类,然后调用TransformText方法,然后将得到的代码内容保存到一个cs文件中,并添加到项目里。而这些工作就得依靠VS Add-in来帮我实现了。

首先,我们需要添加一个VS Add-in的项目

image

找到Connect.cs文件,在OnConnection方法中,添加以下代码

DocumentEvents docMasterEvents = this.application.Events.get_DocumentEvents(null);
docMasterEvents.DocumentSaved += new _dispDocumentEvents_DocumentSavedEventHandler(
    docMasterEvents_DocumentSaved);

以及方法

void docMasterEvents_DocumentSaved(Document Document)
{
    if (Document == null) return;
    if(!Document.Name.ToLower().EndsWith(“.xml”)) return;

    TextTemplate1 gen = new TextTemplate1();

    gen.className = “Table”;

    string code = gen.TransformText();

    // todo: 将代码写入到文件里,并添加到项目中
}

在上面的DocumentSaved方法里,如果发现文件后缀是xml的,就去调用模板。这里有个问题,那就是,会对所有的xml都去调用。可是在一个项目里总会有些其他的xml文件,这些文件是不需要转换的。当然可以对文件内容进行判断,再决定要不要调用模板,不过更简单的方法是用一个特殊的文件名,而不是用.xml。比如在我的项目里,我使用.msgatde作为文件名后缀。讲到这里,又该介绍下模板了,这里的模板是指添加新项时,那些可选择的项目。

为什么要讲模板呢,本来实现这个代码自动生成的工具就是图个方便,可如果每次都要自己将新建的xml文件的后缀改成我自己定义的那个后缀,多麻烦,说不定还很容易写错。所有为了更一步简化操作,我打算定义一个模板,这样在添加新项的时候,就自动生成一个.msgatde后缀的文件。

一个模板里,一般会至少包含3个文件:

image

第一个,图标文件,在对话框里显示用的。

第二个,模板文件,添加新项后,VS会根据这个文件产生新的文件添加到项目中。

第三个,模板描述文件。

现在来看下第三个文件的内容:

image

其中ProjectItem那一段即定义了模板的行为:通过模板里的DataEntity.msgatde文件产生目标文件$fileinputname$.msgatde。

在这些文件编辑好后,需要将其打包成一个zip文件,并将其放置到$my documents$\Visual Studio 2010\Templates\ItemTemplates\Visual C#目录下。现在在选择添加新项,即可看到我们定义的模板了。

image

ok,讲完了怎么定义一个模板,现在该接着讲VS Add-in了。在前面的DocumentSaved方法里还没有实现如何将生成的代码添加到项目里,现在接着说。

首先,需要将得到的代码保存到文件里,这里就有一个问题了,如何知道路径呢?在DocumentSaved方法中,有一个Document的参数,这个就是表示了当前的文档,Document有个属性ProjectItem,通过该属性可以获取到当前文件的路径:

string fullname = Document.ProjectItem.Properties.Item(“FullPath”).Value.ToString();

知道了路径,就容易多啦:

string codeFile = fullname.Repleace(“.msgatde”, “.cs”);

using(StreamWriter sw = new StreamWriter(codeFile))

{

    sw.Write(codeString);

}

现在文件是有了,该把它加到项目里了,很简单:

Document.ProjectItem.ProjectItems.AddFromFile(codeFile);

说到这个方法,要顺便说一句。都知道当我们添加了一个.aspx文件后,会自动产生一个.aspx.cs的文件,并且这个文件会存在于.aspx文件下,这是个很酷的特性,之前在搜索如何实现的时候,网上给出了大致有3种方法,如修改preject file的内容,添加dependupon元素,或者修改注册表等方法,其实不用那么麻烦,通过上面的方法,.cs文件自动被添加到.msgatde文件下面了,效果如下:

image

最后讲下部署插件,在插件的项目里,有个{prjoectname}.AddIn文件,将其copy到\Documents\Visual Studio 2010\Addins目录下,然后将其用文本编辑软件打开:

image

其中第十行是说明该插件的dll文件所在的路径,将其修改为正确的路径。当然,你也可以将文件也复制到该目录下。

 

ok,目前关于如何创建一个代码生成插件的部分就讲完了。这里只是记录了我在学习如何创建这个插件过程中遇到的难点,很多细节部分并没有写下来,还有很多东西需要完善,比如每次生成代码,可以把生成的结果输出到output window,如果出错了,也把错误的原因output出来。

private void OutputToOPW(string format, params object[] objs)
{
    OutputWindow ow = this.applicationObject.ToolWindows.OutputWindow; // applicationObject 是 一个DTE2对象
    OutputWindowPane owp = null;
    try
    {
        owp = ow.OutputWindowPanes.Item("MyAddin");
    }
    catch
    {
        owp = ow.OutputWindowPanes.Add("MyAddin");
    }
    owp.Activate();
    owp.OutputString(string.Format(format, objs));
}

最后,推荐一本书:《Practical.Code.Generation.in.NET》。多亏了这本书,才解决了我之前的很多困扰。

分享到:
评论

相关推荐

    Visual Studio 2022支持Php开发插件

    Visual Studio 2022支持Php开发插件

    Visual Studio 2022扩展开发入门1

    Visual Studio 2022扩展开发入门课前准备(1)认识VS扩展&lt;Grid&gt; &lt;Button Width="85" Background="Azure

    Visual Studio开发Excel插件例子

    该文档主要是一个例子,介绍如何使用VS的OFFICE开发套件来开发一个EXCEL的插件,内容简单,但明了

    在Visual Studio中创建WPS外接程序插件

    如何在Visual Studio中如何创建插件、在WPS中显示插件的方法,如何导出PIA、DLL强签名、打包安装文件夹的方法。需要注意的是,开发WPS插件方法不止一种,我分享的开发流程仅供大家参考

    Visual Studio 扩展插件v6.2

    基于Microsoft Visual Studio 2008环境(具体项目类型为“其他项目类型”→“扩展性”→“Visual Studio 外接程序”),用C#语言开发实现的Visual Studio扩展插件,对.NET项目开发很有用,可以批量执行任务,包括...

    VisualStudio实用插件(主题+实用工具)

    无论你是经验丰富的开发者,还是刚开始工作的新手,你都会想让自己的开发工作尽可能轻松一点。正确的工具使用则可以帮助你实现这个目标。

    Visual Studio Office插件开发向导

    OfficeAddin,Visual Studio Office插件开发向导,用于开发Office的插件的创建工程向导!

    Visual Studio快速开发插件

    实现Visual Studio快速开发的实用插件

    Visual Studio svn插件

    TortoiseSVN版本和AnkhSvn版本不一致,即使两者都安装了, Visual Studio开发环境中svn插件功能仍然不能正常使用。 此资源提供了配套的TortoiseSVN和AnkhSvn, 安装后,svn可正常使用

    Visual Studio的PHP工具 for visual studio 2017 最新版

    一个Visual Studio的PHP工具插件,能够把Visual Studio转变成一个强大的PHP IDE开发环境。

    用Visual Studio 2005 开发VB.NET-C#语言转换插件

    用Visual Studio 2005 开发VB.NET-C#语言转换插件

    Visual Assist X Visual studio助手

    Visual Assist X是一款非常好的Microsoft Visual Studio 2005和Visual Studio .NET插件,支持C/C++,C#,ASP,Visua l Basic,Java和HTML等语言,能自动识别各种关键字、系统函数、成员变量、自动给出输入提示、...

    VisualGDB Ultimate 2021是Visual Studio插件,旨在帮助您调试和修复已安装的系统

    VisualGDB Ultimate 2021是一个可靠且功能强大的Visual Studio插件,旨在帮助您调试和修复已安装的系统。 它是一个完整的套件,带来了广泛的先进和增强的开发工具,可以帮助用户创建任何类型的应用程序,具有如此的...

    Visual Studio 2015 VCRedist package x86 + x64

    这些组件是运行使用 Visual Studio 2015 开发的 C++ 应用程序所必需的,并与 Visual C+ 库动态链接。这些包可用于在计算机上运行此类应用程序,即使没有安装 Visual Studio 2015。这些包安装以下库的运行时组件:C ...

    Visual Studio 插件

    Visual Studio 插件,支持C/C++,C#,ASP,Visual Basic,Java 和 HTML 等语言,Visual Assist X 能自动识别各种关键字、系统函数、成员变量、自动给出输入提示、自动更正大小写错误、自动标示错误等,有助于提高...

    VisualStudio的Python开发插件PTVS.zip

    PTVS (Python Tools for Visual Studio) 是一个开源项目,采用Apache 2.0许可发布。PTVS的主要特性包括:CPython、IronPython、Jython和PyPy;高级编辑功能如IntelliSense;多重构;内置REPL(read-eval-print loop...

    Visual Studio辅助插件VAX

    用过Eclipse的朋友们都知道它自动完成变量名,...现在,习惯使用Visual Studio的朋友们,只要安装此辅助工具之后就可以使用同样的功能了,实在是个实用的工具。软件使用前需破解,将patch.exe复制到安装目录运行即可。

    Visual Studio 扩展插件v3.0

    基于Microsoft Visual Studio 2008环境(具体项目类型为“其他项目类型”→“扩展性”→“Visual Studio 外接程序”),用C#语言开发实现的Visual Studio扩展插件,对.NET项目开发很有用,尤其是项目经理,可以批量...

Global site tag (gtag.js) - Google Analytics