前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >(翻译)LearnVSXNow! #8 插曲-regpkg.exe命令

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

作者头像
明年我18
发布2019-09-18 11:36:35
3970
发布2019-09-18 11:36:35
举报
文章被收录于专栏:明年我18明年我18

当我准备去写“创建我们的第一个工具集”系列的下一篇时,我意识到我的注册表已经被我之前创建的示例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接受如下的命令行语法:

代码语言:javascript
复制
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文件:

代码语言:javascript
复制
regpkg.exe /regFile:.\EmptyPackage.reg /ranu /root:Software\Microsoft\VisualStudio\9.0Exp .\bin\Debug\EmptyPackage.dll

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

代码语言:javascript
复制
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:

代码语言:javascript
复制
[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注册信息就会直接写到注册表里了:

代码语言:javascript
复制
regpkg.exe /ranu /root:Software\Microsoft\VisualStudio\9.0Exp .\bin\Debug\EmptyPackage.dll

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

卸载package

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

代码语言:javascript
复制
regpkg.exe /unregister /ranu /root:Software\Microsoft\VisualStudio\9.0Exp .\bin\Debug\EmptyPackage.dll

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

在开发阶段卸载package

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

代码语言:javascript
复制
"%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,这是一个不错的用法。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2010-03-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 熟悉一下regpkg.exe
  • 用哪个版本的regpgk.exe?
  • regpgk.exe可以做什么?
  • 怎样使用regpgk.exe?
  • 示例
  • 生成reg文件
  • 注册package
  • 卸载package
  • 在开发阶段卸载package
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档