Wix删除卸载的文件



我们有一个office插件,它与wix中创建的msi一起安装。msi与公司范围内的安装工具一起在人们可能打开办公室的时候静默部署。

我们遇到的问题是,并不是所有的dll都将在插件运行时加载,而是在第一次使用时按要求运行。如果安装程序运行,它将在后台替换已卸载的dll,如果应用程序稍后尝试加载它们,则文件/s将不存在,从而导致崩溃。

步骤:

  1. 插件版本1加载,使用版本1编译的dll
  2. 用户正在使用插件,但dll版本1未加载
  3. 开始自动安装,将dll版本1替换为版本2
  4. 用户仍在使用版本1的插件,但他们现在使用需要dll的功能。
  5. 插件试图加载dll版本1,但找不到文件,插件崩溃
  6. 用户重新启动,加载版本2的插件和版本2的dll,一切正常

是否有一种方法在wix说不替换一个dll如果所有的文件不能被替换?或者是否有已知的方法来解决这个问题?

这种情况称为"撕裂状态"。这通常是因为一个重启请求被忽略了。

在这种情况下,通常addin v2 dll不会取代addin v1 dll,因为v1正在使用中,需要重新启动。由于我们成功替换了未使用的支持dll,系统在重新启动之前是不稳定的。

检测这种情况可以绕过,如果外接程序被影子复制,允许所有的文件被替换而不需要重新启动。

对于撕裂状态,除了主动释放插件(通过要求任何主机进程停止)和阻止安装或强制重启(如果不可能)之外,没有一个很好的解决方案。CloseAppRestartResource元素可以在这里提供帮助。

替代方案(MSI不支持)是使用事务文件系统操作。不幸的是,这在现实中行不通(在Windows Longhorn/Vista中尝试过,结果是一场灾难)。或者实现"热补丁";其中加载的v1插件的代码在内存中更新为v2。但我认为MSI也不支持(而且它在技术上使用起来非常具有挑战性)。