App.config Magic In Visual Studio
One area that causes lots of confusion to developers is the behavior of app.config while running within Visual Studio. Because VS treats app.config specially it can be confusing when app.config does not work the way we expect. This post will clarify how the config file is treated while running inside VS. But first an aside.
Visual Studio Hosting Process
Debugging another process is not trivial. There are lots of details to worry about. Consequently debuggers are not simple pieces of code. Starting a debugger can be expensive. Beginning a few versions back VS started using the VS hosting process for debugging processes. This process (vshost) is a wrapper around the debugger. It allows the debugger to be started onced and then continue to run between debug sessions. This helps to alleviate the overhead of the debugger and to also allow the debugger to maintain information between debugging sessions.
The vshost process is started when VS loads a project that is using it. You can see this by using Task Manager to see the running processes. The actual process is called <project>.vshost.exe. It is within this process that your code runs rather than through the normal <process>.exe. Running through a host process is generally the best idea but it can cause some issues. Therefore in the Debug properties of the executable’s project settings is an option to turn off the hosting process.
In .NET an application configuration file is required to be called <process>.exe.config. This is the file that the configuration subsystem will load. The file must reside in the same directory as the executable. Because VS recreates the output directory each time you build you cannot just create this file and store it in the output directory. Instead when you add an Application Configuration File item to your project it is added to the root of the project and called app.config. This file is automatically copied to the output directory and renamed on each build. Therefore after each build you will have a brand new configuration file. Note that if you call the file anything else then this process will not work. Rarely should you change the name.
For most development you will edit the configuration file in VS. These changes will be automatically seen when the program runs under the debugger. However if you make changes to the configuration file at runtime (while running under the debugger) the changes will only persist until the next build. At that time VS will overwrite the file with the root copy. Therefore you CAN NOT run your program and modify the project’s configuration file. The only way to emulate this behavior would be to copy the (modified) configuration back to the root project and rename it. As an aside note that if you modify the configuration file at runtime but do not rebuild your code then the configuration changes may persist.
Which Config Is Which?
One area of confusion is which configuration file your application is actually using while running under the debugger. Many people will say it is the <process>.exe.config file but that is only partially correct. Remember the vshost process of earlier? It complicates things. Remember that if you are using the VS host (the default) then your process is actually <process>.vshost.exe. The configuration subsystem knows nothing about the VS host process so it expects to load the <process>.vshost.exe.config file. When a project is configured to use the hosting process then VS will copy the standard <process>.exe.config file to <process>.vshost.exe.config when the debugger starts. This gives the appearance that the hosting process is using the application’s configuration file when in fact it is VS that is just copying the file for us. More importantly the configuration subsystem is not impacted by this change at all. If the program modifies the configuration file while it runs then those changes are made to the <process>.vshost.exe.config file. The actual process’s configuration and the project’s app.config files are not modified.
DLL Config Files – Myth or Fact?
Many class libraries (DLLs) require configuration information. Most devs like to rely on the configuration subsystem to store this information. Makes sense. If you add an application configuration to the class library project then VS will copy the app.config to the output directory and call it <project>.dll.config as you would expect. It behaves just like a standard Windows application project. Here’s the issue though – the configuration subsystem neither understands nor supports these files. Let me say it again. The configuration subsystem WILL NOT load .dll.config files.
Technically you can change the mappings used by the subsystem to get it to load the files but that is beyond the scope of this article and beyond most applications. The configuration subsystem will only load the <process>.exe.config file. There are forum postings all the time from devs who are confused as to why their dll.config file contains some configuration section but the configuration subsystem won’t read it. They believe, incorrectly, that the subsystem uses the configuration file associated with the assembly that is calling it. That is false. The subsystem only reads the application’s configuration file.
There are two possible workarounds to this issue. The first workaround, the most common, is to merge the dll.config file into the application’s configuration. This is generally the easiest approach and can be done at build time. The alternative approach is to read the configuration file manually at runtime. Some complex libraries follow this route but I cannot recommend it. That is just too much code to write.