繁体   English   中英

从与应用程序二进制目录不同的位置加载WPF app.config / MyApp.exe.config

[英]Load a WPF app.config / MyApp.exe.config from a location different from the app binary directory

  1. 我想从应用程序bin文件夹的子文件夹而不是应用程序bin文件夹本身(例如./Configs/MyApp.exe.config)加载MyApp.exe.config。
  2. 我不想使用System.Configuration对象(由ConfigurationManager.OpenExeConfiguration(configPath)返回),因为这只是一个字符串映射。我想继续使用Settings.Designer中现有的生成的Settings:ApplicationSettingsBase对象。 cs,因为它具有将设置值强制转换为适当的对象。

即我只想重定向设置从中加载自身的位置。 我看了一眼,发现的解决方案都涉及直接与System.Configuration对象直接工作-但是如何将其重新连接到Settings?

似乎有点想做的事-无法理解为什么看起来如此困难? 任何解决方案最欢迎!

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

最简单的方法似乎是使用带有AppDomainSetup对象的新AppDomain,在该对象上我们将ConfigurationFile属性设置为新配置文件的路径。
然后的问题是何时以及如何创建新的应用程序域。 这篇文章提供了一个优雅的解决方案,似乎可以对其进行一些小的修改。

1:添加启动事件处理程序:

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

您需要的是自定义SettingsProvider 本地应用程序的默认值为LocalFileSettingsProvider ,它从与appname.exe相同目录中的appname.exe.config文件获取设置。 您也许可以创建一个从LocalFileSettingsProvider派生的类,该类在另一个目录中。 否则,您必须从SettingsProvider派生。

另请参见ApplicationSettingsBase.Providers属性

如果您的应用程序中没有线程/背景任务,那么Ricibob的解决方案就可以正常工作。 如果确实有它们,则会引起问题。 此外,您可以在一行中实现上述解决方案:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM