app.config に単一の configSection がある場合、Jims ソリューションはクリーンです。私たちの場合、いくつかの configSections (アプリ、ライブラリ、nlog など) があり、新しい場所からファイル全体をロードしたいだけです。これは、元の質問からは明確ではありませんでした。
これを行う最も簡単な方法は、ConfigurationFile プロパティを新しい構成ファイルへのパスに設定した AppDomainSetup オブジェクトで新しい AppDomain を使用することです。
問題は、新しいアプリ ドメインをいつ、どのように作成するかです。 この投稿は、わずかな変更で機能するように見えるエレガントなソリューションを提供します。
1: Startup イベント ハンドラーを追加します。
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: そのハンドラー (既定のアプリケーション ドメイン) で、新しいアプリケーション ドメインを作成します。その作成では、Startup イベント ハンドラーを再帰的に呼び出すだけです。新しいアプリ ドメインが終了すると (アプリが閉じられます)、「外側の」アプリ ドメインでスタートアップが中止されます。これにより、アプリ ドメイン間の呼び出しを行ったり、ブートストラップ アプリを使用して新しいアプリ ドメインを作成したりする必要がなくなります。
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;
}
}