Jims solution is clean when you have a single configSection in the app.config. In our case we have several configSections (for app, libraries, nlog etc) and we want to just load the whole file from a new location. This wasnt really clear from the orignal question.
The eaisest way to do this seemed to be to use a new AppDomain with an AppDomainSetup object on which we set the ConfigurationFile property to path to new config file.
The question is then when and how to create the new app domain. This post offers an elegant solution that seems to work with minor modifications.
1: Add a Startup event handler:
Application x:Class="InstallTool.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml"
Startup="AppStartup"
2: In that handler (in the default application domain) create a new application domain - the creation of which just recursively calls the Startup event handler. When the new app domain is finsihed with (app closed) just closed it an abort startup in the "outer" app domain. This avoids having to make cross app domain calls or have a bootstrapper app to create the new app domain.
public void AppStartup(object sender, StartupEventArgs e) {
if (AppDomain.CurrentDomain.IsDefaultAppDomain()) {
string appName = AppDomain.CurrentDomain.FriendlyName;
var currentAssembly = Assembly.GetExecutingAssembly();
// Setup path to application config file in ./Config dir:
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = System.Environment.CurrentDirectory;
setup.ConfigurationFile = setup.ApplicationBase +
string.Format("\\Config\\{0}.config", appName);
// Create a new app domain using setup with new config file path:
AppDomain newDomain = AppDomain.CreateDomain("NewAppDomain", null, setup);
int ret = newDomain.ExecuteAssemblyByName(currentAssembly.FullName, e.Args);
// Above causes recusive call to this method.
//--------------------------------------------------------------------------//
AppDomain.Unload(newDomain);
Environment.ExitCode = ret;
// We get here when the new app domain we created is shutdown. Shutdown the
// original default app domain (to avoid running app again there):
// We could use Shutdown(0) but we have to remove the main window uri from xaml
// and then set it for new app domain (above execute command) using:
// StartupUri = new Uri("Window1.xaml", UriKind.Relative);
Environment.Exit(0);
return;
}
}