Может ли файл .msi установиться самостоятельно (предположительно с помощью специального действия)?

StackOverflow https://stackoverflow.com/questions/88078

  •  01-07-2019
  •  | 
  •  

Вопрос

Я хочу создать MSI, который в процессе установки будет развертываться вместе с содержащимися в нем файлами/компонентами в TargetDir.

Таким образом, MyApp.msi содержит MyApp.exe и MyAppBootstrapperEmpty.exe (без ресурсов) в своей таблице файлов.

Пользователь запускает MyAppBootstrapperPackaged.exe (содержащий MyApp.msi в качестве ресурса, полученного где-то из Интернета, по электронной почте или иным образом).MyAppBootStrapperPackaged.exe извлекает MyApp.msi во временную папку и запускает его через msiexec.exe.

После завершения процесса msiexec.exe мне нужны MyApp.msi, MyBootstrapperEmpty.exe (И MyApp.exe в папке %ProgramFiles%\MyApp, чтобы MyApp.exe мог иметь гарантированный доступ к MyApp.msi при его запуске (для создания приведенного ниже файла) упомянутый упакованный контент).

MyAppBootstrapper*.exe может попытаться скопировать MyApp.msi в папку %ProgramFiles%\MyApp, но для этого потребуется повышение прав, и он не позволит удалить его с помощью процесса удаления установщика Windows (из пункта «Установка и удаление программ» или иным образом), что должно быть сохранено.

Очевидно (я думаю, это очевидно - я ошибаюсь?) Я не могу включить MSI в качестве файла в свой Media/CAB (сценарий с курицей и яйцом), поэтому я считаю, что это нужно будет сделать с помощью специального действия перед установкой. процесс, добавляя исходный MSI в Media/CAB базы данных MSI и соответствующую запись в таблице файлов на лету.Можно ли это сделать и если да, то как?

Подумайте о модели распространения контента, в которой файлы контента должны распространяться только вместе с Приложением.Контент создается конечным пользователем через Приложение во время выполнения и упаковывается в распространяемый EXE-файл, который включает в себя как Приложение, так и контент.

Установщик MyApp должен оставаться в формате MSI, но может запускаться с помощью EXE-файла Bootstrapper.Установленный MyApp.exe должен иметь доступ как к MyApp.msi, так и к EXE. Приложение должно «собирать» во время выполнения из базового (пустого) MyAppBootstrapper.exe, который также устанавливается MSI, и содержимого, созданного конечный пользователь.Ресурс MSI EXE-файла должен быть таким же, как тот, который использовался для установки приложения, которое выполняет упаковку во время выполнения.

WIX не следует устанавливать вместе с MyApp.

Не может быть никаких сетевых зависимостей во время выполнения/упаковки (т.невозможно выполнить упаковку через веб-сервис — необходимо выполнить локально).

Я знаком (и использую) настраиваемые действия (управляемые и неуправляемые, через DTF и т. д.).

Это было полезно?

Решение

Добавьте несжатый носитель в ваш wxs следующим образом:

<Media Id='2'/>

А затем создайте компонент с элементом File следующим образом:

<File Source='/path/to/myinstaller.msi' Compressed='no' DiskId='2' />

Это заставит установщик искать файл с именем «myinstaller.msi» на установочном носителе в той же папке, что и устанавливаемый MSI.Приведенный выше исходный путь должен указывать на фиктивный файл, он нужен только для того, чтобы успокоить Wix.

Редактировать:Следующий пример test.wxs демонстрирует, что это работает.Он создает файл test.msi, который устанавливается в папку c:\program files est.Обратите внимание, что вам нужно поместить фиктивный файл test.msi в ту же папку, что и text.wxs, чтобы успокоить Wix.

<?xml version='1.0' encoding='utf-8'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
   <Product
         Name='ProductName'
         Id='*'
         Language='1033'
         Version='0.0.1'
         Manufacturer='ManufacturerName' >
      <Package
            Keywords='Installer'
            Description='Installer which installs itself'
            Manufacturer='ManufactererName'
            InstallerVersion='100'
            Languages='1033'
            Compressed='yes'
            SummaryCodepage='1252'/>

      <Media Id='1' Cabinet='test.cab' EmbedCab='yes'/> 
      <Media Id='2' /> 

      <Directory Id='TARGETDIR' Name="SourceDir">
         <Directory Id='ProgramFilesFolder'>
            <Directory Id='TestFolder' Name='Test' >
               <Component Id="InstallMyself">
                  <File Source="./test.msi" Compressed="no" DiskId="2" />
               </Component>
            </Directory>
         </Directory>
      </Directory>

      <Feature
            Id='Complete'
            Display='expand'
            Level='1'
            Title='Copy msi file to program files folder'
            Description='Test'>

         <ComponentRef Id="InstallMyself" />
      </Feature>

   </Product>
