System.IO.Directory.Delete中的异常未在customaction中捕获(使用wix工具集生成的msi)
在.NET Framework 4.7.2上使用Windows 7以管理员身份启动。
调用customaction的日志文件:
MSI(s)(A0:D8)[08:31:39:027]:执行操作:ActionStart(Name = CacheCustomActions.DeleteOldInstallationFolders ,,) MSI(s)(A0:D8)[08:31:39:027]:执行操作:CustomActionSchedule(Action = CacheCustomActions.DeleteOldInstallationFolders,ActionType = 1025,Source = BinaryData,Target = DeleteOldInstallationFolders,CustomActionData = XXXDIR = C:\ XXX \;) MSI(s)(A0:AC)[08:31:39:028]:调用远程自定义操作。 DLL:C:\ Windows \ Installer \ MSI7B8A.tmp,入口点:DeleteOldInstallationFolders SFXCA:将自定义操作提取到临时目录:C:\ Windows \ Installer \ MSI7B8A.tmp- \ SFXCA:绑定到CLR版本v4.0.30319 调用自定义操作CustomActions!CustomActions.CustomActions.DeleteOldInstallationFolders *****开始DeleteOldInstallationFolders *****删除文件夹:C:\ XXX \ temp *****删除文件夹:C:\ XXX \ temp2 CustomAction CacheCustomActions.DeleteOldInstallationFolders返回了实际错误代码1603(请注意,如果在沙箱中进行翻译,则此错误可能不是100%准确)
try
{
session.LogWithTime($"Deleting directory {directory}");
Directory.Delete(directory, true);
}
catch (Exception e)
{
session.LogWithTime($"Failed to delete directory {directory}");
}
预期:目录已删除或引发了异常 实际:存在自定义操作,错误代码为1603。
Wxs文件看起来像这样,但是我不认为有问题,在数百台计算机上一切正常,只是发生错误的一台计算机:
<CustomAction Id="PrepareArgumentsForDeferredCall.DeleteOldInstallationFolders" Property="CacheCustomActions.DeleteOldInstallationFolders" Value="XXXDIR=[XXXDIR];ISEXPERTMODEENABLED=[ISEXPERTMODEENABLED]" Execute="immediate" />
[...]
<CustomAction Id="CacheCustomActions.DeleteOldInstallationFolders" BinaryKey="CustomActionBinary" DllEntry="DeleteOldInstallationFolders" Execute="deferred" Return="check"/>
[...]
<Custom Action="PrepareArgumentsForDeferredCall.DeleteOldInstallationFolders" After="CostFinalize" />
[..]
<Custom Action="CacheCustomActions.DeleteOldInstallationFolders" After="InstallInitialize">NOT REMOVE AND NOT PATCH AND NOT REINSTALL</Custom>
答案 0 :(得分:1)
免责声明 :请谨慎使用所有删除元素(文件/文件夹)。仅在虚拟机上测试。显然。
MSI :您是否尝试过在MSI中使用RemoveFile table
?这是内置的MSI表,允许删除文件和文件夹作为安装操作。仅空文件夹。 Sample。
WiX : WiX's Util namespace
中还有实用程序dll函数:RemoveFolderEx Element (Util Extension)
-这是WiX自己的使用C ++编写的自定义操作,而不是MSI的内置内容。据我所知,您可以使用此方法删除包含文件的文件夹。已经有一段时间。 Sample(未经测试,使用后果自负-显然)。
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
WixUtilExtension.dll
的引用。<util:RemoveFolderEx On="install" Property="OldWebAPP" />
托管代码问题 :使用上述方法,您可以完全避免托管代码。托管代码遭受了许多漏洞,这些漏洞最终会显现出来-如您所见。 .NET代码的安全锁定,已加载错误的.NET运行时版本,GAC依赖问题,这是old, and overly chatty answer on the subject(可能是过时的内容,肯定是杂乱无章的“坚果”)。
自定义操作错误检查 :请注意,您还可以针对所引用的自定义操作禁用错误检查。那应该允许安装程序继续进行而不会失败。如果可以的话。不太好,但我想可能。
自定义操作抑制 :最后,如果您使用属性值对自定义操作进行条件设置,则在传递自定义属性值时可以阻止自定义操作运行通过命令行:
在MSI属性表中设置: SUPPRESSERROR = 0
。然后-在需要时-在命令行上设置:
msiexec.exe /x {PRODUCT-GUID} SUPPRESSERROR="1"
在MSI内部,您可以使用以下条件来执行卸载自定义操作:
REMOVE="ALL" AND SUPPRESSERROR="0"
现在,如果
SUPPRESSERROR
为任意值,则自定义操作将不会运行 但0
,可以通过按下custom uninstall command line
来阻止自定义操作在卸载失败的计算机上运行(请注意,自定义操作仍可以设置为检查错误。