4

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

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

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

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

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

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

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

Благодаря

+0

Я понятия не имею, насколько это полезно для вас, но вы можете попробовать сценарий MSBuild, чтобы достичь своего конфигурационного файла «switch» перед компиляцией проекта. Я видел это так, как это было 2 года назад, но он был встроен в пару линий Hundread из Pearl для того, что было одним из самых сложных сценариев сборки, которые я когда-либо видел. Но вы должны сделать что-то гораздо более упрощенное для своего проекта. – 2009-05-27 17:03:25

ответ

1

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

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

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

Вместо этого вы можете добавить этот файл в проект установки в качестве явной ссылки на файл. Щелкните правой кнопкой мыши проект установки и выберите add/file, затем выберите файл, который хотите включить.Как вы заметили (если в 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), но, к сожалению, это уже не так.

+0

Спасибо за ответ. settings.config не должен находиться под контролем источника. Я включал его так, чтобы он был частью вывода, а также может быть включен в установщик в качестве ресурса. Проблема с добавлением его в качестве ссылки на файл из общего расположения заключается в том, что путь к файлу является абсолютным в установщике (C: \ MyWorkspace \ Solution \ ProjectA \ Config \ settings.config). Однако разработчики имеют разные рабочие пространства, а сборка (TeamBuild) имеет свою собственную структуру каталогов.Таким образом, путь, если относительный не будет недействительным, и это проблема, с которой я столкнулся. Любой способ сделать это относительным? –

+0

Yuck! Это было так давно, что я использовал проекты VS Setup, которые я забыл об этой проблеме. В свойствах проекта развертывания есть «Путь поиска». Если вы добавите соответствующий относительный путь туда, он должен найти его ... по крайней мере, на моей машине, когда я переименовал родительскую папку. –

1

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

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 (в основном проектируемый файл), я добавил следующие запустить 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, которая обрабатывает общие настройки во всех конфигурационных файлах, таких как строки подключения. Эта задача позволяет записывать конфигурационные файлы. Я также не проверяю измененные файлы конфигурации обратно на исходный элемент управления. Они (соответствующий файл конфигурации для цели развертывания) включены в программу установки.

Смежные вопросы