我的 WiX 卸载如何恢复注册表值更改?

发布于 2024-08-26 23:29:21 字数 128 浏览 5 评论 0原文

我使用 WiX 3.0 编写的安装程序使用RegistryValue 元素来修改现有的注册表值(最初由我们的主要产品编写)。我正在尝试找出一种在用户卸载我的实用程序时恢复注册表值的方法。我想避免使用自定义操作,但这可能是唯一的办法? TIA。

The installer I'm writing using WiX 3.0 uses a RegistryValue element to modify an existing registry value (originally written by our main product). I'm trying to figure out a way to restore the registry value when the user uninstalls my utility. I'd like to avoid using a custom action, but that might be the only recourse? TIA.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

知你几分 2024-09-02 23:29:21

我这样做了。有问题的注册表值是与文件扩展名关联的应用程序,但它可以是任何注册表值。

我的第一个想法是使用“自定义操作”进行安装和卸载以保留
并分别恢复相关的regy状态。这
看起来很简单。

我在 VS2008 中创建了一个安装项目,并将 CA 构建为 javascript 文件。 “安装时”脚本获取现有的 regy 值并将其隐藏到一个众所周知的位置。 “卸载时”脚本将在众所周知的位置查找,然后将在那里找到的值放回原始位置。
容易,对吧?

有两个问题:

  1. 安装期间运行的脚本,用于保留预先存在的注册表值,
    更新注册表后运行
    以及新安装的值。因此它保留了新设置,而不是 MSI 运行之前的设置。没用。

  2. 卸载期间运行的脚本,在注册表值之后运行,实际上是整个目录子树,
    已被删除。包括隐藏的价值。所以它已经失去了状态。


为了解决这个问题,我编写了 另一个脚本
重新排序自定义操作
,以便它们在正确的时间运行。

实际上还有一个转折。显然,“恢复”脚本(在
如果在删除应用程序的注册表项后运行卸载程序,则该程序将不起作用。我现在不记得为什么......但我也确定此脚本在此之前无法运行。不知怎的,这也不起作用。

因此,我修改了 MSI 来运行恢复脚本
两次。在第一阶段,它将隐藏的值转移到注册表中的“停车场”。
然后应用程序在注册表中的键和值被删除,但停车场仍然存在。在
第 2 阶段,在事务保护之外,恢复脚本从停车场检索状态,恢复
文件关联,然后删除停车场。

我不记得为什么我需要分两步完成此操作,但我记得在想出该解决方案之前我与它斗争了一段时间。

它在开发中的工作方式:

  • 在 VS 项目中设置 on installon uninstall CA
  • 构建 VS 安装项目,
  • 运行修改 MSI 的后处理脚本。

使用 MSI 时,它比我最初想象的要复杂一些,但它可以工作。

如果您使用 WiX,您可能可以更好地控制步骤的时间和顺序,因此可能不需要后处理步骤。


最后,您说您想避免使用 CA。对我来说,避免使用 CA 是因为在 C++ 中生成它们很痛苦,并且在 .NET 中生成它们通常是不合适的。但是,在 CA 中使用 Javascript 非常简单。有些人认为脚本是 CA 工作的错误工具。我认为这是错误的。 我认为脚本是一个非常用于此目的的好工具。一旦您接受脚本作为一个好的工具,那么您就不需要对创建自定义 CA 保持警惕。

I did this. The registry value in question was the application associated to a file extension, but it could be any registry value.

My first idea was to use a "custom action" for install and uninstall to preserve
and restore, respectively, the associated regy state. This
seemed simple enough.

I created a setup project in VS2008 and built the CA's as javascript files. The "on install" script grabbed the existing regy value and stashed it into a well-known place. The "on uninstall" script would look in the well-known place, and then put the value found there, back in the original location.
Easy, right?

There were two problems:

  1. the script that ran during install, to preserve the pre-existing registry value,
    runs AFTER the registry has already been updated
    with the values for the newly installed thing. So it preserved the new setting instead of the setting that was there before the MSI ran. Not useful.

  2. The script that runs during uninstall, runs AFTER the registry values, and in fact the entire directory subtree,
    have been deleted. Including the stashed value. So it had lost its state.


To solve that I wrote another script that
re-orders the custom actions
so they run at the proper times.

There's actually one more twist. Obviously, the "Restore" script (on
uninstall) won't work if it is run after the registry entries for the app have been deleted. I can't remember now, why... but I also determined that this script could not run before that. Somehow that wasn't working either.

So, I modified the MSI to run the restore script
twice. In phase 1, it transfers the stashed value to a "parking lot" in the registry.
Then the application's Keys and Values in the registry get deleted, but the parking lot remains. In
phase 2, outside the transactional protection, the restore script retrieves the state from the parking lot, restores
the file association, and then deletes the parking lot.

I can't remember exactly why I needed to do this in 2 steps, but I remember fighting with it for a while before coming up with that solution.

The way it works in development:

  • set the on install and on uninstall CA's in the VS project
  • build the VS Setup project
  • run the post-processing script that modifies the MSI.

When using the MSI, it's a little more complicated than I originally thought but it works.

If you are using WiX, you may have more control over the time and ordering of the steps, so may not need that post-processing step.


Finally, you said you wanted to avoid a CA. To me, CA's are avoided because they are painful to produce in C++, and producing them in .NET is often inappropriate. But, it's pretty simple to use Javascript for CA's. Some people think script is the wrong tool for the CA job. I think that's wrongheaded. I think script is a very good tool for this purpose. And once you can accept script as a good tool, then you don't need to hold your nose about creating a custom CA.

怎言笑 2024-09-02 23:29:21

注册表在卸载期间无法写入注册表值,因此必须通过自定义操作来完成此操作是正确的。我认为使用脚本是不好的。是否选择倾听取决于您。我可以告诉你,就在前几天,我被叫去解决一个问题,其中一些人编写了一个 vbscript CA,该 CA 由于文件系统对象在安全锁定过程中未注册而失败。

我建议根据您的需要使用 C++ 或 C#/DTF。

The registry table is incapable of writing a registry value during an uninstall so it is correct that this must be done via custom action. I am of the opinion that using script is bad. Whether you choose to listen is up to you. I can tell you that just the other day I was called into to trouble shoot a situation where some wrote a vbscript CA that was failing because the file system object had been unregistered as part of a security lockdown process.

I suggest C++ or C#/DTF depending on your needs.

轻拂→两袖风尘 2024-09-02 23:29:21

面对类似的问题,需要在安装时更新注册表值并在卸载时恢复到以前的值。
唯一可能的解决方案是为此目的创建自定义操作吗?

我找到了一个 wix 的扩展,它具有用于此目的的功能
wix 扩展链接

Faced with similar issue, need to update the registry value on install and restore to previous value on uninstall.
Is the only solution possible is creating a custom action for this purpose?

I found a extension for wix that has fucntions for this purpose
link to wix extensions

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文