</Wix>

Другие советы

Запуск одного пакета .MSI «изнутри» другого пакета .MSI называется вложенная установка, И его плохое джуджу (см. Правило 20).Установщик Windows имеет некоторые глобальные данные, которые он использует для управления текущей установкой, и он плохо справляется с несколькими установками одновременно.По той же причине, если вы запустите одну установку, а затем попытаетесь запустить другую, пока первая еще выполняется, вы обычно увидите всплывающее окно с сообщением «идет еще одна установка, подождите, пока она не завершится».

У вас может быть программа, обычно называемая загрузчиком (думаю, вы имеете в виду именно это), которая сама по себе не является установочным пакетом, но содержит установочный пакет (например, .MSI или .EXE) в качестве ресурса, возможно, в сжатом виде.Действие программы-загрузчика заключается в извлечении/расширении ресурса в файл, обычно в виде файла. %TEMP% каталог, затем либо запустите извлеченный .EXE, либо запустите MSIEXEC для извлеченного .MSI.Загрузчик может содержать несколько ресурсов и извлекать и устанавливать их один за другим, если вам нужно установить необходимые компоненты перед основным пакетом.Или вы можете отправить несколько пакетов в виде отдельных файлов и позволить загрузчику выполнить/установить их непосредственно с дистрибутивного носителя один за другим, или скопировать их на целевой компьютер и запустить серию установок оттуда, или...

Сам WiX не устанавливается, нет.Это инструмент, с помощью которого можно создавать пакеты .MSI.В списке пожеланий проекта WiX есть универсальная программа-загрузчик, но она еще не реализована.Доступны и другие загрузчики, например. Вот этот.

Вам не понадобится специальное действие — фактически, поскольку загрузчик сам по себе не является установочным пакетом установщика Windows, «настраиваемое действие» не имеет для него никакого значения.И если вы достаточно знакомы с центрами сертификации, чтобы знать об управляемых/неуправляемых/DTF, то вы знаете достаточно, чтобы избегать настраиваемых действий, когда это возможно.(ухмылка)

Я думаю, что вашему загрузчику гораздо проще извлечь файл MSI в какое-то заранее определенное место, а не во временную папку.Например, в C:\Documents and Settings\All Users\Application Data\My Company\My Product Install Cache.После завершения установки загрузчик оставит файл MSI там.Если на каком-то этапе пользователь решит переустановить ваш продукт, установщик Windows сможет найти исходный файл MSI.

Также добавьте путь к этому файлу в Таблица удаления файлов чтобы он удалялся при удалении.Вы можете использовать Элемент RemoveFile в WiX для этого.

Итак, если я понимаю, то я думаю, что мне нужно, чтобы приложение создало преобразование (MST), содержащее файлы содержимого, и применило его к базовому MSI.Хотя я до сих пор не уверен, что понимаю.:)

Я бы настроил путь к кэшу MSI в известное место.

Затем во время выполнения, если вам нужно «отредактировать» MSI, используйте VBScript или аналогичный.

Но все же я спрашиваю ПОЧЕМУ!?!

Я также работаю над способом развертывания нескольких файлов MSI.У меня есть программа bootstrapper.exe, которая объединяет файлы MSI и запускает их по одному.Это решает мою проблему в большинстве случаев.

Случай, который он не решает, — это распространение установки GPO (объект глобальной политики).Для запуска установки GPO требуется файл dot-msi.

Для этого я сделал вот что, что почти решило проблему (но не совсем).Я помещаю файлы dot-msi в таблицу файлов установщика, помещаю свой загрузчик в двоичную таблицу и запускаю его из специального действия, вставленного после InstallFinalize в InstallExecuteSequence.Конечно, загрузчик не сможет запускать другие MSI, поскольку MSI верхнего уровня содержит мьютекс _MSIExecute.

Пройти немного дальше было довольно легко.Я заставил загрузчик вернуть управление установщику верхнего уровня и продолжить.Затем я добавил вызов WaitForSingleObject, чтобы дождаться завершения установки верхнего уровня, после чего загрузчик сможет продолжить завершение установки.

Моя проблема заключается в том, что установка объекта групповой политики происходит во время загрузки, а установка верхнего уровня завершается до завершения работы дополнительных установщиков, и объект групповой политики перезагружает компьютер.

Установка верхнего уровня также возвращает статус успеха, если в дальнейшем установка может фактически завершиться неудачей.

Я все еще ищу способ заблокировать завершение установки верхнего уровня до тех пор, пока не завершится загрузчик.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top