专栏首页明年我18(翻译)LearnVSXNow! #8 插曲-regpkg.exe命令

(翻译)LearnVSXNow! #8 插曲-regpkg.exe命令

当我准备去写“创建我们的第一个工具集”系列的下一篇时,我意识到我的注册表已经被我之前创建的示例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的时候为它指定参数,以实现:

  1. 把注册信息导出到文件中,供安装程序(msi文件)使用。
  2. 把注册信息写入注册表——也就是注册我们的package。
  3. 从注册表中删除注册信息——也就是卸载package。

怎样使用regpgk.exe?

当运行regpkg.exe的时候,你必须告诉它要注册的程序集的名字,以及一些注册的选项(以命令行参数的形式)。regpkg.exe接受如下的命令行语法:

regpkg.exe [options] AssemblyPath

参数AssemblyPath是要注册的程序集的路径,是相对于正在运行regpkg的路径的相对路径(译者注:很不幸,我在使用regpkg时,必须用绝对路径才能够使这个命令正确运行,用相对路径会报错。所以读者在尝试这篇文章里的例子时,如果报错,可以使用绝对路径来试一下。)。 [options]可以指定你希望执行的操作,或者指定注册项的路径。下面的表格列出了可以使用的options:

选项

描述

/ranu

如果你登录的账户不是系统管理员,你就应该用这个选项。应用该选项后,注册信息会写到HKEY_CURRENT_USER下。我建议在开发阶段要一直用这个选项。

/root:RegRoot

指定注册表里的一个根目录,在package注册时写入或删除的键都会位于该根目录下。如果没有指定根目录的话,regpkg.exe就会根据package类上面附加的 DefaultRegistryRootAttribute指定的根目录来注册package。(译者注:可以参考第2篇文章里关于DefaultRegistryRoot的内容) 当开发package的时候,我们通常会用Visual Studio实验室模式(Experimental Hive)来测试我们的package,所以我们必须用Software\Microsoft\VisualStudio\9.0Exp作为根。regpkg.exe会把 Configuration项和它的子项添加到我们指定的根下面。

/unregister

利用该选项,可以清除一个package的注册信息。这个选项不能和下面那一行里的任何一个选项同时用。

/regfile:FileName/rgsfile:FileName/vrgfile:FileName/wixfile:FileName/rgm

这些选项都可以使regpkg.exe把注册信息导出到文件里,以便供其他的程序所用(例如安装程序)。前四个选项必须指定一个文件名:即导出后的文件的文件名。你一次只能用其中的一个选项,它们不能同时用。这四个选项分别用于导出reg、rgs、vrg和wix文件。另外,如果你用了/vrgfile选项的话,你还可以再加上/rgm选项,以便再创建一个rgm文件。 如果你想搞清楚regpkg在注册package时会注册什么样的信息进去的话,我建议你可以用/regfile选项:当regpkg.exe执行完之后,可以用记事本来查看它生成的reg文件。通过双击reg文件,也可以把注册信息添加到注册表。

/CodeBase/Assembly

当注册一个package的时候,包含这个package的程序集也应该被注册,因为在使用package的时候,VS要加载对应的程序集。可以用程序集的全名来注册(通过/Assembly选项),VS会从GAC里加载它;也可以通过绝对路径来注册它(通过/CodeBase选项),VS会从这个路径里加载它。

示例

让我们看一下一些使用regpkg的例子。

生成reg文件

这个例子为第2篇文章中的EmptyPackage生成了EmptyPackage.reg文件:

regpkg.exe /regFile:.\EmptyPackage.reg /ranu /root:Software\Microsoft\VisualStudio\9.0Exp .\bin\Debug\EmptyPackage.dll

这条命令运行完后,我们可以在生成的reg文件里看到如下内容:

REGEDIT4  [HKEY_CURRENT_USER\9.0Ex\Configuration\InstalledProducts\EmptyPackagePackage]@="#110""Package"="{223643a0-af7c-4741-99df-e9641691af50}""ProductDetails"="#112""PID"="1.0""LogoID"="#400"  [HKEY_CURRENT_USER\9.0Ex\Configuration\Packages\{223643a0-af7c-4741-99df-e9641691af50}]@="MyCompany.EmptyPackage.EmptyPackagePackage, EmptyPackage, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null""InprocServer32"="C:\\Windows\\system32\\mscoree.dll""Class"="MyCompany.EmptyPackage.EmptyPackagePackage""Assembly"="EmptyPackage, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"  [HKEY_CURRENT_USER\9.0Ex\Configuration\Packages\{223643a0-af7c-4741-99df-e9641691af50}]"ID"=dword:00000001"MinEdition"="Standard""ProductVersion"="1.0""ProductName"="EmptyPackage""CompanyName"="MyCompany"

这个文件包含三个段注册信息,这些信息都会注册到Configuration注册项下面。第一段和第三段的信息来自于EmptyPackagePackage类上面附加的一些attribute:

