Используя Wix, как я могу развернуть один из нескольких файлов web.config при установке веб-приложения ASP.net

Я использую бета-версию Wix 3.6 из командной строки, а не как проекты VS. У меня есть веб-приложение, которое забирается с помощью тепла в виде каталога. Это работает. Я использую преобразования web.config для управления каждым файлом web.config целевой среды. Они выводятся с помощью msbuild, это работает и сохраняет видимость в Visual Studio и системе управления версиями.

Я столкнулся с проблемой развертывания одного из нескольких файлов web.config, которые я вручную включаю в product.wxs как компоненты с условиями. Я ожидал включить все компоненты в качестве развертываемых функций и позволить условиям выбрать только один как активный. Например:

        <DirectoryRef Id="wwwroot">
        <Component Id="setup_a" Guid="some_guid" >
            <File Source="$(var.ConfigSourceDir)\setup_a\web.config"  />
            <Condition>ENVIRON = setup_a</Condition>
        </Component>

        <Component Id="setup_b" Guid="some_guid" >
            <File Source="$(var.ConfigSourceDir)\setup_b\web.config" />
            <Condition>ENVIRON = setup_b</Condition>
        </Component>

Это не создало никаких проблем с переименованием, перемещением или удалением файлов, но имеет очень фундаментальную проблему, состоящую в том, что несколько файлов web.config сопоставляются с одним и тем же местом назначения, и это дает мне легкую ошибку "Product.wxs(xxx) : error LGHT0091 : Обнаружен повторяющийся символ «Файл: web.config». Обычно это означает, что идентификатор повторяется. Убедитесь, что все ваши идентификаторы данного типа (файл, компонент, функция) уникальны."

Альтернативный подход заключался в использовании файлов .config с разными именами и переименовании/перемещении одного из них в web.config, например:

        <DirectoryRef Id="wwwroot">
                <Component Id="setup_a" Guid="some_guid" >
                <File Id="setup_a.config" Source="$(var.ConfigSourceDir)\setup_a.config"  />
                <CopyFile Id="moveit" SourceDirectory="wwwroot" SourceName="setup_a.config" DestinationDirectory="wwwroot" DestinationName="web.config"  />
               </Component>

Это не вызывает ошибки, команда CopyFile вообще ничего не делает. Я просто получаю setup_a.config в папке wwwroot.

Если я вложу CopyFile в файл, действие копирования будет работать:

        <DirectoryRef Id="wwwroot">
               <Component Id="setup_a" Guid="some_guid" >
               <File Id="setup_a.config" Source="$(var.ConfigSourceDir)\setup_a.config"  >
                    <CopyFile Id="moveit" DestinationName="web.config"/>
               </File>
               </Component>

... но вложенный CopyFile означает, что я не могу добавить (это запрещено) атрибут Delete="yes" для создания действия "переместить". Вместо этого у меня остались и setup_a.config, и web.config в папке wwwroot. В качестве альтернативы, если я добавлю отдельный файл удаления в тот же элемент компонента, он также ничего не сделает:

<RemoveFile Id="removefile" On="install" Directory="wwwroot" Name="setup_a.config"/>
</Component>

Итак, я надеюсь получить рабочий пример того, как обрабатывать несколько файлов web.config в условном развертывании, не оставляя файлы позади. имя целевого файла web.config фиксируется фреймворком и не может быть изменено. Различные конфигурации также предварительно генерируются вне wix с использованием преобразований конфигурации, это также нельзя изменить, но сгенерированные имена файлов могут быть любыми.

ваше здоровье!


person Paul George    schedule 22.12.2011    source источник


Ответы (2)


Вы слишком все усложняете. Это должно работать:

    <Component Id="setup_a" Guid="some_guid" >
        <File Name="web.config" Id="config_a" Source="$(var.ConfigSourceDir)\setup_a\web.config"  />
        <Condition>ENVIRON = setup_a</Condition>
    </Component>

    <Component Id="setup_b" Guid="some_guid" >
        <File Name="web.config" Id="config_b" Source="$(var.ConfigSourceDir)\setup_b\web.config" />
        <Condition>ENVIRON = setup_b</Condition>
    </Component>

Здесь обратите внимание на пару вещей:

  • имя File/@Name такое же - это имя целевого файла, которое вы хотели бы иметь (web.config)
  • File/@Id отличается для каждого файла, чтобы избежать легкой ошибки, о которой вы упомянули в первую очередь.
  • File/@Source может быть любым - он просто описывает какой файл брать в качестве исходника

В этом примере свет по-прежнему будет выдавать предупреждение LGHT1076, но это всего лишь предупреждение — оно обращает ваше внимание на то, что условия ДОЛЖНЫ быть взаимоисключающими, чтобы избежать проблем.

person Yan Sklyarenko    schedule 22.12.2011
comment
Аааа, отсутствие атрибута имени испортило элементы моего файла, заставив меня думать, что это не сработает. Ваш пример сработал, спасибо Ян. - person Paul George; 24.12.2011
comment
Я делаю это немного чище (избегайте предупреждений о проверке ICE). Я создаю компоненты/файлы как web.config-a и web.config, а затем использую элемент CopyFile, чтобы клонировать его в web.config. ДВС хороший и чистый. Минус - лишний файл на коробке. Положительным моментом является то, что файл дает мне визуальную подсказку о том, какой выбор был сделан, и копию исходных файлов на случай, если кто-то подправит web.config, и я захочу сравнить/откатить. - person Christopher Painter; 25.06.2014

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

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

person Christopher Painter    schedule 23.12.2011