Использование Wix для создания 32-битных и 64-битных инсталляторов из одного файла .wxs - PullRequest
29 голосов
/ 03 июня 2011

Я бы хотел сохранить мой верхний уровень .wxs DRY при сборке 32- и 64-битных установщиков. Я использую аргумент -arch для Candle.exe для управления сборкой архитектуры установщика по умолчанию.

Стена, которую я сейчас поражаю, состоит в том, что кажется, что ProgramFilesFolder отличается между 32- и 64-битными (ProgramFiles64Folder) архитектурами. Вот моя первая попытка обойти:

<?if $(sys.BUILDARCH)=x64 ?>
<Directory Id='ProgramFiles64Folder' Name='PFiles'>
<?else ?>
<Directory Id='ProgramFilesFolder' Name='PFiles'>
<?endif ?>
    <Directory Id='the-rest' Name="Company Name">
...

Я попробовал это с ошибкой. Очевидно, проверка XML запускается до оценки препроцессора. Когда я вручную переключаюсь на использование ProgramFiles64Folder, моя сборка работает.

Я попытался пойти по маршруту DirectoryRef безуспешно. Любые предложения о том, как заставить это работать без замены sed в файле .wxs?

Примечание: я пробовал это в Wix 3.5 и 3.6.

Ответы [ 2 ]

44 голосов
/ 04 июня 2011

Вместо того, чтобы условно включать открывающиеся элементы Directory (что делает XML недействительным), условно задайте переменные препроцессора, которые используются в качестве имен каталогов, как говорится в комментарии @Daniel Pratt. Аналогично, наличие переменной «да / нет» в зависимости от платформы упрощает настройку 64-битных компонентов, поиск в реестре и т. Д.

Определение переменных

этот ответ )

<?if $(var.Platform) = x64 ?>
  <?define ProductName = "Product Name (64 bit)" ?>
  <?define Win64 = "yes" ?>
  <?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?else ?>
  <?define ProductName = "Product Name" ?>
  <?define Win64 = "no" ?>
  <?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
<?endif ?>

$(var.Platform) встроен, но его значение используется для определения пользовательских переменных $(var.ProductName), $(var.Win64) и $(var.PlatformProgramFilesFolder).

Использование переменных

Вы можете либо использовать директивы препроцессора <?if для проверки значений переменных (как это делается с $(var.Platform) при определении пользовательских переменных выше), либо иметь препроцессор, вставляющий значения переменных в атрибут XML или значения элементов. Пара примеров:

32/64-битные компоненты

<Component Id="..." Win64="$(var.Win64)">
   ...
</Component>

Это приведет к появлению предупреждений в редакторе Visual Studio WiX о том, что $(var.Win64) не является одним из допустимых значений атрибута (yes / no), но их можно безопасно игнорировать, поскольку препроцессор заменит соответствующее значение к тому времени, когда компилятор завладеет им.

32/64-битная папка Program Files

<Directory Id="$(var.PlatformProgramFilesFolder)">
  ...
</Directory>

Обновление для обработки отдельных 32/64-битных кодов продуктов

В ответ на комментарий rharrison33, спрашивающий, как обработать требование для различных кодов продуктов (или почти чего-либо) в 32- и 64-битных установщиках (при условии, что вы не можете / не хотите их автоматически генерировать):

  • Передать отдельные коды продуктов в свечу в качестве переменных препроцессора, в командной строке или с помощью файла ответов:
candle <all other flags> -d ProductCode32=<guid1> -d ProductCode64=<guid2>
  • Добавьте код продукта в качестве одной из зависимых от архитектуры переменных препроцессора и установите для него соответствующую входную переменную:
    • В 32-битной <?if ?> ветви: <?define ProductCode = "$(var.ProductCode32)" ?>
    • В 64-битной <?if ?> ветви: <?define ProductCode = "$(var.ProductCode64)" ?>
  • См. $(var.ProductCode) в Product/@Id.

Сделано это CW, потому что ссылка Даниэля отвечает на вопрос и, кроме того, содержит намного больше информации.

3 голосов
/ 03 декабря 2013

У меня была эта проблема с WiX 3.7.Это был крошечный установщик, и мне не требовалась гибкость переменных, поэтому я скрыл закрывающий тег Directory от анализатора, обернув его так же, как открывающий тег:

<?if $(sys.BUILDARCH)=x64?>
    <Directory Id="ProgramFiles64Folder">
<?else?>
    <Directory Id="ProgramFilesFolder">
<?endif?>

...

<?if $(sys.BUILDARCH)=x64?></Directory><?else?></Directory><?endif?>

Это взлом, но он работал для моего варианта использования.

...