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

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

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

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

还有其他想法吗?

有帮助吗?

解决方案

方法有很多,但没有一种是理想的。

1:您可以使用 伴随文件 强制更新有问题的文件。如果指定的伴随文件始终得到更新,这可能是可行的方法。本质上,这意味着您将非版本化文件链接到其伴随文件的版本更新逻辑(文件一起更新)。我从未在 WIX 中使用过这个,但我认为这就像添加 伴侣文件属性 到 File 元素并指向您想要“版本遵循”的文件的 ID。在 MSI 文件中,它看起来像这样:

enter image description here

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

3:然后有 大锤法: :放 重新安装模式 = amus 强制覆盖所有文件,无论版本如何。我什至不应该提及这一点,因为它非常危险(您最终可能会覆盖系统文件,或者在较新的 Windows 版本上触发令人讨厌的运行时错误,因为文件受到保护)。仅将其用于开发测试,并且不要认为这是一个快速解决方案。它造成的问题多于它解决的问题。

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


链接:

其他提示

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

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

<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]变量,需要事先设置。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top