我们软件以前版本的安装程序包含一个 NOT 标有Permanent="Yes"
的组件文件。现在,我们希望在升级过程中读取此文件的升级前内容,这将覆盖具有不同内容的文件。有没有办法做到这一点?
答案 0 :(得分:1)
如果你确切地说你正在做什么会导致文件被覆盖,那将会有所帮助。一些主要的升级(你正在做什么?)将首先完全卸载产品,然后完整安装新产品。如果出现这种情况,则使用在RemoveExistingProducts之前排序的自定义操作将文件备份到某处,以便您的应用程序可以检索内容,或者在其被覆盖之前获取所需的内容。
如果您正在进行稍后排序的主要升级(例如afterInstallExecute)或者您正在执行修补程序,则无法确定该文件是否会被覆盖,因为文件覆盖规则不会替换自上次更新的文件它已安装。如果应用程序更改了文件,则此类升级不会覆盖它:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa370531(v=vs.85).aspx
或者,如果文件自安装后未更改,请更改日期以使其显示为已修改,如下所述:
还不清楚永久=是你想要的 - 这会将文件永久粘贴到系统上。您可能正在考虑NeverOverwrite,但如果应用程序更改文件通常不需要它,并且更容易在升级时决定(通过更改日期)而不是承诺NeverOverwrite,当它有时不清楚是什么产品可能在将来需要。
评论指的是在升级期间检索产品的先前版本。有很多方法可以做到这一点:
如果你知道以前版本的ProductCode,MsiGetProductInfo(以及脚本等中的等价物)将返回产品版本值或字符串:
https://msdn.microsoft.com/en-us/library/aa370130(v=vs.85).aspx
或者,如果您不想对该值进行硬编码,则传递UpgradeCode的MsiEnumProducts将返回已安装的ProductCodes列表。如果您有自己的引导程序或UI,您希望向用户显示当前安装的版本,则此技术非常有用。
在WiX主要升级中,关联属性(WIX_UPGRADE_DETECTED)是检测到的ProductCodes列表(通常是一个列表),因此您可以使用它来获取正在升级的产品的版本。在一个小的vbscript示例中,类似于:
set installer = CreateObject(" WindowsInstaller.Installer")
和
prodversionstring = installer.productinfo(WIX_UPGRADE_DETECTED," VersionString")
会让你走近。
答案 1 :(得分:0)
假设这个文件是一个配置文件,比如XML文件,我发现这只是Windows Installer的一个难点。您发送文件版本1,最终用户修改某些属性,然后您发送要保留这些自定义项的文件版本2。
问题是这是一个非常复杂的合并。如果您只关心1-2个属性,它可以正常工作但如果答案是我需要保留所有这些属性,那么您将在丢失所有自定义项或从文件的第2版获取更改之间陷入困境。
您可以在安装程序中编写大量自定义操作来执行所有操作,但我建议有更好的方法:有2个文件。
安装程序所拥有的1个文件,可以随时安全地覆盖,并且存储由覆盖的应用程序拥有的1个文件。可以将其视为转换文件。安装程序不知道该文件,因此它永远不会覆盖或删除它。 (从MSI角度定义用户数据。)
例如.NET框架Web.Config架构AppSettings element有一个文件属性,旨在很好地支持它。
指定包含custom的外部文件的相对路径 应用配置设置。指定的文件包含 在和中指定的相同类型的设置 元素并使用与那些相同的键/值对格式 元素。指定的路径相对于主配置 文件。对于Windows窗体应用程序,这将是二进制文件夹 (例如/ bin / debug),而不是应用程序的位置 配置文件。对于Web窗体应用程序,路径是相对的 到web.config文件所在的应用程序根目录。
请注意,如果指定的文件可以,运行时将忽略该属性 找不到。