当我准备去写“创建我们的第一个工具集”系列的下一篇时,我意识到我的注册表已经被我之前创建的示例package给污染了。当我试图卸载这些package以便清理这些垃圾时,我和regpkg.exe程序有了一次亲密的接触。早先我就有计划写这么一篇类似主题的文章(但一直没有写),现在我决定不再拖了,就算我们不得不先暂停一下“创建我们的第一个工具集”系列的编写。
在这篇文章里,你可以看到关于这个命令的我认为非常重要的内容。VS 2008 SDK的文档并没有太多关于regpkg.exe的内容,所以,在这篇文章中我尽量根据我的经验,用容易理解的语言来帮助你了解它。
熟悉一下regpkg.exe
如果看过了前面的文章,并且创建了示例包,你的Visual Studio experimental hive下就注册了一些VSPackage的信息。你的注册表(和VS experimental hive)已经被没有用的package给污染了。为了清理掉这些垃圾,我们将和regpkg.exe来一次“亲密的接触”,利用它来卸载这些package。
任何一个package和它的对象(例如菜单和工具窗)都可以通过VS 2008 SDK(当然也包括VS 2005 SDK)提供的regpkg.exe程序注册并集成到VS IDE中。regpkg.exe程序的作用就是注册和卸载VSPackage,并且支持“手动”地注册和卸载。
用哪个版本的regpgk.exe?
如果你在电脑上同时安装了VS 2005 SDK和VS 2008 SDK,你的机子上就会有两个不同版本的regpkg.exe。每一个只能用在由相应版本的VS SDK创建的package上。如果为了自动找到该程序,你把其中一个regpkg.exe程序所在的路径放到了环境变量Path里,你就有可能遇到由于版本不对而带来的问题。所以,当你的package注册失败时,首先要确定是不是用了错误版本的regpkg.exe程序。
VS 2008 SDK版本的regpkg.exe位于VS 2008 SDK的安装目录(可以参考环境变量VSSDK90Install的值)下的VisualStudioIntegration\Tools\Bin目录中。在该目录下还有一个VS2005的子目录,里面放的值VS 2005 SDK版本的regpkg.exe。
那么,这两个版本的regpkg.exe有什么区别呢?regpkg.exe程序在运行时,会扫描一个程序集中的Package类上面附加的一些Attribute,这些Attribute定义在Microsoft.VisualStudio.Shell.dll程序集(对于VS 2005)或者Microsoft.VisualStudio.Shell.9.0.dll程序集(对于VS 2008)中。这些不同版本的Attribute虽然有相同的名字,但它们并不是同一种类型(因为他们在不同的程序集里),所以regpkg.exe无法扫描到不同版本的Attribute。
你可以试一下:在任意一个VSPackage项目里,删掉对~Shell.9.0.dll的引用,并添加对~Shell.dll的引用。当生成你的VSPackage时,你会看到“No registration data found in this assembly”的错误消息。这个消息出现在成功编译package之后,这是因为改变引用并不会导致编译不通过。出现这个错误的原因,是由于在MSBuild任务里运行了regpkg.exe,而那些注册package需要的attribute又是定义在另外版本的sdk中的,所以会注册不成功。
regpgk.exe可以做什么?
regpkg会扫描程序集中和package注册有关的attribute,并根据这些attribute生成一个注册项的集合,供下一步使用。我们可以在运行regpkg.exe的时候为它指定参数,以实现:
- 把注册信息导出到文件中,供安装程序(msi文件)使用。
- 把注册信息写入注册表——也就是注册我们的package。
- 从注册表中删除注册信息——也就是卸载package。
怎样使用regpgk.exe?
当运行regpkg.exe的时候,你必须告诉它要注册的程序集的名字,以及一些注册的选项(以命令行参数的形式)。regpkg.exe接受如下的命令行语法: