Всем здоровья, а мне нужна помощь
Необходимо написать инсталлятор на WiX так, чтобы из-одного и того же пакета устанавливались две различные компоненты.
Выбор компонент в принципе можно реализовать через GroupButtons или ComboBox, а вот что прописывать в Features?
Как я понял если я буду работать через Level (например для одного компонента INSTALLEVEL=2, а для другого INSTALLEVEL=3), то получу штангу —
при выборе компонента с INSTALLEVEL=3 все равно будет утанавливаться компонент с INSTALLEVEL=2.
Кто поможет? В принципе интересует только обработка выбора компонет для инсталляции, все остальное готово.
Здравствуйте, v0lev, Вы писали:
V>Всем здоровья, а мне нужна помощь
V>Необходимо написать инсталлятор на WiX так, чтобы из-одного и того же пакета устанавливались две различные компоненты.
V>Выбор компонент в принципе можно реализовать через GroupButtons или ComboBox, а вот что прописывать в Features?
V>Как я понял если я буду работать через Level (например для одного компонента INSTALLEVEL=2, а для другого INSTALLEVEL=3), то получу штангу —
V>при выборе компонента с INSTALLEVEL=3 все равно будет утанавливаться компонент с INSTALLEVEL=2.
V>Кто поможет? В принципе интересует только обработка выбора компонет для инсталляции, все остальное готово.
1) На диалоге выбора с чекбоксиками, выбираются Features а не Components.
2) INSTALLLEVEL нужен для того, чтобы без выбора фич можно юыло поставить ту или иную конфигурацию. Чаще всего это typical/full install. Можно сказать, это параметр, который определяет стартовый набор помеченных крыжечками чекбоксов на этом диалоге или набор фич при установке по умолчанию без диалогов (silent mode) и специальных параметров командной строки.
Так что, группируйте по фичам, а не по компонентам. Компонент — это своего рода минимальная единица инсталляции в пакете (не совсем гранула, но можно сказать и гранула, все зависит от того, с какой стороны смотреть). Если у вас планируются Upgrade без переустановки всего пакета, то советую почитать про разницу между ними повнимательнее.
Успехов!
Здравствуйте, WPooh, Вы писали:
WP>1) На диалоге выбора с чекбоксиками, выбираются Features а не Components.
Все правильно, именно Features я и назвал компонентами — моя ошибка в терминологии.
Вот что имеем:
<Directory ...>
<Component Id="WstComponent" ... >
<File Id="File1_1" ... />
<File Id="File1_2" ... />
</Component>
</Directory>
<Directory ...>
<Component Id="SrvComponent" ... >
<File Id="File2_1" ... />
<File Id="File2_2" ... />
...
</Component>
</Directory>
Как видно из кода — две различные компоненты: для установки на сервер и на рабочую станцию. Далее прописываем фичи — для каждой фичи свой компонент:
<Feature Id="ServerInstall" Description="SRVR Components." Level="1" Title="SRVR" >
<ComponentRef Id="SrvComponent" />
</Feature>
<Feature Id="WStationInstall" Description="WS Components." Level="1" Title="WS" >
<ComponentRef Id="WstComponent" />
</Feature>
Только мое предложение не CheckBox, а RadioButtonGroup, которая лежит на форме фыбора типа инсталляции:
<UI>
<RadioButtonGroup Property="TpInstall">
<RadioButton Text="To server" Value="Server" ... />
<RadioButton Text="To workstation" Value="WStation" ... />
</RadioButtonGroup>
<Dialog Id="SelectTpInstall" ...>
<Control Id="ButtonsTpInstall" Type="RadioButtonGroup" Property="TpInstall" />
</Dialog>
</UI>
Как видно их кода, по соответствующей кнопке устанавливается проперть TpInstall.
Так вот хотелось бы в зависимости от установленного значения TpInstall (Server или WStation) заблокировать соответствующую фичу (если установлено Server, то заблокировать фичу "WStationInstall", и наоборот).
А вот как это сделать? Пробовал так:
<Feature Id="ServerInstall" Description="SRVR Components." Level="1" Title="SRVR" >
<Condition Level="2">TpInstall <> "Server"</Condition>
<ComponentRef Id="SrvComponent" />
</Feature>
<Feature Id="WStationInstall" Description="WS Components." Level="1" Title="WS" >
<Condition Level="2">TpInstall <> "WStation"</Condition>
<ComponentRef Id="WstComponent" />
</Feature>
Не получилось
Что не так? Если можно, то сразу код.
Заранее благодарю.
Здравствуйте, v0lev, Вы писали:
[кусь]
V>Как видно из кода — две различные компоненты: для установки на сервер и на рабочую станцию.
Windows Installer плохо проработан на тему взаимоисключающих условий на установку фич и сложных условий на зависимости между одноуровневыми фичами (не вложенными друг в друга).
Поэтому, я бы сделал два разных пакета: один — для сервера, другой — для клиента. Иначе надо делать много приседаний для того, чтобы обеспечить корректную установку, правда, тут все зависит от требований к инсталятору.
В общем, я бы пошел именно с этой стороны: разделить пакеты на серверный и клиентский. Это идеологически более правильно, чем все вместе. Даже если оба пакета маленькие.
Невозможность установки двух пакетов на одну машину делается через LaunchCondition.
Если есть причины, чтобы иметь один пакет, пожалуйста, укажите их.
V> Далее прописываем фичи — для каждой фичи свой компонент:
[кусь]
V>Как видно их кода, по соответствующей кнопке устанавливается проперть TpInstall.
V>Так вот хотелось бы в зависимости от установленного значения TpInstall (Server или WStation) заблокировать соответствующую фичу (если установлено Server, то заблокировать фичу "WStationInstall", и наоборот).
В принципе, Windows Installer предоставляет возможность устанавливать пакет без всякого UI или с минимальным UI. Поэтому, у этой проперти должно быть дефолтное значение, которое вы сами должны задать. А чтобы была возможность указать что именно ставить с использованием вашей проперти, нужно чтобы она была публичной, то есть, uppercase, например, TPINSTALL. При этом, в командной строке этот механизм уже предусмотрен через установку пропертей ADDLOCAL, REMOVE, ADDSOURCE, REINSTALL и парочки других. То есть, эти мезанизмы хорошо бы согласовать.
Но, если я правильно помню, эти проперти анализируются до того, как показывается диалог — есть такая операция как CostFinalize, где и происходит анализ того, какие фичи запрошены на установку во всяких внешних пропертях, InstallLevel и в таблице Condition.
Можно создать свою CustomAction и вызвать функцию MsiSetFeatureState. Я на всякий случай обращаю внимание, что другая функция, MsiConfigureFeature, не имеет отношения к текущему процессу инсталляции, а предназначена для вызова нового процесса и переконфигурирования уже установленного продукта. Это чтобы зря не экспериментировали.
V>А вот как это сделать? Пробовал так:
V><Feature Id="ServerInstall" Description="SRVR Components." Level="1" Title="SRVR" >
V> <Condition Level="2">TpInstall <> "Server"</Condition>
V> <ComponentRef Id="SrvComponent" />
V></Feature>
V><Feature Id="WStationInstall" Description="WS Components." Level="1" Title="WS" >
V> <Condition Level="2">TpInstall <> "WStation"</Condition>
V> <ComponentRef Id="WstComponent" />
V></Feature>
V>Не получилось
Потому, что вы таким образом прописали условия в таблицу Condition. А она анализируется до того, как активируется основной UI с кнопочками "Next" и "Cancel" на диалогах.
V>Что не так? Если можно, то сразу код.
1) MsiSetFeatureState в вашей CustomAction и не надо приседать больше.
2) Стандартными средствами сложнее.
Для этого мне нужно много написать и немного обдумать комбинации установки, в частности, если вам нужно, чтобы работал Upgrade, надо повспоминать маленько.
Сходу у меня есть вариант с помещением всех компонентов в одну фичу и выбором установки на уровне компонентов, а не фич — это можно делать на более поздних этапах.
Схема проста.
Есть две фейковые фичи, содержащие по одному компоненту. Я предпочел бы туда положить что-нибудь не важное для работы продукта. Например, записи в реестр типа "установлен сервер" или "установлен клиент".
Третья фича — невидимая на диалоге (см описание таблицы Feature). В ней находятся все компоненты. У компонентов поставлены условия: устанавливать, если устанавливается фича "сервер" на одних и аналогично "клиент" на других.
<?define InstallServerCondition="&ServerInstall=3"?>
<?define InstallClientCondition="&WStationInstall=3"?>
...
<Component Id="WstComponent" ... >
<File Id="File1_1" ... />
<File Id="File1_2" ... />
<Condition>$(var.InstallClientCondition)</Condition>
</Component>
<Component Id="SrvComponent" ... >
<File Id="File2_1" ... />
<File Id="File2_2" ... />
<Condition>$(var.InstallServerCondition)</Condition>
</Component>
Кстати, как я понял, вы все файлы накидали в один компонент. Это не очень хорошо для апгрейдов, но это совсем отдельный разговор.
V>Заранее благодарю.
Пожалуйста. Но я настоятельно рекомандую раскидать по двум разным инсталяшкам.