如何添加仅在卸载(通过MSI)时发生的WiX自定义操作?
我想修改一个MSI安装程序(通过WiX创build)来删除卸载时的整个目录。
我了解了WiX中的RemoveFile
和RemoveFolder
选项,但是这些选项不够强大,无法recursion删除安装后创build内容的整个文件夹。
我注意到类似的堆栈溢出问题卸载WiX时删除文件 ,但我想知道这是否可以做更简单地使用调用批处理脚本来删除文件夹。
这是我第一次使用WiX,而且我仍然掌握着自定义操作 。 什么是将在卸载时运行批处理脚本的自定义操作的基本示例?
这个话题长久以来一直令人头痛。 我终于明白了。 网上有一些解决scheme,但没有一个真的有效。 当然,没有文件。 所以在下面的图表中有几个build议使用的属性以及它们在各种安装场景下的值:
所以在我的情况下,我想要一个只能在卸载时运行的CA – 不能升级,不能修复或修改。 根据上面的表格,我不得不使用
<Custom Action='CA_ID' Before='other_CA_ID'> (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
它的工作!
yaluna的答案有多个问题,属性名称也是区分大小写的, Installed
是正确的拼写( INSTALLED
将不起作用)。 上面的表应该是这样的:
另外假设一个完整的维修和卸载属性的实际值可能是:
WiXexpression式语法文档说:
在这些expression式中,可以使用属性名称(请记住它们区分大小写)。
这些属性在Windows安装指南(例如已安装 )
编辑:对第一个表的小修正; 显然“卸载”也可以发生只有REMOVE
为True
。
您可以使用自定义操作来完成此操作。 您可以在<InstallExecuteSequence>
下为您的自定义操作添加一个参考:
<InstallExecuteSequence> ... <Custom Action="FileCleaner" After='InstallFinalize'> Installed AND NOT UPGRADINGPRODUCTCODE</Custom>
然后,您还必须在<Product>
下定义您的操作:
<Product> ... <CustomAction Id='FileCleaner' BinaryKey='FileCleanerEXE' ExeCommand='' Return='asyncNoWait' />
FileCleanerEXE是一个二进制文件(在我的例子中是一个自定义操作的c ++程序),它也在<Product>
定义:
<Product> ... <Binary Id="FileCleanerEXE" SourceFile="path\to\fileCleaner.exe" />
真正的技巧是自定义操作中的Installed AND NOT UPGRADINGPRODUCTCODE
条件,而且每次升级都会运行您的操作(因为升级实际上是卸载,然后重新安装)。 如果你正在删除文件,可能不想在升级过程中想要。
在一个侧面说明:我build议经历使用类似C ++程序的事情来执行操作,而不是批处理脚本的麻烦,因为它提供的权力和控制 – 你可以防止“cmd提示符”窗口闪烁您的安装程序运行。
批处理脚本最大的问题是处理回滚,当用户单击取消(或在安装过程中出现错误)。 处理这种情况的正确方法是创build一个将临时行添加到RemoveFiles表的CustomAction。 这样Windows安装程序将为您处理回滚情况。 当你看到解决scheme时,它非常简单。
无论如何,只有在卸载期间才能执行操作,请添加一个Condition元素:
REMOVE ~= "ALL"
〜=表示比较不区分大小写(即使我认为ALL始终是uppercaesd)。 有关更多信息,请参阅有关条件语法的MSI SDK文档 。
PS:从来没有我坐下来想过的事情,“哦,batch file在安装包中是一个很好的解决scheme”。 实际上,find一个包含batch file的安装包只会鼓励我退还产品。
我使用C ++ DLL分别编码的自定义操作,并使用该DLL在卸载时使用以下语法调用适当的函数:
<CustomAction Id="Uninstall" BinaryKey="Dll_Name" DllEntry="Function_Name" Execute="deferred" />
使用上面的代码块,我可以在卸载时运行C ++ DLL中定义的任何函数。 仅供参考,我的卸载function有清除当前用户数据和registry项的代码。