Dsl学习笔记-2

安装完相应的插件工具后,就开始自己建立一个新的package文件了

打开VS,选择其他项目类型-扩展性,我们可以看到下图:

我们要建立DSlPackage可以有两种方式:
1:Visual Studio Package
可以直接建立一个简单的Package,建立后Solution如下图:
这是一个简单的vspackage,其中没有DslDefinition.dsl文件(该文件在选择Domain-Specific Language Designer会详细描述),
其中Guid.cs
1 static class GuidList
2     {
3         public const string guidVSPackageEmptyPkgString = "4cd4d350-c117-4dde-afb1-368af69b118d";
4         public const string guidVSPackageEmptyCmdSetString = "c565f06f-5723-4ab5-9eec-f429c14adbf4";
5         public const string guidToolWindowPersistanceString = "4f19b025-dfd2-4b3f-a12d-2f9840509558";
6 
7         public static readonly Guid guidVSPackageEmptyCmdSet = new Guid(guidVSPackageEmptyCmdSetString);
8     };

其中guidVSPackageEmptyPkgString代表package name

guidVSPackageEmptyCmdSetString对应着guidVSPackageEmptyCmdSet,

guidToolWindowPersistanceString对应着package显示的ToolWindowPane,

文件PkgCmdIDList.cs

static class PkgCmdIDList
    {
        public const uint cmdidCalculateTool = 0x101;
    }

cmdidCalculateTool对应着guidVSPackageEmptyPkgString的id

然后就是StartupToolset.vsct文件了,可以说它是整个vspackage的核心

<?xml version="1.0" encoding="utf-8"?>
<CommandTable xmlns=    
      "http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable"
      xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <Extern href="stdidcmd.h"/>
  <Extern href="vsshlids.h"/>

  <Extern href="msobtnid.h"/>
  <Commands package="guidVSPackageEmptyPkg">
    <Buttons>
      <Button guid="guidVSPackageEmptyCmdSet" id="cmdidCalculateTool"
            priority="0x0100" type="Button">
        <Parent guid="guidSHLMainMenu" id="IDG_VS_WNDO_OTRWNDWS1"/>
        <Icon guid="guidImage" id="bmpPic1"/>
        <Strings>
          <CommandName>cmdidCalculateTool</CommandName>
          <ButtonText>Calculate Tool Window</ButtonText>
        </Strings>
      </Button>
    </Buttons>
    <Bitmaps>
      <Bitmap guid="guidImage" href="Resources\Package.ico" usedList="bmpPic1"/>
    </Bitmaps>
  </Commands>
  <Symbols>
    <GuidSymbol name="guidVSPackageEmptyPkg"
          value="{4cd4d350-c117-4dde-afb1-368af69b118d}"/>
    <GuidSymbol name="guidVSPackageEmptyCmdSet"
          value="{c565f06f-5723-4ab5-9eec-f429c14adbf4}">
      <IDSymbol name="cmdidCalculateTool" value="0x0101"/>
    </GuidSymbol>
    <GuidSymbol name="guidImage" value="{91CB158E-29BC-4818-8C1F-967AF94D96B1}">
      <IDSymbol name="bmpPic1" value="1"/>
    </GuidSymbol>
  </Symbols>
</CommandTable>

他把前面提到的Guid.cs,PkgCmdIDList.cs关联了起来,指定了相应的guid

.vsct文件是Visual Studio 2008 SDK里的一种新的XML格式,vsct代表Visual Studio的命令表(Command Table),Visual Studio利用vsct文件的定义为我们的package的命令创建用户界面。如果你查看这个文件的属性的话,你会发现该文件的Build Action是VSCTCompile。在package编译过程中,vsct文件会被编译成二进制的资源,并以1000作为资源ID添加到VSPackage.resx资源文件中。当regpkg.exe去注册我们的package的时候,vsct文件代表的资源也会注册到Visual Studio中。而当VS实验室启动的时候,VS只需要去读取已注册的资源以便更新VS的界面(例如显示菜单或工具栏项),而不需要加载我们的package。

