2016-01-15 4 views
0

У меня есть пакет WiX с двумя пакетами msi: A и B. Сначала я успешно установил пакет версии 1.0.0.0. Затем я устанавливаю MajorUpgrade версии 2.0.0.0. Пакет успешно обновлен. Не удалось выполнить обновление пакета B и начался откат.Откат к предыдущей версии установщика пакетов WiX

Я определил Msi обновление пакета, как: <MajorUpgrade AllowSameVersionUpgrades="yes" Schedule="afterInstallInitialize" DowngradeErrorMessage="A newer version of [ProductName] is already installed." />

Пакет B вернулся к версии 1.0.0.0. Пакет Рулон, удаленный. Итак, пучок остается в противоречивом состоянии.

Мне нужно вернуть весь пакет до версии 1.0.0.0, если обновление не выполнено. Является ли это возможным?

+0

я нашел дискуссию по этому же вопросу: [здесь] (http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/ Bootstrapper-multiple-MSI-s-don-t-rollback-to-a-work-installed-state-td7586867.html) и [здесь] (http: //windows-installer-xml-wix-toolset.687559. n2.nabble.com/Installl-upgrade-several-MSIs-in-one-single-transaction-td7495903.html) Это требует транзакций Multi-MSI, которые в настоящее время не поддерживаются WiX. –

ответ

1

Нет стандартного способа его выполнения, поскольку транзакции с несколькими MSI не поддерживаются WiX.

Я нашел обходное решение, которое работает для меня. Я использую Custom Bootstrapper Application, поэтому я могу обработать событие сбоя в коде C#. Если вы используете приложение WiX Standard Bootstrapper Application (WiXStdBA), это не поможет вам.

Если обновление не удалось, я вызываю предыдущий установщик пакетов из кэша пакетов Windows в режиме молчания. Он восстанавливает предыдущее состояние.

Следующий код выражает идею:

Bootstrapper.PlanRelatedBundle += (o, e) => { PreviousBundleId = e.BundleId; }; 

Bootstrapper.ApplyComplete += OnApplyComplete; 

private void OnApplyComplete(object sender, ApplyCompleteEventArgs e) 
{ 
    bool updateFailed = e.Status != 0 && _model.InstallationMode == InstallationMode.Update; 
    if (updateFailed) 
    { 
     var registryKey = string.Format("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{0}", VersionManager.PreviousBundleId); 
     RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(registryKey) 
      ?? RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64).OpenSubKey(registryKey); 

     if (key != null) 
     { 
      string path = key.GetValue("BundleCachePath").ToString(); 
      var proc = new Process(); 
      proc.StartInfo.FileName = path; 
      proc.StartInfo.Arguments = "-silent -repair"; 
      proc.Start(); 
      proc.WaitForExit(); 
     } 
    } 
} 
Смежные вопросы