Jak znaleźć ścieżkę do aktywnego pliku app.config?

167

Próbuję zakończyć ten program obsługi wyjątków:

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);
}

Wydaje się, że ten problem występuje tylko wtedy, gdy używam nUnit.

MatthewMartin
źródło

Odpowiedzi:

363

Spróbuj tego

AppDomain.CurrentDomain.SetupInformation.ConfigurationFile

Mam nadzieję, że to pomoże

Cédric Rup
źródło
Jest to o wiele lepsze niż próba użycia Assembly.GetEntryAssembly () + „.config”, które nie działa w niektórych sytuacjach w ASP.NET iw niektórych sytuacjach podczas używania AppDomains.
Contango
4
jak mogę zmienić tę ścieżkę?
Vignesh Subramanian
Dziękuję Ci. Miałem projekt zaktualizowany z VS2008 -> VS2013, który odmówił odczytania pliku app.config. Następnie dowiedziałem się przez AppDomain.CurrentDomain.SetupInformation.ConfigurationFile, że szukał pliku XXX.vshost.exe.config, który nie był generowany. Więc wyłączyłem VS Hosting na karcie debugowania właściwości projektu. Potem musiałem zmienić nazwę mojego pliku app.config na {projectName} .config, umieścić go w folderze bin i w końcu zadziałało
drzounds
1
Nie działa dla mnie. Ta odpowiedź jednak tak.
Kay Zed
4
A co z .net core?
jjxtra
64

Ściśle mówiąc, nie ma jednego pliku konfiguracyjnego. Oprócz ASP.NET 1 mogą istnieć trzy pliki konfiguracyjne korzystające z obsługi inbuilt ( System.Configuration). Oprócz konfiguracji komputera: app.exe.configmobilny użytkownik i lokalny użytkownik.

Aby uzyskać konfigurację „globalną” ( exe .config):

ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
                    .FilePath

Użyj różnych ConfigurationUserLevelwartości dla plików konfiguracyjnych mobilnych i niemobilnych według użycia.


1 Który ma zupełnie inny model, w którym zawartość folderów podrzędnych (wirtualnych IIS lub systemu plików) web.configmoże (w zależności od ustawienia) dodać lub zastąpić folder nadrzędny web.config.

Richard
źródło
2
Najpierw podniosłem „Odpowiedź”, co było bardzo pomocne. Ale na koniec naprawdę potrzebowałem tego podejścia, więc dziękuję również za umieszczenie go tutaj.
Noam Gal
Nie zapomnij dodać odniesienia do konfiguracji Systemowej
Black Horus
9

Jeśli masz na myśli, że zwracasz wartość null tylko wtedy, gdy używasz NUnit, prawdopodobnie będziesz musiał skopiować wartość ConnectionString z pliku app.config swojej aplikacji do pliku app.config w bibliotece testów.

Gdy jest uruchamiany przez moduł ładujący test, zestaw testowy jest ładowany w czasie wykonywania i będzie wyglądał we własnym pliku app.config (zmienionym na testAssembly.dll.config w czasie kompilacji), a nie w pliku konfiguracyjnym aplikacji.

Aby uzyskać lokalizację uruchamianego zestawu, spróbuj

System.Reflection.Assembly.GetExecutingAssembly().Location
Colin Desmond
źródło
1
Zasugeruj „AppDomain.CurrentDomain.SetupInformation.ConfigurationFile” z @Cedric Rup, w przeciwnym razie otrzymasz wyjątek w niektórych sytuacjach w ASP.NET iw niektórych sytuacjach podczas korzystania z AppDomains.
Contango
6

Upewnij się, że klikasz właściwości pliku i ustawisz go na „zawsze kopiuj”, w przeciwnym razie nie będzie go w folderze Debug \ z twoją szczęśliwą biblioteką DLL, aby skonfigurować miejsce, w którym ma być i dodać więcej dzwonków

Chad Grant
źródło
6

Kiedy po raz pierwszy zdałem sobie sprawę, że projekt testów jednostkowych odwoływał się do app.config w tym projekcie, a nie do app.config powiązanego z moim projektem kodu produkcyjnego (oczywiście, DOH), właśnie dodałem wiersz w zdarzeniu po kompilacji projektu Prod który skopiuje plik app.config do folderu bin projektu testowego.

Problem rozwiązany

Jak dotąd nie zauważyłem żadnych dziwnych skutków ubocznych, ale nie jestem pewien, czy to jest właściwe rozwiązanie, ale przynajmniej wydaje się, że działa.

Kasper
źródło
4

Brakuje tu jeszcze jednej opcji, którą widziałem:

const string APP_CONFIG_FILE = "APP_CONFIG_FILE";
string defaultSysConfigFilePath = (string)AppDomain.CurrentDomain.GetData(APP_CONFIG_FILE);
selalerer
źródło
Fajną rzeczą w tym, choć wygląda na to hack, jest to, że kompiluje się pod .NET Standard 2.0. Zwraca wartość null w .NET Core 2.0, ale jest przydatna podczas migracji.
EM0
3

W zależności od lokalizacji pliku konfiguracyjnego System.Reflection.Assembly.GetExecutingAssembly().Locationmoże zrobić to, czego potrzebujesz.

William Edmondson
źródło
2
Dodatkowo możesz mieć kilka „aktywnych” plików konfiguracyjnych w tym samym czasie. Machine.config, web.config na poziomie struktury, konfiguracja na poziomie aplikacji itp., Więc nie sądzę, aby można było automatycznie zlokalizować unikalną lokalizację pliku parametrów połączenia bez analizowania wszystkich możliwych plików konfiguracyjnych dostępnych dla Twojej aplikacji.
William Edmondson
3

Wypróbowałem jedną z poprzednich odpowiedzi w aplikacji internetowej (właściwie rola sieci Web platformy Azure działająca lokalnie) i nie do końca działała. Jednak to podobne podejście zadziałało:

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

Plik konfiguracyjny okazał się być w C: \ Program Files \ IIS Express \ MyComponent.dll.config. Ciekawe miejsce na to.

RedGreenCode
źródło