Relocating app.config file to a custom path
Asked Answered
L

9

34

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

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.

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\\.

Lysol answered 3/12, 2009 at 8:59 Comment(1)
the default behavious is the a program has 1 default config file in its own director and each user has their own config file stored in their user area, bu default any settings set to user will be pulled from the users config unless not present then it will use the programs configOffwhite
C
18

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:

// 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.

Consumer answered 3/12, 2009 at 10:12 Comment(4)
I tried this for an application that used WCF, but it wouldn't work (correct me if I'm wrong). Any ideas on how to relocate app.config for an app that uses WCF?Gymkhana
@Gravitas: If it is still relevant for you: I found a solution: #6151144Fluoride
Useful to learn that programName.exe.config is where app.config ends up. Thank you for the information.Lancaster
More specifically, AssemblyName.exe.configDafna
R
44

If still relevant, we have used the following I found on another suggested answer to another question here on 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...

Rance answered 3/10, 2012 at 12:23 Comment(1)
If you use that technique certain sections of configuration will not be applied. For example <runtime>.Piss
C
18

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:

// 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.

Consumer answered 3/12, 2009 at 10:12 Comment(4)
I tried this for an application that used WCF, but it wouldn't work (correct me if I'm wrong). Any ideas on how to relocate app.config for an app that uses WCF?Gymkhana
@Gravitas: If it is still relevant for you: I found a solution: #6151144Fluoride
Useful to learn that programName.exe.config is where app.config ends up. Thank you for the information.Lancaster
More specifically, AssemblyName.exe.configDafna
E
9

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)

  • Define an app.config as you always do.
  • 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

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

Example 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.

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.

More info see msdn

Edict answered 17/12, 2014 at 18:36 Comment(1)
Note: This just for loading the appSettings section from a separate file. It isn't loading the entire app.config from another locationDuplication
A
7

This worked for me.. (taken from 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!

Advisee answered 15/4, 2014 at 10:7 Comment(1)
This approach works if you have an app.config with only <appSettings> class at root level. Otherwise it throws an exception. (VB.NET 4.5.2)Uriah
S
2

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

ConfigurationManager.OpenExeConfiguration Method (String)

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

AppDomainSetup.ConfigurationFile Property

Stemware answered 3/12, 2009 at 9:5 Comment(3)
This would help for cases where I manually read setting from the config, but not for the sections that .NET reads itself, such as WCF setup and ConnectionStrings etc.Lysol
You can only modify AppDomainSetup.ConfigurationFile during the process of creating a new app domain. You can't modify it once your app domain is running.Jovian
@Lysol - I agree - I just tried it to load a custom .config file for WCF, and it just didn't work (correct me if I'm wrong!). Any ideas on how to relocate the .config file for an app that uses WCF?Gymkhana
M
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:

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.

Mccue answered 9/2, 2011 at 21:29 Comment(2)
If using .NET 4.5, you can replace this code with "AppDomain.CurrentDomain.SetData ("APP_CONFIG_FILE", "path to config file")" (see answer below). I have verified this and it works perfectly (it loads a new app.config into the current app domain).Gymkhana
Yes, APP_CONFIG_FILE works for me. Still have to use the ResetConfigManager() hack and RefreshSection("appSettings"). This whole .net configuration thing calls for a complete rewrite!Clarisclarisa
J
1

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.

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.

Jovian answered 3/12, 2009 at 9:21 Comment(0)
P
-1

If u use the registry, your problem can be resolved.

Pretypify answered 16/3, 2020 at 7:59 Comment(0)
R
-3

MSDN probably would help...

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

Rosaliarosalie answered 3/12, 2009 at 9:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.