WiX RemoveRegistryKey 元素的行为不像宣传的那样
Posted
技术标签:
【中文标题】WiX RemoveRegistryKey 元素的行为不像宣传的那样【英文标题】:WiX RemoveRegistryKey element not behaving as advertised 【发布时间】:2017-07-04 13:10:23 【问题描述】:卸载时似乎无法删除注册表项。请注意,这不是this 问题的重复,因为我认为我没有同样的问题。或者,如果我这样做了,我想澄清一下为什么。当我在新的 VM 上安装时会出现此问题,因此我不是在同一个 GUID 之上安装的。
我正在做的是将来自用户(来自 UI)的值放入一些属性中,然后通过 CustomAction 将这些值导入到一些 C# 代码中,然后我在其中加密这些值并将它们放入一个注册表项。
我不使用 WiX 将值放入注册表项,而是通过 C# 代码进行。原因是我似乎无法将属性导入 C# 自定义操作,然后将相同代码中的值导出回 WiX(我可以单独执行每个操作都没有问题)。但这是一个不同的问题......
无论如何,我得到这些值,加密它们,并将它们放入注册表项中就好了。卸载时我似乎无法删除注册表项。奇怪的是,它确实删除了键中除一个之外的每个值,但它不会删除整个键。
这是应该删除密钥(但不会)的 XML:
<Component Id="Component_CleanRegistryOnUninstall"
Directory="TARGETDIR"
Guid="86D04E28-2EF8-4A6C-BB9B-577EA1597BB5"
KeyPath="yes">
<RemoveRegistryKey Id="CleanupRegistry"
Root="HKLM"
Key="Software\...\...\InstallCfg"
Action="removeOnUninstall"/>
</Component>
这是创建 C# 自定义操作的 XML:
<Fragment>
<Property Id="VAL1" Hidden="yes"/>
<Property Id="VAL2" Hidden="yes"/>
<Property Id="VAL3" Hidden="yes"/>
<Property Id="VAL4" Hidden="yes"/>
<SetProperty Id="CustomAction_PassProperty"
Value="VAL1=[VAL1];VAL2=[VAL2];VAL3=[VAL3];VAL4=[VAL4]"
Sequence="execute"
Before="CustomAction_PassProperty"/>
<Binary Id="Binary_PassProps"
SourceFile="$(var.CreateRegistryKey.TargetDir)CreateRegistryKey.CA.dll"/>
<!-- Note that 'Impersonate="no"' elevates the privilege of the C# code, needed to create keys -->
<CustomAction Id="CustomAction_PassProperty"
BinaryKey="Binary_PassProps"
DllEntry="CreateKeys"
Execute="deferred"
Impersonate="no"
Return="check"
HideTarget="yes"/>
<InstallExecuteSequence>
<Custom Action="CustomAction_PassProperty"
After="InstallInitialize"/>
</InstallExecuteSequence>
</Fragment>
这是 C# 本身:
[CustomAction]
public static ActionResult CreateKeys(Session session)
// encrypt and set set the registry keys
Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\...\\...\\InstallCfg", "Val1", Encrypt(session.CustomActionData["VAL1"]));
Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\...\\...\\InstallCfg", "Val2", Encrypt(session.CustomActionData["VAL2"]));
Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\...\\...\\InstallCfg", "Val3", Encrypt(session.CustomActionData["VAL3"]));
Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\...\\...\\InstallCfg", "Val4", Encrypt(session.CustomActionData["VAL4"]));
// also, set the "SettingsProcessed" key to false
Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\...\\...\\InstallCfg", "SettingsProcessed", "false");
return ActionResult.Success;
设置的最终值——刚刚作为“假”而不是加密值传入的值——是一个标志,可能是问题的关键。
这是一种奇怪的行为:当我卸载时,密钥并没有被删除,但它确实删除了所有值除了一个没有被删除的值传递给 C# 函数,标志。它不会被删除。但是,即使我创建了一个属性,也要为该属性赋予值“false”,然后将其传递给 C#,如下所示:
Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\...\\...\\InstallCfg", "SettingsProcessed", session.CustomActionData["SETTINGSPROCESSED"]);
同样的事情发生了:除它之外的所有其他值都被删除。我承认这可能是组件问题,答案可能在this 答案中,但我无法弄清楚。
总结一下:注册表项已创建,但<RemoveRegistryKey>
不会在卸载时将其删除。
编辑::
Bob 从来没有让他的<RemoveRegistryKey>
元素起作用。他退出 IT 并搬到奥马哈,在那里经营一家黎巴嫩/荷兰比萨店并练习班卓琴。
不,真的,我从来没有让它工作。我最终创建了 另一个 删除密钥的自定义操作。这太令人沮丧了,让我想搬到奥马哈。
【问题讨论】:
【参考方案1】:您需要设置条件在卸载期间不运行CustomAction_PassProperty
。
像这样:
<InstallExecuteSequence>
<Custom Action="CustomAction_PassProperty"
After="InstallInitialize>NOT REMOVE="ALL"</Custom>
</InstallExecuteSequence>
它“删除所有值”除了硬编码的值可能是因为您在卸载期间重写了 VAL1, VAL2...
的值,此时这些属性可能为空(它们仅在安装期间在 ui 中设置顺序对吗?)。
【讨论】:
感谢您的回复!是的,属性仅在 UI 序列期间设置,硬编码标志除外。在卸载期间它们会被删除是有道理的(硬编码标志除外)。当我提出您建议的条件时,我确实得到了不同的行为 - 现在,当我卸载时,它不会删除这些值。 VAL1,..., VALX 以及标志仍然存在。然而,这不是我想做的。我想完全删除注册表项。 This 对话澄清了很多关于条件的问题——如何让自定义操作在您需要时运行。我需要做的是:让我的自定义操作仅在安装和维修期间运行。 另外,在卸载过程中,我需要删除自定义操作创建的注册表项。这就是我卡住的地方。 您是否在Component_CleanRegistryOnUninstall
组件?此外,我建议记录卸载并查看与组件相关的情况。做yourmsi.msi /x /l*v log.txt
以上是关于WiX RemoveRegistryKey 元素的行为不像宣传的那样的主要内容,如果未能解决你的问题,请参考以下文章
WiX:错误 RegistryKey 元素包含意外属性“ForceDeleteOnUninstall”
wix - 错误 CNDL0004:从命令行运行时文件元素包含意外的属性“src”
为啥 FileSearch 元素的 MinVersion 属性在我的 WiX 安装程序中不起作用?