强制升级在初始安装期间修改的文件

时间:2009-09-16 10:52:53

标签: wix windows-installer upgrade

我正在为基于WiX的安装程序进行升级功能。

作为安装的一部分,我们正在安装web.config文件,然后使用自定义操作更新文件中的连接字符串。

但是,当我们运行升级时,这会导致问题。我们希望在InstallFinalize之后安排RemoveExistingProducts,因为这在不删除和重新安装未更改的文件方面效率最高。但是,当Windows Installer尝试确定是否应该更新它时,这会留下原始的web.config文件。由于它的上次修改日期比其创建日期更新,因此Windows Installer决定不更新它(请参阅Windows Installer使用的versioning rules)。但是我们需要更新它。

一个明显的解决方案是将RemoveExistingProducts的调度更改为InstallValidate之后 - 但这样效率很低,而且,我认为如果我们需要这样做,我认为它不会让我们有机会从现有文件迁移设置。

还有其他想法吗?

3 个答案:

答案 0 :(得分:16)

有许多方法 - 没有一种是理想的。

1:您可以使用随播广告强制更新相关文件。如果指定的伴随文件始终更新,这可能是要走的路。实质上,这意味着您将非版本化文件链接到其配套文件的版本更新逻辑(文件一起更新)。我从来没有在WIX中使用它,但我认为它就像将 CompanionFile属性添加到File元素并指向要“版本跟随”的文件的ID一样简单。在MSI文件中,它看起来像这样:

enter image description here

2:您可以在文件成本核算之前使用自定义操作删除文件(或者更好,将其重命名为备份格式)。问题是如果安装失败,文件将丢失。如果重命名文件而不是删除,则可以将其放回,以防通过回滚自定义操作设置失败。有时我使用RemoveFile表来删除安装时的文件,但是根据InstallExecuteSequence中指定的顺序,这可能不起作用(删除必须在msi进行文件成本核算之前进行)。

3:然后有大锤方法:设置 REINSTALLMODE = amus 强制覆盖所有文件,无论版本如何。我甚至不应该提到它,因为它非常危险(你最终可能会覆盖系统文件,或者在较新的Windows版本上会因为文件受到保护而触发一个讨厌的运行时错误)。仅用于开发测试,并不认为它是一个快速修复。它导致的问题多于解决的问题。

作为变体,可接受的方法可能是将 REINSTALLMODE设置为emus (替换旧的和相同的版本文件)。如果您不想增加版本号但继续重建二进制文件,这可能会有所帮助 - 就像很多.NET中的情况一样。我的猜测是,这会导致一系列全新的问题 - 最明显的二进制不同但版本相同的文件如果您将其用于公开发布 - 部署气味如果有的话。作为仅限QA / DEV的方法,它可以工作。但说真的,为什么要这么麻烦?只需自动增加二进制文件的构建版本,就可以可靠地解决问题。


<强> 链接

答案 1 :(得分:1)

仅限于那些。您可以通过自定义操作尽早删除特定文件,但请务必正确处理!或者您可以为文件指定一个版本,因此升级规则会将其视为将版本化的文件替换为非版本化文件,但补丁程序可能会因为该文件的版本错误而感到烦恼。

答案 2 :(得分:0)

另一个明显的想法是不使用自定义操作来更新您的配置文件。而是让WIX通过XML扩展名进行更新。例如

<Component Id="web.config" Guid="f12ff575-ad5f-47bc-a5c9-40b1e3a7f9f5" >
    <File Source="$(var.SrcPath)\web.config.config" KeyPath="yes" />

    <util:XmlConfig Id="AppSqlInstanceName"
                    File="[#web.config]"
                    Action="create"
                    ElementPath="//configuration/connectionStrings/add[\[]@name='YourStringKey'[\]]"
                    Name="connectionString"
                    Node="value"
                    Value="metadata=res://*/YourModel.csdl|res://*/YourModel.ssdl|res://*/YourModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=[SQLSERVERANDINSTANCE];initial catalog=DatabaseName;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;"
                    On="install"/>
</Component>

这是使用[SQLSERVERANDINSTANCE]变量,需要先进行设置。