为什么在 Wix 中设置 KeyPath 时文件会被覆盖
Why file get overwritten when KeyPath is set in Wix
热生成的Files.wxs片段:
<?xml version="1.0" encoding="utf-8"?>
<Wix
xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="INSTALLFOLDER">
<Directory Id="dirF5D9BDF13CBC346EDDFD6D0959FFB838" Name="config">
<Component Id="cmp0CBEDCE6B62E5666B3362D0EB41267BC" Guid="*">
<File Id="fil73D1987B7864F07C97735D7E40243AB2" KeyPath="yes"
Source="$(var.App.TargetDir)\config\accounts-example.ini" />
</Component>
</Component>
</Directory>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="Binaries">
<ComponentRef Id="cmp0CBEDCE6B62E5666B3362D0EB41267BC" />
</ComponentGroup>
</Fragment>
</Wix>
Product.wxs:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
<Product Id="*" Name="xxx" Language="2052" Version="$(var.ProductVersion)" Manufacturer="xxx"
UpgradeCode="425BDA6F-31B8-47AD-88D8-4B2DBE394XXX">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade AllowSameVersionUpgrades="yes" DowngradeErrorMessage="New Version [ProductName] has been installed。" />
<MediaTemplate EmbedCab="yes" />
<WixVariable Id="WixUILicenseRtf" Value="./License.rtf" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MANUFACTURERFOLDER" Name="!(bind.property.Manufacturer)">
<Directory Id="INSTALLFOLDER" Name="!(bind.property.ProductName)" />
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="!(bind.property.ProductName)" />
<Directory Id="DesktopFolder" Name="Desktop" />
</Directory>
</Directory>
<Feature Id="ProductFeature" Title="XXX_Installer" Level="1">
<ComponentGroupRef Id="Binaries" />
<ComponentRef Id="ApplicationShortcut" />
<ComponentRef Id="ApplicationShortcutDesktop" />
<ComponentRef Id="RegistryEntries" />
</Feature>
<UIRef Id="WixUI_ErrorProgressText" />
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
<UIRef Id="WixUI_InstallDir" />
<DirectoryRef Id="ApplicationProgramsFolder">
<Component Id="ApplicationShortcut" Guid="E1F61345-CC60-40FE-8FC4-FBE1598F8XXX">
<Shortcut Id="ApplicationStartMenuShortcut"
Name="!(bind.property.ProductName)"
Description="!(bind.property.ProductName)"
Target="[INSTALLFOLDER]XXX_App.exe"
WorkingDirectory="INSTALLFOLDER" />
<RemoveFolder Id="ApplicationProgramsFolder" On="uninstall" />
<RegistryValue Root="HKCU" Key="Software\Microsoft\!(bind.property.ProductName)" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
</DirectoryRef>
<DirectoryRef Id="DesktopFolder">
<Component Id="ApplicationShortcutDesktop" Guid="BEDF111F-0889-4317-8E67-41425F00CXXX">
<Shortcut Id="ApplicationDesktopShortcut"
Name="!(bind.property.ProductName)"
Description="!(bind.property.ProductName)"
Target="[INSTALLFOLDER]XXX_App.exe"
WorkingDirectory="INSTALLFOLDER" />
<RemoveFolder Id="DesktopFolder" On="uninstall" />
<RegistryValue Root="HKCU" Key="Software\Microsoft\!(bind.property.ProductName)" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
</DirectoryRef>
<DirectoryRef Id="TARGETDIR">
<Component Id="RegistryEntries" Guid="0D919675-E219-43EA-AAB3-E6F81A013XXX">
<RegistryKey Root="HKCU"
Key="Software\Microsoft\Windows\CurrentVersion\Run">
<RegistryValue Name="!(bind.property.ProductName)"
Type="string"
Value="[INSTALLFOLDER]XXX_App.exe"/>
</RegistryKey>
</Component>
</DirectoryRef>
<UI>
<Publish Dialog="ExitDialog"
Control="Finish"
Event="DoAction"
Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
</UI>
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="启动!(bind.property.ProductName)" />
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX" Value="1" />
<Property Id="WixShellExecTarget" Value="[INSTALLFOLDER]XXX_App.exe" />
<CustomAction Id="LaunchApplication"
BinaryKey="WixCA"
DllEntry="WixShellExec"
Impersonate="yes" />
</Product>
</Wix>
每次安装新版本都会覆盖已有的文件accounts-example.ini.
帐户的覆盖行为是预期的-example.ini,但我将有另一个文件user.db不想被覆盖。
它说如果 KeyPath 设置为 'yes' 那么它不会覆盖现有文件,不是吗?我如何配置 Wix 以覆盖一个文件而不覆盖另一个文件?
关于KeyPath的一些文章:
what-is-the-wix-keypath-attribute
copy-if-not-exist-in-wix
如果您使用主要升级元素执行此操作,您需要告诉我们它的预定位置。如果是 "early"(比如 afterInstallInitialize),那么所有的东西都会先卸载,然后安装新的升级,安装的每个文件都来自新的升级。如果它按顺序排列 "late"(例如 afterInstallExecute),则覆盖规则适用(例如 https://msdn.microsoft.com/en-us/library/windows/desktop),这是因为升级基本上是在现有文件上安装每个文件。
请注意 MajorUpgrade 计划的 WiX 默认值是在安装验证之后,因此正如我所描述的(以及 WiX 文档所说)将首先卸载整个旧产品(显然是删除所有文件),然后所有新文件将被卸载安装。
在此处查看时间表:
http://wixtoolset.org/documentation/manual/v3/xsd/wix/majorupgrade.html
WiX 密钥路径 link 的解释还有很多不足之处。说如果组件存在 none 其资源将被安装是不正确的。我不清楚这是什么意思,因为将应用覆盖规则。
就您的数据文件而言,如果它们在安装后已更新,则不会被传入文件覆盖。所以很可能你的ini文件被覆盖了,因为它没有被改变。如果你的数据库已经更新,那么它不会被替换,但是,同样,当你的主要升级是 "late"(或者它是一个补丁)时,这是覆盖规则。
热生成的Files.wxs片段:
<?xml version="1.0" encoding="utf-8"?>
<Wix
xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="INSTALLFOLDER">
<Directory Id="dirF5D9BDF13CBC346EDDFD6D0959FFB838" Name="config">
<Component Id="cmp0CBEDCE6B62E5666B3362D0EB41267BC" Guid="*">
<File Id="fil73D1987B7864F07C97735D7E40243AB2" KeyPath="yes"
Source="$(var.App.TargetDir)\config\accounts-example.ini" />
</Component>
</Component>
</Directory>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="Binaries">
<ComponentRef Id="cmp0CBEDCE6B62E5666B3362D0EB41267BC" />
</ComponentGroup>
</Fragment>
</Wix>
Product.wxs:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
<Product Id="*" Name="xxx" Language="2052" Version="$(var.ProductVersion)" Manufacturer="xxx"
UpgradeCode="425BDA6F-31B8-47AD-88D8-4B2DBE394XXX">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade AllowSameVersionUpgrades="yes" DowngradeErrorMessage="New Version [ProductName] has been installed。" />
<MediaTemplate EmbedCab="yes" />
<WixVariable Id="WixUILicenseRtf" Value="./License.rtf" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MANUFACTURERFOLDER" Name="!(bind.property.Manufacturer)">
<Directory Id="INSTALLFOLDER" Name="!(bind.property.ProductName)" />
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="!(bind.property.ProductName)" />
<Directory Id="DesktopFolder" Name="Desktop" />
</Directory>
</Directory>
<Feature Id="ProductFeature" Title="XXX_Installer" Level="1">
<ComponentGroupRef Id="Binaries" />
<ComponentRef Id="ApplicationShortcut" />
<ComponentRef Id="ApplicationShortcutDesktop" />
<ComponentRef Id="RegistryEntries" />
</Feature>
<UIRef Id="WixUI_ErrorProgressText" />
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
<UIRef Id="WixUI_InstallDir" />
<DirectoryRef Id="ApplicationProgramsFolder">
<Component Id="ApplicationShortcut" Guid="E1F61345-CC60-40FE-8FC4-FBE1598F8XXX">
<Shortcut Id="ApplicationStartMenuShortcut"
Name="!(bind.property.ProductName)"
Description="!(bind.property.ProductName)"
Target="[INSTALLFOLDER]XXX_App.exe"
WorkingDirectory="INSTALLFOLDER" />
<RemoveFolder Id="ApplicationProgramsFolder" On="uninstall" />
<RegistryValue Root="HKCU" Key="Software\Microsoft\!(bind.property.ProductName)" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
</DirectoryRef>
<DirectoryRef Id="DesktopFolder">
<Component Id="ApplicationShortcutDesktop" Guid="BEDF111F-0889-4317-8E67-41425F00CXXX">
<Shortcut Id="ApplicationDesktopShortcut"
Name="!(bind.property.ProductName)"
Description="!(bind.property.ProductName)"
Target="[INSTALLFOLDER]XXX_App.exe"
WorkingDirectory="INSTALLFOLDER" />
<RemoveFolder Id="DesktopFolder" On="uninstall" />
<RegistryValue Root="HKCU" Key="Software\Microsoft\!(bind.property.ProductName)" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
</DirectoryRef>
<DirectoryRef Id="TARGETDIR">
<Component Id="RegistryEntries" Guid="0D919675-E219-43EA-AAB3-E6F81A013XXX">
<RegistryKey Root="HKCU"
Key="Software\Microsoft\Windows\CurrentVersion\Run">
<RegistryValue Name="!(bind.property.ProductName)"
Type="string"
Value="[INSTALLFOLDER]XXX_App.exe"/>
</RegistryKey>
</Component>
</DirectoryRef>
<UI>
<Publish Dialog="ExitDialog"
Control="Finish"
Event="DoAction"
Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
</UI>
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="启动!(bind.property.ProductName)" />
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX" Value="1" />
<Property Id="WixShellExecTarget" Value="[INSTALLFOLDER]XXX_App.exe" />
<CustomAction Id="LaunchApplication"
BinaryKey="WixCA"
DllEntry="WixShellExec"
Impersonate="yes" />
</Product>
</Wix>
每次安装新版本都会覆盖已有的文件accounts-example.ini.
帐户的覆盖行为是预期的-example.ini,但我将有另一个文件user.db不想被覆盖。
它说如果 KeyPath 设置为 'yes' 那么它不会覆盖现有文件,不是吗?我如何配置 Wix 以覆盖一个文件而不覆盖另一个文件?
关于KeyPath的一些文章:
what-is-the-wix-keypath-attribute
copy-if-not-exist-in-wix
如果您使用主要升级元素执行此操作,您需要告诉我们它的预定位置。如果是 "early"(比如 afterInstallInitialize),那么所有的东西都会先卸载,然后安装新的升级,安装的每个文件都来自新的升级。如果它按顺序排列 "late"(例如 afterInstallExecute),则覆盖规则适用(例如 https://msdn.microsoft.com/en-us/library/windows/desktop),这是因为升级基本上是在现有文件上安装每个文件。
请注意 MajorUpgrade 计划的 WiX 默认值是在安装验证之后,因此正如我所描述的(以及 WiX 文档所说)将首先卸载整个旧产品(显然是删除所有文件),然后所有新文件将被卸载安装。
在此处查看时间表:
http://wixtoolset.org/documentation/manual/v3/xsd/wix/majorupgrade.html
WiX 密钥路径 link 的解释还有很多不足之处。说如果组件存在 none 其资源将被安装是不正确的。我不清楚这是什么意思,因为将应用覆盖规则。
就您的数据文件而言,如果它们在安装后已更新,则不会被传入文件覆盖。所以很可能你的ini文件被覆盖了,因为它没有被改变。如果你的数据库已经更新,那么它不会被替换,但是,同样,当你的主要升级是 "late"(或者它是一个补丁)时,这是覆盖规则。