Несколько файлов конфигурации .NET и проблема проекта установки - PullRequest
4 голосов
/ 27 мая 2009

Чтобы обработать настройки для различных целей развертывания, я переместил настройки приложения из app.config в его собственный файл и включил этот файл в app.config через configSource. Я также создал файл настроек для каждой цели. Вот иллюстрация:

Project A
   app.config (references settings.config)
   settings.config 
   settings.Release.config
   settings.Debug.config

Во время пост-сборки я копирую соответствующие настройки. {Configuration} .config в выходной каталог. Пока это работает нормально, и я вижу файл settings.config в выходном каталоге проекта, содержащий настройки для текущей конфигурации сборки: Release, Debug и т. Д.

Однако у меня проблема с проектом установки, который у меня есть для этого проекта (Проект A). Первоначально, это не был файл settings.config. Поэтому я установил действие сборки для файла settings.config как Content и добавил файлы содержимого из Project A в проект установки. Это гарантировало, что файл settings.config был включен в настройку. Однако, поскольку проект установки, по-видимому, выбирает файл settings.config из каталога проекта, а не из выходного каталога, файл settings.config, включенный в установку, не является тем, чем он должен быть. Я хочу, чтобы один из выходного каталога был включен в программу установки, так как он является правильным для текущей конфигурации сборки. Я попробовал следующее:

  • Добавлен файл settings.config в виде файла в проект установки. Тем не менее, похоже, что я могу указать только абсолютный путь. Поэтому, когда я добавляю его из выходного каталога конкретной конфигурации сборки (..bin \ debug \ settings.config), он не работает в другой конфигурации сборки, поскольку (..bin \ debug \ settings.config) существует в указанная директория Я рассмотрел использование относительных или динамических путей в проекте установки, где конфигурация сборки может быть указана как часть пути, но я не смог ничего найти.

Я подумал об использовании события предварительной сборки, чтобы фактически изменить файл settings.config в каталоге проекта, а затем скопировать его в выходной каталог, установив его «Копировать в выходной каталог», чтобы всегда копировать или копировать, если он более новый. Это должно гарантировать, что соответствующий файл settings.config будет скопирован в выходной каталог точно так же, как решение после сборки, а также должен убедиться, что содержимое файла settings.config обновлено до его включения в проект установки. Однако мне не нравится это решение, потому что я должен убедиться, что файл settings.config доступен для записи, прежде чем я смогу внести какие-либо изменения, так как он контролируется исходным кодом. Если он доступен только для чтения, мне нужно перевернуть его для записи, внести изменения, а затем снова установить для чтения. Это добавляет дополнительную сложность.

Мне было интересно, если у кого-нибудь есть идея получше или она знает хитрость проекта установки, которая позволяет мне включить файл settings.config, соответствующий текущей конфигурации сборки, в программу установки.

Спасибо

Ответы [ 2 ]

1 голос
/ 11 июня 2009

Я решил пойти к достижению того же результата (имея возможность иметь разные параметры конфигурации для разных целевых сред) по-другому. Вот как я это реализовал, и это прекрасно работает. Я прочитал некоторые посты здесь, в SO, о задаче XmlMassUpdate из Задачи сообщества MSBuild и решил использовать ее. Вот что я сделал:

1) Для каждого проекта, который должен иметь различные настройки в зависимости от целевой среды, я добавил в проект файл XML с именем app.config.substitutions.xml или web.config.substitutions.xml. Итак, проект выглядел как

Project A   
 app.config 
 app.config.substitutions.xml

В файле app.config.substitutions.xml есть подстановки параметров, которые XmlMassUpdate обработает и применяет к файлу app.config. Ниже приведен пример файла подстановки, который я использую:

<configuration xmlns:xmu="urn:msbuildcommunitytasks-xmlmassupdate">
  <substitutions>
    <Development>
      <appSettings>
        <add xmu:key="key" key="SomeSetting" value="DevValue" />
      </appSettings>
    </Development>
    <Test>
      <appSettings>
        <add xmu:key="key" key="SomeSetting" value="TestValue" />
      </appSettings>
    </Test>
    <Release>
      <appSettings>
        <add xmu:key="key" key="SomeSetting" value="ReleaseValue" />
      </appSettings>
    </Release>
  </substitutions>
