Защо файлът се презаписва, когато KeyPath е зададен в 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.

Поведението при презаписване се очаква за accounts-example.ini, но ще имам друг файл user.db, който не иска да бъде презаписан.

Пише, че ако KeyPath е настроен на „да“, тогава той не презаписва съществуващия файл, нали? Как мога да конфигурирам Wix да презаписва един файл и да не презаписва друг?


Някои статии за KeyPath:

what-is-the-wix-keypath-attribute

copy-if-not-exist-in-wix


person user1633272    schedule 19.03.2017    source източник


Отговори (1)


Ако правите това с основен елемент за надграждане, трябва да ни кажете къде е планирано. Ако е „ранно“ (като afterInstallInitialize), тогава всичко ще бъде деинсталирано първо и след това новата надстройка ще бъде инсталирана и всеки файл, който е инсталиран, ще бъде от новата надстройка. Ако е подредено „късно“ (като afterInstallExecute), тогава се прилагат правилата за презаписване (като това https://msdn.microsoft.com/en-us/library/windows/desktop) и това е така, защото надстройката основно инсталира всеки файл върху съществуващите файлове.

Имайте предвид, че WiX по подразбиране за графика на MajorUpgrade е afterInstallValidate, така че както описах (и както се казва в документацията на WiX) целият по-стар продукт първо ще бъде деинсталиран (очевидно премахване на всички файлове), след което всички нови файлове ще бъдат инсталирани.

Вижте графика тук:

http://wixtoolset.org/documentation/manual/v3/xsd/wix/majorupgrade.html

Обяснението на връзката към WiX keypath оставя много да се желае. Не е вярно да се каже, че ако компонентът присъства, нито един от неговите ресурси няма да бъде инсталиран. Не ми е ясно какво означава това, защото ще се прилагат правилата за презаписване.

Що се отнася до вашите файлове с данни, те няма да бъдат презаписани от входящ файл, ако са били актуализирани след инсталирането им. Така че е вероятно вашият ini файл да бъде презаписан, защото не е бил променен. Ако вашата база данни е била актуализирана, тогава тя няма да бъде заменена, но, отново, това са правила за презаписване, когато основната ви надстройка е „закъсняла“ (или е корекция).

person PhilDW    schedule 19.03.2017
comment
Току-що добавих Product.wxs в темата. Промених инсталирания файл и след това преинсталирах инсталатора, файлът беше презаписан. - person user1633272; 20.03.2017
comment
Вижте моя разширен отговор. Това всъщност не презаписва файла. Току-що сте планирали основната надстройка, за да премахнете първо всички файлове и след това да инсталирате новите. Все едно сте деинсталирали ръчно стария продукт и след това сте инсталирали новия. - person PhilDW; 20.03.2017
comment
Как да избегнем това? Имам предвид презаписване на един файл, но не и за друг. - person user1633272; 21.03.2017
comment
Надстройката трябва да бъде планирана след Installexecute, след което се прилагат правилата за презаписване. Както гласят правилата, файл с данни няма да бъде презаписан, ако е бил актуализиран след инсталирането му, така че модифициран DB или ini файл няма да бъде презаписан. Ini файлът актуализиран ли е след инсталирането? Използвате ли файлов хеш за файлове с данни въз основа на MSI файловия хеш? Не е ясно дали искате да презапишете ini файла, защото смятате, че това е правилното нещо, дори ако вашият ini файл за надстройка е идентичен. - person PhilDW; 21.03.2017
comment
Благодаря. Аз всъщност не презаписвам ini файла, просто презаписвам xxx-template.ini, действителният ini първоначално се генерира от template.ini. Аз съм начинаещ в WiX, така че не знам как да „планирам надграждане след Installexecute“. Някаква връзка или документ мога ли да прочета? - person user1633272; 21.03.2017
comment
връзката е добавена към моя отговор - person PhilDW; 21.03.2017