[InstalledProductRegistration(false, "#110", "#112", "1.0", IconResourceID = 400)][ProvideLoadKey("Standard", "1.0", "EmptyPackage", "MyCompany", 1)][Guid(GuidList.guidEmptyPackagePkgString)] public sealed class EmptyPackagePackage : Package { ... }

第二段是关于程序集和package的信息。

注册package

去掉/regfile选项的话,我们的package注册信息就会直接写到注册表里了:

regpkg.exe /ranu /root:Software\Microsoft\VisualStudio\9.0Exp .\bin\Debug\EmptyPackage.dll

我们可以运行regedit.exe打开注册表编辑器,来看一下上面这条命令执行后的结果。

卸载package

我猜你已经开始想象怎样卸载package了。没错,我们只需要简单地在命令行里加上/unregister选项:

regpkg.exe /unregister /ranu /root:Software\Microsoft\VisualStudio\9.0Exp .\bin\Debug\EmptyPackage.dll

如果运行regedit.exe打开注册表编辑器的话,你会看到EmptyPackagePackage相关的注册键已经被删除了。

在开发阶段卸载package

如果我们可以在项目里添加一些可以用来卸载没用的package的东西,是非常棒的。有好几种方法可以做到这一点。我建议你用最简单的方法:在项目里添加一个command文件(.cmd),在这个文件里调用regpkg.exe,并加上/unregister选项。例如:

"%VSSDK90Install%\VisualStudioIntegration\Tools\Bin\regpkg.exe" /unregister /ranu /root:Software\Microsoft\VisualStudio\9.0Exp .\bin\Debug\<your.dll>pause

我建议在调用regpkg.exe时,用环境变量VSSDK90Install来避免和VS 2005 SDK的regpkg.exe混淆。我假设你是把这个command文件放在了项目文件(csproj)的目录下,如果不是的话,请你修改这个command文件里的dll的路径。

一定要注意,每次编译package后,这package会被重新注册进去。另外,如果你的解决方案下不止一个package项目,我建议把cmd文件放在解决方案文件夹下,以便卸载解决方案下的所有package。

总结

现在我们与regpkg.exe命令有了一次亲密接触了,并且知道它是怎样工作的了。由于VS 2005 SDK和VS 2008 SDK用的是不同的regpkg.exe,所以使用的时候一定要小心,确保使用正确的那个。

用这个命令可以把注册项写入一个文件里,并且在真正注册进去之前检查一下它。这可以帮助我们清楚到底注册了什么东西,甚至可以帮助我们找到package注册时遇到的错误。

另外,我们也可以在项目里添加一个command文件并根据自己的需要来卸载package,这是一个不错的用法。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • (翻译)LearnVSXNow! #13- VS IDE中的菜单和命令

    几乎所有的VSPackage都有用户交互,用户可以通过点击Visual Studio中的菜单或工具栏来激活VSPackage的功能或显示相关的界面。

    明年我18
  • Linux red hat enterprise5下安装oracle

    我对linux是绝对的菜鸟,但今天有份工作是给一台装在linux上的oracle服务器设置自动数据备份。这很可能是只做一次的工作,只做一次的东西,时间久了肯定会...

    明年我18
  • 一个轻量小巧的集成在vs里的代码生成工具

    liberate是一个集成在vs里的轻量小巧的代码生成框架,当然如果您已经熟练运用CodeSmith了,您就不用考虑它了。不过也可以把它作为学习vsx...

    明年我18
  • 关于stm32的正交解码

    关于正交解码,我先解释何为正交解码,,,,其实名字挺高大上的,,,,还是先说编码器吧 看一下我用过的一种编码器 ? ? ? 编码器的 线 数 ,是说编码器转一圈...

    杨奉武
  • 一文看懂银联云闪付二维码付款行如何改造

    银联与付款行之间存在2种持卡人账户扣款的模式,即“移动应用前置模式”和“银行卡前置模式”。APP绑定本行卡可以选择其中一种模式,银联通过参数配置管理;APP绑定...

    金融民工小曾
  • 【数据分析可视化】通过去重进行数据清洗

    瑞新
  • 赶潮流!劳斯莱斯也玩起了“无人驾驶”!

    镁客网
  • 每天一道面试题——登录

    我常说一句话;测试人员最重要的财富就是他受过训练的大脑。而其中最重要的,就是他是否具备成熟的测试思维。

    张树臣
  • Mac OS X 下非官方软件自启动处理

    正文之前 说是处理,想必也没几个人喜欢自启动的软件,我是一个控制欲比较强的人,开机自启搜狗输入法这个我能接受,但是像印象笔记啊,向日葵圆孔Client客户端这些...

    用户1687088
  • 自动清理Oracle归档日志

    Oracle的归档模式( ARCHIVELOG ) 一般用于数据库的复制和备份,相对重要的企业应用都会打开该模式,每当执行了增删改的操作,Oracle就会自动归...

    tonglei0429

扫码关注云+社区

领取腾讯云代金券