System.IO.Directory.Delete 的异常未在 customaction 中捕获
Exception from System.IO.Directory.Delete not caught in customaction
来自 System.IO.Directory.Delete 的异常未在 customaction 中捕获(使用 wix 工具集生成的 msi)
发生在 .NET Framework 4.7.2 Windows 7 以管理员身份启动。
自定义操作调用的日志文件:
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
***** 开始删除旧安装文件夹
***** 正在删除文件夹: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>
Disclaimer: Use caution with all remove elements (files / folders). Test on virtuals only. Obviously.
MSI:您是否尝试过使用 RemoveFile table
in MSI? This is the built-in MSI table to allow deletion of files and folders as installation operations. Empty folders only. Sample.
WiX: WiX's Util namespace
中还有实用dll函数: RemoveFolderEx Element (Util Extension)
- this is WiX's own custom action written in C++ and not MSI's built-in stuff. As far as I recall you can delete folders with files using this approach. Been a while. Sample(未经测试,使用风险自负 - 显然)。
- 修改 WiX 源(顶级元素):
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
- 在 Program Files (x86) 下的主 WiX 安装文件夹中添加对
WixUtilExtension.dll
的引用。
- 使用元素:
<util:RemoveFolderEx On="install" Property="OldWebAPP" />
托管代码问题:使用上面的方法可以完全避免托管代码。托管代码存在许多漏洞,这些漏洞最终会自行显现——就像您所看到的那样。 .NET 代码的安全锁定、错误的 .NET 运行时版本加载、GAC 依赖性问题,这里是一个 old, and overly chatty answer on the subject(可能是过时的内容,肯定是混乱和 "nuts")。
自定义操作错误检查:请注意,您也可以禁用您引用的自定义操作的错误检查。这应该允许安装程序继续而不会失败。如果那是一个 acceptable 选项。不太好,但我想有可能。
Custom Action Suppression:最后,如果您使用 属性 值调节自定义操作,您可以阻止来自 运行 的自定义操作,如果您通过命令行传入自定义 属性 值:
在微星中设置属性table:SUPPRESSERROR = 0
。然后 - 需要时 - 在命令行上设置:
msiexec.exe /x {PRODUCT-GUID} SUPPRESSERROR="1"
在 MSI 中,您将卸载自定义操作设置为:
REMOVE="ALL" AND SUPPRESSERROR="0"
Now the custom action will not run if SUPPRESSERROR
is anything
but 0
, allowing you to prevent the custom action from running on machines where the uninstall is failing by pushing down a custom uninstall command line
(note that the custom action can still be set to check for errors).
来自 System.IO.Directory.Delete 的异常未在 customaction 中捕获(使用 wix 工具集生成的 msi)
发生在 .NET Framework 4.7.2 Windows 7 以管理员身份启动。
自定义操作调用的日志文件:
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 ***** 开始删除旧安装文件夹 ***** 正在删除文件夹: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>
Disclaimer: Use caution with all remove elements (files / folders). Test on virtuals only. Obviously.
MSI:您是否尝试过使用 RemoveFile table
in MSI? This is the built-in MSI table to allow deletion of files and folders as installation operations. Empty folders only. Sample.
WiX: WiX's Util namespace
中还有实用dll函数: RemoveFolderEx Element (Util Extension)
- this is WiX's own custom action written in C++ and not MSI's built-in stuff. As far as I recall you can delete folders with files using this approach. Been a while. Sample(未经测试,使用风险自负 - 显然)。
- 修改 WiX 源(顶级元素):
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
- 在 Program Files (x86) 下的主 WiX 安装文件夹中添加对
WixUtilExtension.dll
的引用。 - 使用元素:
<util:RemoveFolderEx On="install" Property="OldWebAPP" />
托管代码问题:使用上面的方法可以完全避免托管代码。托管代码存在许多漏洞,这些漏洞最终会自行显现——就像您所看到的那样。 .NET 代码的安全锁定、错误的 .NET 运行时版本加载、GAC 依赖性问题,这里是一个 old, and overly chatty answer on the subject(可能是过时的内容,肯定是混乱和 "nuts")。
自定义操作错误检查:请注意,您也可以禁用您引用的自定义操作的错误检查。这应该允许安装程序继续而不会失败。如果那是一个 acceptable 选项。不太好,但我想有可能。
Custom Action Suppression:最后,如果您使用 属性 值调节自定义操作,您可以阻止来自 运行 的自定义操作,如果您通过命令行传入自定义 属性 值:
在微星中设置属性table:SUPPRESSERROR = 0
。然后 - 需要时 - 在命令行上设置:
msiexec.exe /x {PRODUCT-GUID} SUPPRESSERROR="1"
在 MSI 中,您将卸载自定义操作设置为:
REMOVE="ALL" AND SUPPRESSERROR="0"
Now the custom action will not run if
SUPPRESSERROR
is anything but0
, allowing you to prevent the custom action from running on machines where the uninstall is failing by pushing down acustom uninstall command line
(note that the custom action can still be set to check for errors).