7

我需要允许用户指定安装程序在卸载期间是否应删除或保留注册表项。这就是我所做的。我有一个带有 Condition 元素的 RemoveRegistryKey 组件,如下所示:

<Component
    Id="ID"
    Guid="GUID"
    KeyPath="yes" >

    <Condition></Condition>

    <RemoveRegistryKey
        Root="HKLM"
        Key="Software\PATH_TO_KEY" 
        Action="removeOnUninstall"/>
</Component>

这似乎按预期工作。如果我将 Condition 元素硬编码为0,则注册表项会保留,如果我将其设置为1,则注册表项会被删除。(创建此注册表项的组件不同,但我将其ForceDeleteOnUninstall属性设置为no。)

现在,我需要在卸载过程中通过用户输入来控制这种情况。我在 C# 中有一个 CA,如下所示:

[CustomAction]
public static ActionResult AskUser(Session session)
{
    MessageResult result = session.Message
    (
        InstallMessage.User +
            (int)MessageBoxIcon.Information +
            (int)MessageBoxButtons.YesNo,
            new Record { FormatString = String.Format("Delete registry key?") }
    );

    if (result == MessageResult.Yes)
        session["DELETEREGKEY"] = "1";

    return ActionResult.Success;
}

我使用以下代码安排 CA 执行:

<CustomAction Id="AskUserCA" BinaryKey="CA_Dll" DllEntry="AskUser" Execute="immediate" />

<InstallExecuteSequence>
    <Custom Action="AskUserCA" Before="InstallValidate">(REMOVE="ALL") AND (NOT UPGRADINGPRODUCTCODE)</Custom>
</InstallExecuteSequence>

我将 RemoveRegistryKey 组件的 Condition 元素设置为:

<Condition>DELETEREGKEY="1"</Condition>

我也尝试了 DELETEREGKEY=1 和 DELETEREGKEY,但即使我从 CA 得到提示(它出现在卸载确认对话框之后)并且我可以在日志文件中看到(当我使用日志记录时)DELETEREGKEY 设置为 1,无论响应(是或否),注册表项都不会被删除。我尝试在其他事件之前/之后安排 CA,但似乎没有任何帮助。

为什么这种情况似乎总是评估为假?有没有办法让它工作?

另外,有没有更好的选择?我正在考虑修改卸载对话框以添加一个复选框,提示用户删除注册表项,但我不确定如何执行此操作。我知道如何对安装序列进行更改——修改现有对话框或添加新对话框(我正在使用修改后的 WixUI_InstallDir 序列),但我不知道如何在卸载时进行。

有任何想法吗?

4

3 回答 3

5

通常,您在 UI 序列中而不是在执行序列中安排对话框。当您不这样做时,您将无法进行静默(卸载)安装。

我认为您的 CustomAction (CA) 运行到较晚,并且将执行的脚本已经创建。 DELETEREGKEY在这种情况下未设置并评估为 false - 结果 Key 保留。

请尝试将您的 CA 移动到 UI-Sequence。

于 2013-10-01T07:39:32.807 回答
1

对于用户数据和其他设置等项目,我过去通过在卸载过程中将数据留在机器上来处理它。在安装过程中,您可以检查此类数据,如果存在,则提示用户删除\覆盖该数据。

于 2013-10-03T17:52:52.283 回答
0

我将在这里总结我自己的发现。

看起来在执行序列中设置属性为时已晚,无法在评估条件时生效。但是将 CA 移动到 UI 序列也不是一个好的选择,因为默认情况下,卸载会在静默模式下运行,绕过 UI。有一种方法可以调整自定义卸载快捷方式和添加/删除程序 (ARP) 条目以在完整 UI 模式下运行卸载程序,但它会带来自己的麻烦,其中最少的是必须手动填充 ARP 注册表条目。

我采用的方法是在执行序列期间调用的同一 CA 中以编程方式简单地删除注册表项(因此我不需要 RemoveRegistryKey 组件)。为了允许静默卸载,我还添加了命令行选项来指定是否应删除注册表项以及是否显示提示(如果未提供删除键开关)。默认情况下,我保留注册表项。不是很优雅,但似乎可以完成这项工作。

关于修改卸载对话框的建议,请参阅WiX 3.7:如何在卸载期间添加或更新对话框?

于 2013-10-13T07:26:31.533 回答