System.IO.Directory.Delete中的异常未在customaction中捕获

时间:2019-03-28 10:48:34

标签: .net exception wix custom-action

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>

1 个答案:

答案 0 :(得分:1)

  

免责声明 :请谨慎使用所有删除元素(文件/文件夹)。仅在虚拟机上测试。显然。


MSI :您是否尝试过在MSI中使用RemoveFile table?这是内置的MSI表,允许删除文件和文件夹作为安装操作。仅空文件夹。 Sample

WiX WiX's Util namespace 中还有实用程序dll函数:RemoveFolderEx Element (Util Extension)-这是WiX自己的使用C ++编写的自定义操作,而不是MSI的内置内容。据我所知,您可以使用此方法删除包含文件的文件夹。已经有一段时间。 Sample(未经测试,使用后果自负-显然)。

  • 修改WiX源(顶级元素): <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
  • 在程序文件(x86)下的WiX主安装文件夹中添加对 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 来阻止自定义操作在卸载失败的计算机上运行(请注意,自定义操作仍可以设置为检查错误。