Подтвердить что ты не робот

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

Я хотел бы сохранить свой верхний уровень .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.

4b9b3361

Ответ 1

Вместо условного включения открытых элементов 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 бит каталога программных файлов

<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, потому что ссылка Даниэля отвечает на вопрос и имеет гораздо более интересную информацию, кроме того.

Ответ 2

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

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

...

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

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