</configuration>

Для получения подробной информации о том, как указать замены, посмотрите документацию для XmlMassUpdate или просто выполните поиск по ней.

2) Теперь мне нужно запустить XmlMassUpdate как часть автоматизации сборки (TeamBuild / MSBuild). Поэтому в BeforeCompile в файле определения сборки TeamBuild (в основном, в файле proj) я добавил следующее для запуска XmlMassUpdate в файлах конфигурации, имеющих соответствующий файл .substitution.xml

  <PropertyGroup>
    <SubstitutionFileExtension>.substitutions.xml</SubstitutionFileExtension>
    <TargetEnvironment>Test</TargetEnvironment>
  </PropertyGroup>

  <Target Name="BeforeCompile" Condition="'$(IsDesktopBuild)'!='true'">
    <CreateItem Include="$(SolutionRoot)\**\app.config;$(SolutionRoot)\**\web.config">
      <Output ItemName="ConfigurationFiles" TaskParameter="Include"/>
    </CreateItem>
    <CreateItem Include="@(ConfigurationFiles)" Condition="Exists('%(FullPath)$(SubstitutionFileExtension)')">
      <Output ItemName="ConfigFilesWithSubstitutions" TaskParameter="Include"/>
    </CreateItem>
    <Message Text="Updating configuration files with deployment target specific settings..."/>
    <XmlMassUpdate
      ContentFile="%(ConfigFilesWithSubstitutions.FullPath)"
      SubstitutionsFile="%(ConfigFilesWithSubstitutions.FullPath)$(SubstitutionFileExtension)"
      ContentRoot="/configuration"
      SubstitutionsRoot="/configuration/substitutions/$(TargetEnvironment)"/>   
  </Target>

Обратите внимание, что файлы конфигурации доступны только для чтения во время сборки, поэтому я обязательно установлю их для записи перед запуском этой задачи. На самом деле у меня есть другая пользовательская задача MSBuild, которая запускается до XmlMassUpdate, которая обрабатывает общие параметры для всех файлов конфигурации, таких как строки подключения. Эта задача делает файлы конфигурации доступными для записи. Я также не проверяю измененные файлы конфигурации обратно в систему контроля версий. Они (соответствующий файл конфигурации для цели развертывания) включены в установщик.

1 голос
/ 11 июня 2009

Если бы мне пришлось подойти к этой проблеме, я бы начал со следующего вопроса:

Почему settings.config должен находиться под контролем исходного кода, если settings.Debug.config или settings.Release.config предоставляют такую ​​же информацию?

Ответ, если я правильно прочитал ваш вопрос, заключается в том, что вам нужно было заставить файл settings.config появляться как часть вывода сборки. Я предполагаю, что это потому, что ваш проект установки использует встроенный выбор «Первичный вывод».

Вместо этого вы можете добавить этот файл в проект установки в качестве явной ссылки на файл. Щелкните правой кнопкой мыши по проекту установки и выберите «Добавить / файл», затем выберите файл, который вы хотите включить. Как вы заметите (если только это не было исправлено в VS2008, который, к сожалению, мне пока не разрешено использовать на работе), существует очень досадное ограничение, накладываемое на добавленные вручную файлы - нет способа сделать так, чтобы конфигурация пути компоновки была в курсе. Вы можете обойти это, скопировав соответствующий файл settings.config в общую папку (например, bin / Configuration) и выбрав его оттуда. Это ограничивает вас сборкой версий Debug и Release последовательно, а не параллельно, но для многих это, вероятно, не является большой проблемой.

Если вам не нужно использовать проекты установки VS, я настоятельно рекомендую вам взглянуть на WiX (Windows Installer XML - для получения дополнительной информации см. http://wix.sourceforge.net/). Это легко позволит вам выполнить то, что необходимо, хотя, если вы не знакомы с внутренней работой Microsoft Installer, начальная кривая обучения может быть немного крутой. Microsoft использует WiX для некоторых довольно важных задач установки (например, Office 2007, SQL Server и т. Д.). Можно было надеяться, что WiX станет частью Visual Studio (для VS 2010), но, к сожалению, это уже не так.

...