Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
English version is here.
Один из наиболее часто задаваемых вопросов - как сохранить значение свойства, которое было присвоено свойству во время инсталлирования программы (присвоенное либо через параметер в командной строке или через пользовательский интерфейс как, например, INSTALLLOCATION).
В качестве примера возьмем одну из возможный ситуатций. Рассмотрим очень простой пример. Идея состоит в том, что пользователь передает через командную строку значение, которое необходимо записать в XML файл. Также, необходимо чтобы это значение осталось неизменным при "починке" (repair). Начнем с очень простого примера:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="https://schemas.microsoft.com/wix/2006/wi"
xmlns:util="https://schemas.microsoft.com/wix/UtilExtension">
<?define UpgradeCode="{D1C829D8-5A5B-412C-90ED-7F92750F8152}"?>
<?define CurrentVersion="1.0.0.0"?>
<Product Id="*"
Name="PreserveProperty"
Language="1033"
Version="$(var.CurrentVersion)"
Manufacturer="PreserveProperty"
UpgradeCode="$(var.UpgradeCode)">
<Package InstallerVersion="200"
Compressed="yes"
InstallScope="perMachine"
Languages="1033" />
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
<!-- Make sure properties are passed in the command line -->
<Condition Message="MYPROPERTY variable must be set in the command line">
Installed OR MYPROPERTY
</Condition>
<!-- Installation -->
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLLOCATION" Name="PreserveProperty">
<Component Id="ProductComponent"
Guid="cf13f922-e33c-4b78-a849-46e32c000e09">
<File Id="XmlFile"
Name="test.xml"
Source="test.xml"
KeyPath="yes" />
<util:XmlFile Id="SetMYPROPERTY"
Action="setValue"
ElementPath="//config/parameter[\[]@name='MyProperty'[\]]/@value"
Value="[MYPROPERTY]"
File="[#XmlFile]" />
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id="ProductFeature" Title="PreserveProperty" Level="1">
<ComponentRef Id="ProductComponent" />
</Feature>
</Product>
</Wix>
Для того чтобы проверить, что свойство MYPROPERTY было включено в командную строку, используется Custom Action Type 19 (элемент <Condition>).
Во время установки, инсталлятор скопирует файл install test.xml и установит значение атрибута value в значение свойства MYPROPERTY. Файл test.xml выглядит следующим образом:
<config>
<parameter name='MyProperty' value='' />
</config>
Если Вы скомпилируете пример и установите его, то Вы увидите, что файл test.xml создан и значение атрибута value то же, что и переданное через командную строку. Попробуйте установить пример используя следующую командную строку:
msiexec /i PreserveProperty.msi MYPROPERTY="123"
Можно также попробовать и без свойства MYPROPERTY в командной строке. Программа выдаст сообщение об ошибке из элемента <Condition>.
Теперь, попробуем починить инсталляцию. Это можно сделать через Add/Remove Programs, меню Repair. После того, как починка окончена, откройте файл test.xml. Вы увидите, что значение атрибута value пусто. Проблема в том, что MYPROPRTY="123" не было использовано при запуске msiexec.exe. Нашей обязанностью является сохранение значения свойства переданного msiexec.exe во время первоначальной установки.
Давайте внесем изменения в наш WiX файл:
- Сохраним значение свойства в реестре (registry)
- Восстановим значение свойства из реестра во время AppSearch (будем использовать временное свойство)
- Скопируем значение временного свойства в MYPROPRTY при условии, что это НЕ начальная установка
Первый пункт простой:
<RegistryKey Id="PreservePropertyInRegistry"
Root="HKLM"
Key="SOFTWARE\ACME Corp" Action="createAndRemoveOnUninstall">
<RegistryValue Id="SavedProperty"
Action="write"
Type="string"
Name="SavedProperty"
Value="[MYPROPERTY]" />
</RegistryKey>
Второй пункт - обычный RegistrySearch:
<Property Id="SAVEDMYPROPERTY" Secure="yes">
<RegistrySearch Id="FindSavedMYPROPERTY"
Root="HKLM"
Key="SOFTWARE\ACME Corp"
Name="SavedProperty"
Type="raw"
Win64="no" />
</Property>
Третий пункт - элемент <SetProperty> (или Custom Action Type 51, если Вы все еще используете версию V2), но с добавленным условием, что программа уже установлена.
<SetProperty Id="MYPROPERTY" After="AppSearch" Value="[SAVEDMYPROPERTY]">
Installed
</SetProperty>
Исходный код в attachment.