187

I'm trying to finish this exception handler:

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

This problem seems to only happen to me when I'm using nUnit.

MatthewMartin
  • 32,326
  • 33
  • 105
  • 164

8 Answers8

382

Try this

AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
Christopher Moore
  • 15,626
  • 10
  • 42
  • 52
Cédric Rup
  • 15,468
  • 3
  • 39
  • 30
  • This is wayyyyyyyy better than trying to use Assembly.GetEntryAssembly() + ".config" which doesn't work in some situations in ASP.NET and in some situations when using AppDomains. – Contango Oct 08 '13 at 13:27
  • 5
    how can i change this path? – Vignesh Subramanian May 06 '15 at 13:59
  • Thank you. I had a project upgraded from VS2008 -> VS2013 that refused to read the app.config file. Then I learned via AppDomain.CurrentDomain.SetupInformation.ConfigurationFile that it was searching for XXX.vshost.exe.config which was not being generated . So I turned it off VS Hosting in project properties debug tab. Then I had to rename my app.config file to {projectName}.config, put it in the bin folder and it finally worked – drzounds Jun 29 '16 at 19:50
  • 3
    Didn't work for me. [This answer did](http://stackoverflow.com/a/7069366/344541) however. – Kay Zed Sep 28 '16 at 15:13
  • Excellent, I was able to use this to find the config file being used when running a job on SQL Server. – Paul McCarthy May 02 '17 at 14:17
  • 12
    What about .net core? – jjxtra Jul 02 '18 at 16:40
72

Strictly speaking, there is no single configuration file. Excluding ASP.NET1 there can be three configuration files using the inbuilt (System.Configuration) support. In addition to the machine config: app.exe.config, user roaming, and user local.

To get the "global" configuration (exe.config):

ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
                    .FilePath

Use different ConfigurationUserLevel values for per-use roaming and non-roaming configuration files.


1 Which has a completely different model where the content of a child folders (IIS-virtual or file system) web.config can (depending on the setting) add to or override the parent's web.config.

Richard
  • 106,783
  • 21
  • 203
  • 265
10

If you mean you are only getting a null return when you use NUnit, then you probably need to copy the ConnectionString value the your app.config of your application to the app.config of your test library.

When it is run by the test loader, the test assembly is loaded at runtime and will look in its own app.config (renamed to testAssembly.dll.config at compile time) rather then your applications config file.

To get the location of the assembly you're running, try

System.Reflection.Assembly.GetExecutingAssembly().Location
Colin Desmond
  • 4,824
  • 4
  • 46
  • 67
  • 1
    Suggest "AppDomain.CurrentDomain.SetupInformation.ConfigurationFile" from @Cedric Rup otherwise you will get an exception in some situations in ASP.NET and in some situations when using AppDomains. – Contango Oct 08 '13 at 13:29
6

Make sure you click the properties on the file and set it to "copy always" or it will not be in the Debug\ folder with your happy lil dll's to configure where it needs to be and add more cowbell

Chad Grant
  • 44,326
  • 9
  • 65
  • 80
6

The first time I realized that the Unit testing project referenced the app.config in that project rather then the app.config associated with my production code project (off course, DOH) I just added a line in the Post Build Event of the Prod project that will copy the app.config to the bin folder of the test project.

Problem solved

I haven't noticed any weird side effects so far, but I am not sure that this is the right solution, but at least it seems to work.

Kasper
  • 1,710
  • 2
  • 17
  • 31
5

One more option that I saw is missing here:

const string APP_CONFIG_FILE = "APP_CONFIG_FILE";
string defaultSysConfigFilePath = (string)AppDomain.CurrentDomain.GetData(APP_CONFIG_FILE);
MatthewMartin
  • 32,326
  • 33
  • 105
  • 164
selalerer
  • 3,766
  • 2
  • 23
  • 33
  • The nice thing about this, hacky as it looks, is that it compiles under .NET Standard 2.0. It returns null under .NET Core 2.0, but it's useful during the migration. – EM0 Jan 18 '18 at 12:27
3

I tried one of the previous answers in a web app (actually an Azure web role running locally) and it didn't quite work. However, this similar approach did work:

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

The config file turned out to be in C:\Program Files\IIS Express\MyComponent.dll.config. Interesting place for it.

RedGreenCode
  • 2,195
  • 1
  • 25
  • 33
3

Depending on the location of your config file System.Reflection.Assembly.GetExecutingAssembly().Location might do what you need.

Oleks
  • 31,955
  • 11
  • 77
  • 132
William Edmondson
  • 3,619
  • 3
  • 32
  • 41
  • 2
    Additionally, you can have several "active" config files at the same time. Machine.config, framework level web.config, app level config, etc... so I don't think there is a way to automatically locate a unique connection string file location without parsing through all the possible config files available to your app. – William Edmondson Apr 27 '09 at 14:16