将app.config文件重定位到自定义路径

时间:2022-06-29 23:13:16

Is it possible to relocate the whole App.Config file to a custom path?

是否可以将整个App.Config文件重定位到自定义路径?

It seems a bit odd that the config file resides in the same folder as the exe, with Windows' new approcah of saving all program settings in c:\ProgramData and all.

配置文件与exe文件位于同一文件夹中似乎有点奇怪,Windows的新approcah保存了c:\ ProgramData和all中的所有程序设置。

An additional requirement we have is to programatically specify where to find the app.config file. The reason for this being that we spawn different service instances from the same exes, and would like to store each service's app.config in that service's settings folder under c:\ProgramData\\.

我们的另一个要求是以编程方式指定在哪里找到app.config文件。这样做的原因是我们从同一个exes生成不同的服务实例,并希望将每个服务的app.config存储在c:\ ProgramData \\下该服务的settings文件夹中。

8 个解决方案

#1


14  

Each AppDomain has/can have its own configuration file. The default AppDomain created by CLR host uses programname.exe.config; if you want to provide your own configuration file, create separate AppDomain. Example:

每个AppDomain都有/可以拥有自己的配置文件。 CLR主机创建的默认AppDomain使用programname.exe.config;如果要提供自己的配置文件,请创建单独的AppDomain。例:

// get the name of the assembly
string exeAssembly = Assembly.GetEntryAssembly().FullName;

// setup - there you put the path to the config file
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = System.Environment.CurrentDirectory;
setup.ConfigurationFile = "<path to your config file>";

// create the app domain
AppDomain appDomain = AppDomain.CreateDomain("My AppDomain", null, setup);

// create proxy used to call the startup method 
YourStartupClass proxy = (YourStartupClass)appDomain.CreateInstanceAndUnwrap(
       exeAssembly, typeof(YourStartupClass).FullName);

// call the startup method - something like alternative main()
proxy.StartupMethod();

// in the end, unload the domain
AppDomain.Unload(appDomain);

Hope that helps.

希望有所帮助。

#2


33  

If still relevant, we have used the following I found on another suggested answer to another question here on Stack Overflow...

如果仍然相关,我们在Stack Overflow上使用了以下我在另一个问题的另一个建议答案中找到的...

AppDomain.CurrentDomain.SetData ("APP_CONFIG_FILE", "path to config file")

Worked great for us when we had issues loading app.config from DLL only...

当我们从DLL加载app.config时遇到问题时,我们工作得很好...

#3


4  

