Как найти путь к активному файлу app.config?

167

Я пытаюсь закончить этот обработчик исключений:

if (ConfigurationManager.ConnectionStrings["ConnectionString"]==null)
{
    string pathOfActiveConfigFile = ...?
    throw new ConfigurationErrorsException(
       "You either forgot to set the connection string, or " +
       "you're using a unit test framework that looks for  "+
       "the config file in strange places, update this file : " 
       + pathOfActiveConfigFile);
}

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

MatthewMartin
источник

Ответы:

363

Попробуй это

AppDomain.CurrentDomain.SetupInformation.ConfigurationFile

Надеюсь, поможет

Седрик Руп
источник
Это лучше, чем пытаться использовать Assembly.GetEntryAssembly () + ".config", которая не работает в некоторых ситуациях в ASP.NET и в некоторых ситуациях при использовании доменов приложений.
Контанго
4
как я могу изменить этот путь?
Виньеш Субраманян
Спасибо. У меня был проект, обновленный с VS2008 -> VS2013, который отказался читать файл app.config. Затем я узнал через AppDomain.CurrentDomain.SetupInformation.ConfigurationFile, что он ищет XXX.vshost.exe.config, который не генерируется. Поэтому я отключил VS Hosting в закладке отладки свойств проекта. Затем мне пришлось переименовать мой файл app.config в {projectName} .config, поместить его в папку bin, и он наконец
заработал
1
Не работал для меня Этот ответ сделал однако.
Кей Зед
4
Как насчет ядра .net?
JJXTRA
64

Строго говоря, нет единого файла конфигурации. За исключением ASP.NET 1, может быть три файла конфигурации, использующих System.Configurationподдержку inbuilt ( ). В дополнение к конфигурации машины: app.exe.configпользовательский роуминг и локальный пользователь.

Чтобы получить «глобальную» конфигурацию ( exe .config):

ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
                    .FilePath

Используйте разные ConfigurationUserLevelзначения для пользовательских конфигурационных файлов в роуминге и без роуминга.


1 Который имеет совершенно другую модель, в которой содержимое дочерних папок (IIS-виртуальная или файловая система) web.configможет (в зависимости от настроек) добавлять или переопределять родительские web.config.

Ричард
источник
2
Сначала я поднял «Ответ», что было очень полезно. Но, в конце концов, я действительно нуждался в таком подходе, так что спасибо, что выложили его и здесь.
Ноам Гал
Не забудьте добавить ссылку на System.configuration
Black Horus
9

Если вы имеете в виду, что вы получаете нулевой возврат только при использовании NUnit, то вам, вероятно, нужно скопировать значение ConnectionString ваш app.config вашего приложения в app.config вашей тестовой библиотеки.

Когда он запускается загрузчиком тестов, тестовая сборка загружается во время выполнения и просматривает собственный app.config (переименованный в testAssembly.dll.config во время компиляции), а не файл конфигурации ваших приложений.

Чтобы узнать местоположение сборки, на которой вы работаете, попробуйте

System.Reflection.Assembly.GetExecutingAssembly().Location
Колин Десмонд
источник
1
Предложите «AppDomain.CurrentDomain.SetupInformation.ConfigurationFile» из @Cedric Rup, в противном случае вы получите исключение в некоторых ситуациях в ASP.NET и в некоторых ситуациях при использовании доменов приложений.
Контанго
6

Убедитесь, что вы щелкнули свойства файла и задали для него значение «всегда копировать», иначе его не будет в папке Debug \ с вашими счастливыми папками, чтобы настроить, где он должен быть, и добавить еще один «колокольчик».

Чад Грант
источник
6

В первый раз, когда я понял, что проект модульного тестирования ссылается на app.config в этом проекте, а не на app.config, связанный с моим проектом производственного кода (конечно, DOH), я просто добавил строку в событие после сборки проекта Prod это скопирует app.config в папку bin тестового проекта.

Задача решена

До сих пор я не заметил каких-либо странных побочных эффектов, но я не уверен, что это правильное решение, но, по крайней мере, оно работает.

Kasper
источник
4

Здесь отсутствует еще одна опция, которую я видел:

const string APP_CONFIG_FILE = "APP_CONFIG_FILE";
string defaultSysConfigFilePath = (string)AppDomain.CurrentDomain.GetData(APP_CONFIG_FILE);
selalerer
источник
Хорошая вещь об этом, как это ни странно, в том, что он компилируется под .NET Standard 2.0. В .NET Core 2.0 возвращает ноль, но это полезно во время миграции.
EM0
3

В зависимости от расположения вашего конфигурационного файла System.Reflection.Assembly.GetExecutingAssembly().Locationможет быть сделано то, что вам нужно.

Уильям Эдмондсон
источник
2
Кроме того, вы можете иметь несколько «активных» конфигурационных файлов одновременно. Machine.config, уровень фреймворка web.config, конфигурация уровня приложения и т. Д., Поэтому я не думаю, что есть способ автоматически определить местоположение файла уникальной строки подключения, не анализируя все возможные файлы конфигурации, доступные для вашего приложения.
Уильям Эдмондсон
3

Я попробовал один из предыдущих ответов в веб-приложении (на самом деле веб-роль Azure работает локально), и он не совсем сработал. Тем не менее, этот похожий подход сработал:

var map = new ExeConfigurationFileMap { ExeConfigFilename = "MyComponent.dll.config" };
var path = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None).FilePath;

Конфигурационный файл оказался в C: \ Program Files \ IIS Express \ MyComponent.dll.config. Интересное место для этого.

RedGreenCode
источник