Сохранить настройки реестра при обновлении - PullRequest
1 голос
/ 10 декабря 2010

Я использую WiX 3.0.Я пытаюсь сохранить все настройки реестра при обновлении.

Я нашел следующую ссылку http://www.mail-archive.com/wix-users@lists.sourceforge.net/msg28844.html

Я предпочитаю использовать подход Property и RegistrySearch, а не подход настраиваемого действия, потому что я думал, что он выглядит проще.

К сожалению, этот подход не очень хорошо работает для меня.Мои проекты получили некоторые значения реестра типа DWORD и SZ.Для всех значений реестра типа DWORD добавляется знак # в начале.Я проверил руководство по WiX.Вот как работает RegistrySearch.

Итак, после обновления весь мой тип реестра DWORD изменяется на SZ.Значение выглядит одинаково, за исключением того, что # добавлено впереди.Например, я получил значение 2 в значении реестра «LogLevel» с типом DWORD.После обновления я получаю значение «# 2» в значении реестра «LogLevel» с типом SZ в том же месте.

Вот фрагмент кода

<Property Id='LOG_LEVEL' Value='Information'>
  <RegistrySearch Id='LogLevelRegistry' Type='raw' Root='HKLM' Key='Software\Company\Product' Name='LogLevel' Win64='$(var.Win64)'/>
</Property>

<Component Id="RegistryKey">
    <RegistryKey Root='HKLM' Key='Software\Company\Product' Action='createAndRemoveOnUninstall'>
      <RegistryValue Type='int' Name='LogLevel' Value='[LOG_LEVEL]'/>
    </RegistryKey>
</Component>

Интересно, есть ли какая-либо строковая функция, которая может помочь мне обрезать "#" из свойства LOG_LEVEL, прежде чем я верну его обратно.Или есть какой-нибудь разумный способ сохранить ключи реестра при обновлении?Должен ли я пойти на подход Custom Action?

Ответы [ 2 ]

5 голосов
/ 12 декабря 2010

Я наконец-то получил подход RegistrySearch. Я надеюсь, что это может помочь другим людям в будущем.

Я проверил документацию MSI. Таблица реестра фактически не содержит столбец с именем type. Вместо этого он хранит значение странным образом, поэтому MSI знает, какой тип значения реестра следует создать. В моем случае я хочу создать значение реестра типа DWORD. Значение должно храниться как # 1 в таблице реестра, если я хочу поместить числовое значение 1 в значение реестра. Вот ссылка на Реестр таблицы

Итак, почему Wix RegistryValue имеет обязательный атрибут Type? Я думаю, это потому что Викс пытается быть с тобой добрым. Если вы пометите тип как int, вы можете просто ввести «1» в атрибуте value. Вам не нужно помнить, что вы должны ввести «# 1» вместо «1». Когда вы компилируете исходный код Wix, компилятор сделает за вас грязную работу и переведет «1» в «# 1».

Аналогично, RegistrySearch является прямым отображением таблицы базы данных MSI RegLocator. Это возвращает # 1 мне, потому что мой тип значения реестра - DWORD. Жаль, что Викс на этот раз не сделал для меня перевод. Следующий код возвращает мне необработанные данные из таблицы. Итак, мое свойство LOG_LEVEL хранит # 1 вместо 1.

<Property Id='LOG_LEVEL' Value='3'>
  <RegistrySearch Id='LogLevelRegistry' Type='raw' Root='HKLM' Key='Software\Company\Product' Name='LogLevel' Win64='$(var.Win64)'/>
</Property>

Вот ссылка для RegistrySearch

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

<Component Id="RegistryKey">
  <RegistryKey Root='HKLM' Key='Software\Company\Product' Action='createAndRemoveOnUninstall'>
    <RegistryValue Type='int' Name='LogLevel' Value='[LOG_LEVEL]'/>
  </RegistryKey>
</Component>

Как я уже сказал, Wix добавит # для меня, когда увидит тип "int". Итак, значение в таблице Registry теперь равно ## 1. Если вы проверите документ MSDN, ## 1 будет интерпретироваться как строковое значение "# 1". Поэтому значение моего реестра воссоздается с новым типом SZ и новым значением "# 1"

Чтобы исправить эту проблему, я изменил свой код на этот

<Property Id='LOG_LEVEL' Value='#3'>
  <RegistrySearch Id='LogLevelRegistry' Type='raw' Root='HKLM' Key='Software\Company\Product' Name='LogLevel' Win64='$(var.Win64)'/>
</Property>

<Component Id="RegistryKey">
  <RegistryKey Root='HKLM' Key='Software\Company\Product' Action='createAndRemoveOnUninstall'>
    <RegistryValue Type='string' Name='LogLevel' Value='[LOG_LEVEL]'/>
  </RegistryKey>
</Component>

Обратите внимание, что хотя я здесь указываю тип "строка", у меня все еще есть значение реестра с типом DWORD, созданное для меня. Это потому, что MSI интерпретирует значение в таблице Registry. Если значение реестра LogLevel не существует (новая установка), я установлю для него значение по умолчанию # 3. Если значение реестра LogLevel существует, оно сохранит существующий LogLevel.

Также обратите внимание, что этот метод работает, потому что Wix 3.0 не выполняет никакой обработки значения свойства. Он помещает значение, хранящееся в свойстве, непосредственно в таблицу Registry. Просто из любопытства я также попробовал следующее.

<RegistryValue Type='string' Name='LogLevel' Value='#1'/>

На этот раз Wix правильно экранировал символ # и поместил ## 1 в таблицу Registry. Если позже Wix решит также экранировать символ # внутри значения свойства, мое решение здесь не будет работать.

0 голосов
/ 10 декабря 2010

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

Надеюсь, это поможет.

...