This worked for me.. (taken from http://msdn.microsoft.com/en-us/library/system.configuration.appsettingssection.aspx)

这对我有用..(摘自http://msdn.microsoft.com/en-us/library/system.configuration.appsettingssection.aspx)

// open config
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

// update appconfig file path
config.AppSettings.File = "C:\\dev\\App.config";

// Save the configuration file.
config.Save(ConfigurationSaveMode.Modified);

// Force a reload in memory of the changed section.
ConfigurationManager.RefreshSection("appSettings");

Then when you call

然后当你打电话

NameValueCollection settings = System.Configuration.ConfigurationManager.AppSettings;

or any operation to fetch the app config, the new path is used.

或任何获取应用程序配置的操作,都使用新路径。

Hope this might help someone else who has same problem!

希望这可以帮助其他有同样问题的人!

#4


4  

I know this is an old question, but for those who just want to have their app.config in a different location then their binary output build location, the following works as microsoft intended it (and thus no need re-read and re-write the file to disk)

我知道这是一个老问题,但是对于那些只想将app.config放在不同位置然后是二进制输出构建位置的人来说,下面的工作就像微软想要的那样(因此不需要重新读取和重写)文件到磁盘)

  • Define an app.config as you always do.
  • 像往常一样定义app.config。
  • Define another config file where you want to have the actual configuration file
  • 定义另一个要包含实际配置文件的配置文件
  • Change the app.config so that it refers to the configuration file
  • 更改app.config以使其引用配置文件

At runtime the settings from the configuration file will override the settings in the app.config (if present). And you are done.

在运行时,配置文件中的设置将覆盖app.config中的设置(如果存在)。你完成了。

Example app.config

示例app.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
    </startup>
  <appSettings file="..\Config\settings.config">
    <add key="port" value="1001"/>
  </appSettings>
</configuration>

Note the file="..\Config\settings.config". You are completely free to define the path to the location where you want your users to change settings.

请注意file =“.. \ Config \ settings.config”。您可以完全*地定义希望用户更改设置的位置的路径。

Example of the actual configuration file

实际配置文件的示例

<?xml version="1.0" encoding="utf-8"?>
<appSettings>
  <add key="port" value="1234"/>
</appSettings>

At runtime the setting port will have the value 1234.

在运行时,设置端口的值为1234。

More info see msdn

更多信息,请参阅msdn

#5


2  

This is an ancient question, but I ran into this same problem and came up with a hacky workaround from a few minutes in reflector:

这是一个古老的问题,但是我遇到了同样的问题,并在反射器中提出了几分钟的hacky解决方法:

static public class ConfigHack {
    static public void OverrideAppConfig(string path) {
        ((AppDomainSetup)
            typeof(AppDomain)
                .GetField("_FusionStore", BindingFlags.NonPublic | BindingFlags.Instance)
                .GetValue(AppDomain.CurrentDomain))
        .ConfigurationFile = path;
    }

    static public void ResetConfigManager() {
        typeof(ConfigurationManager)
            .GetField("s_initState", BindingFlags.Static | BindingFlags.NonPublic)
            .SetValue(null, 0);
    }
}

I've only used it on .NET2, but it looks the same in 4 in reflector. Of course I wouldn't recommend shipping this :P I only use it for quick internal things.

我只在.NET2上使用它,但在反射器中看起来相同。当然我不建议发货:P我只用它来快速内部的东西。

#6


1  

I am sorry if I misunderstand your request but can you not use

如果我误解了您的请求,我很抱歉,但您不能使用

ConfigurationManager.OpenExeConfiguration Method (String)

ConfigurationManager.OpenExeConfiguration方法(String)

Based on the change, is it possible that you can use

根据变化,您是否可以使用

AppDomainSetup.ConfigurationFile Property

AppDomainSetup.ConfigurationFile属性

#7


0  

You could use astander's approach of calling OpenExeConfiguration. If you literally want to relocate your config file, you'll have to create your own app domain. In the process of setting up your app domain you get the chance to specify where the config file is located.

您可以使用旁观者调用OpenExeConfiguration的方法。如果您真的想重新定位配置文件,则必须创建自己的应用程序域。在设置应用程序域的过程中,您可以指定配置文件的位置。

BTW, .NET config files aren't great for configuration, at least not the sort that users can modify: they're not like INI files or the registry. If you want flexibility over where your configuration comes from you're better off storing it separately.

BTW,.NET配置文件不适合配置,至少不是用户可以修改的类型:它们不像INI文件或注册表。如果您希望灵活配置来自您的配置,最好将其单独存储。

#8


-2  

MSDN probably would help...

MSDN可能会有所帮助......

The element simplifies servicing for component assemblies. If one or more applications use an assembly that has a configuration file residing in a well-known location, the configuration files of the applications that use the assembly can use the element to include the assembly configuration file, rather than including configuration information directly. When the component assembly is serviced, updating the common configuration file provides updated configuration information to all applications that use the assembly

该元件简化了组件装配的维护。如果一个或多个应用程序使用具有驻留在众所周知位置的配置文件的程序集,则使用该程序集的应用程序的配置文件可以使用该元素包含程序集配置文件,而不是直接包含配置信息。在维护组件程序集时,更新公共配置文件会向使用该程序集的所有应用程序提供更新的配置信息

#1


14  

Each AppDomain has/can have its own configuration file. The default AppDomain created by CLR host uses programname.exe.config; if you want to provide your own configuration file, create separate AppDomain. Example:

每个AppDomain都有/可以拥有自己的配置文件。 CLR主机创建的默认AppDomain使用programname.exe.config;如果要提供自己的配置文件,请创建单独的AppDomain。例:

// get the name of the assembly
string exeAssembly = Assembly.GetEntryAssembly().FullName;

// setup - there you put the path to the config file
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = System.Environment.CurrentDirectory;
setup.ConfigurationFile = "<path to your config file>";

// create the app domain
AppDomain appDomain = AppDomain.CreateDomain("My AppDomain", null, setup);

// create proxy used to call the startup method 
YourStartupClass proxy = (YourStartupClass)appDomain.CreateInstanceAndUnwrap(
       exeAssembly, typeof(YourStartupClass).FullName);

// call the startup method - something like alternative main()
proxy.StartupMethod();

// in the end, unload the domain
AppDomain.Unload(appDomain);

Hope that helps.

希望有所帮助。

#2


33  

If still relevant, we have used the following I found on another suggested answer to another question here on Stack Overflow...

如果仍然相关,我们在Stack Overflow上使用了以下我在另一个问题的另一个建议答案中找到的...

AppDomain.CurrentDomain.SetData ("APP_CONFIG_FILE", "path to config file")

Worked great for us when we had issues loading app.config from DLL only...

当我们从DLL加载app.config时遇到问题时,我们工作得很好...

#3


4  

This worked for me.. (taken from http://msdn.microsoft.com/en-us/library/system.configuration.appsettingssection.aspx)

这对我有用..(摘自http://msdn.microsoft.com/en-us/library/system.configuration.appsettingssection.aspx)

// open config
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

// update appconfig file path
config.AppSettings.File = "C:\\dev\\App.config";

// Save the configuration file.
config.Save(ConfigurationSaveMode.Modified);

// Force a reload in memory of the changed section.
ConfigurationManager.RefreshSection("appSettings");

Then when you call

然后当你打电话

NameValueCollection settings = System.Configuration.ConfigurationManager.AppSettings;

or any operation to fetch the app config, the new path is used.

或任何获取应用程序配置的操作,都使用新路径。

Hope this might help someone else who has same problem!

希望这可以帮助其他有同样问题的人!

#4


4  

I know this is an old question, but for those who just want to have their app.config in a different location then their binary output build location, the following works as microsoft intended it (and thus no need re-read and re-write the file to disk)

我知道这是一个老问题,但是对于那些只想将app.config放在不同位置然后是二进制输出构建位置的人来说,下面的工作就像微软想要的那样(因此不需要重新读取和重写)文件到磁盘)

  • Define an app.config as you always do.
  • 像往常一样定义app.config。
  • Define another config file where you want to have the actual configuration file
  • 定义另一个要包含实际配置文件的配置文件
  • Change the app.config so that it refers to the configuration file
  • 更改app.config以使其引用配置文件

At runtime the settings from the configuration file will override the settings in the app.config (if present). And you are done.

在运行时,配置文件中的设置将覆盖app.config中的设置(如果存在)。你完成了。

Example app.config

示例app.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
    </startup>
  <appSettings file="..\Config\settings.config">
    <add key="port" value="1001"/>
  </appSettings>
</configuration>

Note the file="..\Config\settings.config". You are completely free to define the path to the location where you want your users to change settings.

请注意file =“.. \ Config \ settings.config”。您可以完全*地定义希望用户更改设置的位置的路径。

Example of the actual configuration file

实际配置文件的示例

<?xml version="1.0" encoding="utf-8"?>
<appSettings>
  <add key="port" value="1234"/>
</appSettings>

At runtime the setting port will have the value 1234.

在运行时,设置端口的值为1234。

More info see msdn

更多信息,请参阅msdn

#5


2  

This is an ancient question, but I ran into this same problem and came up with a hacky workaround from a few minutes in reflector:

这是一个古老的问题,但是我遇到了同样的问题,并在反射器中提出了几分钟的hacky解决方法:

static public class ConfigHack {
    static public void OverrideAppConfig(string path) {
        ((AppDomainSetup)
            typeof(AppDomain)
                .GetField("_FusionStore", BindingFlags.NonPublic | BindingFlags.Instance)
                .GetValue(AppDomain.CurrentDomain))
        .ConfigurationFile = path;
    }

    static public void ResetConfigManager() {
        typeof(ConfigurationManager)
            .GetField("s_initState", BindingFlags.Static | BindingFlags.NonPublic)
            .SetValue(null, 0);
    }
}

I've only used it on .NET2, but it looks the same in 4 in reflector. Of course I wouldn't recommend shipping this :P I only use it for quick internal things.

我只在.NET2上使用它,但在反射器中看起来相同。当然我不建议发货:P我只用它来快速内部的东西。

#6


1  

I am sorry if I misunderstand your request but can you not use

如果我误解了您的请求,我很抱歉,但您不能使用

ConfigurationManager.OpenExeConfiguration Method (String)

ConfigurationManager.OpenExeConfiguration方法(String)

Based on the change, is it possible that you can use

根据变化,您是否可以使用

AppDomainSetup.ConfigurationFile Property

AppDomainSetup.ConfigurationFile属性

#7


0  

You could use astander's approach of calling OpenExeConfiguration. If you literally want to relocate your config file, you'll have to create your own app domain. In the process of setting up your app domain you get the chance to specify where the config file is located.

您可以使用旁观者调用OpenExeConfiguration的方法。如果您真的想重新定位配置文件,则必须创建自己的应用程序域。在设置应用程序域的过程中,您可以指定配置文件的位置。

BTW, .NET config files aren't great for configuration, at least not the sort that users can modify: they're not like INI files or the registry. If you want flexibility over where your configuration comes from you're better off storing it separately.

BTW,.NET配置文件不适合配置,至少不是用户可以修改的类型:它们不像INI文件或注册表。如果您希望灵活配置来自您的配置,最好将其单独存储。

#8


-2  

MSDN probably would help...

MSDN可能会有所帮助......

The element simplifies servicing for component assemblies. If one or more applications use an assembly that has a configuration file residing in a well-known location, the configuration files of the applications that use the assembly can use the element to include the assembly configuration file, rather than including configuration information directly. When the component assembly is serviced, updating the common configuration file provides updated configuration information to all applications that use the assembly

该元件简化了组件装配的维护。如果一个或多个应用程序使用具有驻留在众所周知位置的配置文件的程序集,则使用该程序集的应用程序的配置文件可以使用该元素包含程序集配置文件,而不是直接包含配置信息。在维护组件程序集时,更新公共配置文件会向使用该程序集的所有应用程序提供更新的配置信息