最后我们要看的是VSPackageEmptyPackage.cs文件

 [PackageRegistration(UseManagedResourcesOnly = true)]
    // This attribute is used to register the informations needed to show the this package
    // in the Help/About dialog of Visual Studio.
    [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
    [Guid(GuidList.guidVSPackageEmptyPkgString)]
    [ProvideMenuResource(1000, 1)]
    [ProvideToolWindow(typeof(MyToolWindow))] 
    public sealed class VSPackageEmptyPackage : Package
属性 描述
PackageRegistration

    regpkg.exe命令发现到类定义中有PackageRegistration这个Attribute时,会把该类当作一个package。例如把这个Attribute加到我们的类定义上面,regpkg.exe就会把我们的EmptyPackagePackage类当作一个package,并且根据该类上面含有的其他Attribute来注册我们的类。另外,在我们的例子中,我们把PackageRegistrationUseManagedResourcesOnly设成了true,这意味着我们的package中的所有资源都会定义在可管理的package中(managed package),而不是定义在卫星程序集里(statelite.dll)

DefaultRegistryRoot

    VS提供了一个简单的方法去开发和调试Visual Studio组件:在运行devenv.exe(也就是VS IDE)时,可以指定一个注册表的根。当我们在调试模式下运行我们的VS组件时,我们的组件实际上会运行在Visual Studio实验室下(Microsoft Visual Studio 2008 Experimental hive)。实验室模式下的VS和我们平时的开发环境应用了不同的设置。(译者注:有两种方式启动Visual Studio实验室,1、在开发package的VS IDE点击调试/开始执行或Ctrl+F5。2、通过开始-》所有程序-》Microsoft Visual Studio 2008 SDK-》Start Microsoft Visual Studio 2008 SP1 under Experimental hive)     当我们在VS中执行“开始调试”时(译者注:应该是利用VS进行编译时),VS会执行regpkg.exe命令,并且为该命令指定参数,以便注册我们的package到VS实验室环境中。     如果regpkg.exe命令在运行时并没有指定参数,那么就会用到DefaultRegistryRoot属性里指定的注册表的根。在我们的例子中,我们指定了“普通”的VS 2008 IDE用到的注册表根。

(译者注:利用VS进行编译时,查看输出窗口,可以看到有这么一条命令:RegPkg.exe /root:Software\Microsoft\VisualStudio\9.0Exp /ranu /codebase "路径\EmptyPackage\bin\Debug\EmptyPackage.dll",在这条命令里,通过/root开关指定了注册表的根为9.0Exp,也就是说我们通过DefaultRegistryRoot指定的根并没有用到。所以在通过VS进行编译时,会把package注册到Experimental hive中。原文作者的意思是如果不指定RegPkg命令的/root开关的话,就会用到DefaultRegistryRoot指定的注册表根)

InstalledProductRegistration

    这个Attribute提供的信息会显示在VS IDE的“帮助|关于”对话框里。它的构造函数需要四个参数:

    --第一个参数是false,表示我们并不提供自己的界面去显示package信息。

    --第二和第三个参数分别表示package的名字和描述。字符“#”表明名字和描述的值需要在资源文件中读出,资源名就是#号后面的ID。

    --第四个参数“1.0”是产品ID(版本号)

    --第五个参数(IconResourceID)代表package的图标。

    资源(名字、描述和图标)定义在VSPackage.resx文件中。

ProvideLoadKey

    每一个VS组件都应该用所谓的package load key(PLK)进行签名,Visual Studio用PLK去检查package的合法性。不过,如果你安装了Visual studio SDK的话,会安装一个VSIP的许可证,通过它,package可以在没有PLK的情况下运行。

    但是,我们的package的最终用户很可能没有VSIP的许可证,所以我们需要PLK。ProvideLoadKey属性用于定义PLK和生成PLK的基础信息。通过比较基础信息和PLK是否一致,VS可以验证package并决定是否允许package加载运行。

    ProvideLoadKey属性构造函数的前4个参数分别表示如下含义:

    --预计的最小版本

    --产品(Package)的版本号

    --产品(Package)的名字

    --公司名称(所有者/开发者)

    第5个参数是资源文件中定义PLK的资源ID。

(译者注:PLK需要到微软网站上http://msdn.microsoft.com/en-us/vsx/cc655795.aspx去申请)

Guid

这个Attribute定义了我们package的GUID。GUID是我们package的唯一标识,被用作COM注册、在IDE里得到我们package的引用,等等。

 

另外ProvideMenuResourceAttribute构造函数有两个参数,第一个参数是resourceID,这个参数值必须是1000,因为VSCT编译器在把vsct文件编译到VSPackage资源中的时候,默认用1000作为vsct文件对应的资源ID。第二个参数是versionID,它的取值在资源的缓存机制中非常重要。现在先不要深入研究它的细节了,只需要记住ProvideMenuResourceAttribute允许我们为package注册菜单资源。 我们需要修改project如下:

<VSCTCompile Include="StartupToolset.vsct">
      <ResourceName>1000</ResourceName>
    </VSCTCompile>

这样一个简单的package就完成了。
我们可以运行下看看是否有加载,如下图:
加载成功。
 
2:Domain-Specific Language Designer,to be continued!
 
posted @ 2013-10-21 11:33  gavin.huang  阅读(410)  评论(0编辑  收藏  举报