从不同于app二进制目录的位置加载WPF app.config / MyApp.exe.config

时间:2012-11-27 12:54:44

标签: c# configuration settings app-config config

  1. 我想从app bin文件夹的子文件夹而不是app bin文件夹本身加载MyApp.exe.config(例如./Configs/MyApp.exe.config)。
  2. 我不想使用System.Configuration对象(由ConfigurationManager.OpenExeConfiguration(configPath)返回),因为这只是一个字符串映射。我想继续使用现有生成的Settings:ApplicationSettingsBase对象在Settings中.Designer.cs,因为它具有转换为适当对象的设置值。
  3. 即我只想重定向设置加载自身的位置。我看了一下,我能找到的所有解决方案都直接直接使用System.Configuration对象 - 但如何将其重新连接到设置?

    想要做什么似乎是合理的事情 - 无法理解为什么它看起来如此困难?欢迎任何解决方案!

3 个答案:

答案 0 :(得分:4)

当app.config中有一个configSection时,Jims解决方案很干净。在我们的例子中,我们有几个configSections(对于app,libraries,nlog等),我们只想从新位置加载整个文件。从orignal问题来看,这并不是很清楚。

最简单的方法是使用带有AppDomainSetup对象的新AppDomain,我们将ConfigurationFile属性设置为新配置文件的路径。
问题是何时以及如何创建新的应用程序域。 This post提供了一个优雅的解决方案,似乎只需稍加修改即可。

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事件处理程序。当新的应用程序域被finsihed(应用程序已关闭)时,只需将其关闭为“外部”应用程序域中的中止启动。这样可以避免进行跨应用程序域调用或使用引导程序应用程序来创建新的应用程序域。

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

答案 1 :(得分:1)

您需要的是自定义SettingsProvider。本地应用程序的默认值为LocalFileSettingsProvider,它从appname.exe所在目录中的appname.exe.config文件中获取设置。您可以创建一个派生自LocalFileSettingsProvider的类,该类在不同的目录中查找。如果做不到这一点,你必须从SettingsProvider派生。

另见ApplicationSettingsBase.Providers property

答案 2 :(得分:0)

如果您的应用程序中没有线程/后台任务,那么Ricibob的解决方案可以正常工作。如果你有它们会导致问题。此外,您可以在一行中实现上述解决方案:

 AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", YOUR_CONFIG_LOCATION);