Click here to Skip to main content
Click here to Skip to main content

Specify a Configuration File at Runtime for a C# Console Application

By , 14 Jun 2006
 

Introduction

When building a console app, it is often necessary to provide various settings. Adding an app.config file to your project allows you to store all your settings in a file that is processed at runtime. When compiled, app.config becomes yourapp.exe.config.

This is great until you need to run a large collection of different settings depending on the circumstance. There are a few ways I have seen to deal with this:

  1. Create a number of config files with the correct keys and before runtime, name the config file you want to use as yourapp.exe.config. Workable, but since you are always renaming files, it may become difficult to determine which settings have been run and which have not.
  2. Create custom tags in the app.config (see simple two-dimensional configuration file), then via another key set which section is the setting you want during the current run. This is the solution I have seen a number of times on the Internet. This is a workable solution, but it can lead to unwieldy app.config files, depending on the number of keys and configurations.

I was not satisfied with both of these solutions. What I wanted was the ability to specify at runtime which config file to use. In this way, I can keep settings for different configurations neatly separated. Here is how I did this.

A Console App

using System;
using System.Configuration;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Net;

namespace yournamepace
{
    class Program
    {
        static void Main(string[] args)
        {
            // get config file from runtime args
            // or if none provided, request config
            // via console
            setConfigFileAtRuntime(args);

            // Rest of your console app
        }
    }

    protected static void setConfigFileAtRuntime(string[] args)
    {
        string runtimeconfigfile;

        if (args.Length == 0)
        {
            Console.WriteLine("Please specify a config file:");
            Console.Write("> "); // prompt
            runtimeconfigfile = Console.ReadLine();
        }
        else
        {
            runtimeconfigfile = args[0];
        }

        // Specify config settings at runtime.
        System.Configuration.Configuration config
    = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        config.AppSettings.File = runtimeconfigfile;
        config.Save(ConfigurationSaveMode.Modified);
        ConfigurationManager.RefreshSection("appSettings");
    }
}

app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <!--
    App settings are specified at runtime.
    Need to specify at minimum this stub file
    -->
    <appSettings></appSettings>
</configuration>

Typical Runtime Config File 1

<appSettings>
    <add key="anykey1" value="anyvalue1" />
    <add key="anykey2" value="anyvalue2"/>
</appSettings>

Typical Runtime Config File 2

<appSettings>
    <add key="anykey1" value="anothervalue1" />
    <add key="anykey2" value="anothervalue2"/>
</appSettings>

Now, at runtime, you do the following from the command prompt:

c:\> yourapp.exe myruntimeconfigfile1.config
c:\> yourapp.exe myruntimeconfigfile2.config

Or just double click yourapp.exe, and you will be prompted for a config file.

History

  • 15th June, 2006: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

braditude
Web Developer
United States United States
Member
Software Design Engineer working at Bluetooth Special Interest Group.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralOther Section and SectionGroupsmemberTobias Manthey23 Jan '09 - 0:17 
Hi,
 
The example is pretty much limited to the appSettings section. Any idea how to do the same for other Sections and SectionGroups?
 
Thanks,
Tobias
GeneralRe: Other Section and SectionGroupsmembertharnjaggar8 Nov '10 - 1:04 
Only solution (and imho, also for the appSettings) is to load a fresh appDomain. That way you can maintain true separated config files. See example below:
 


namespace CfgTest
{
public class Program : MarshalByRefObject
{
static void Main(string[] args)
{
string runtimeconfigfile;
 
if (args.Length == 0)
{
Console.WriteLine("Please specify a config file:");
Console.Write("> "); // prompt
runtimeconfigfile = Console.ReadLine();
}
else
{
runtimeconfigfile = args[0];
}
 
// Specify config settings at runtime.
AppDomainSetup setup = new AppDomainSetup();
setup.ConfigurationFile = runtimeconfigfile;
AppDomain newDomain = AppDomain.CreateDomain("newConfigDomain", null, setup);
Program prg = (Program)newDomain.CreateInstanceFromAndUnwrap("CfgTest.exe", "CfgTest.Program");
prg.Do();
AppDomain.Unload(newDomain);
}
 
public void Do()
{
Console.Out.WriteLine("anykey1 = " + ConfigurationManager.AppSettings["anykey1"]);
Console.Out.WriteLine("anykey2 = " + ConfigurationManager.AppSettings["anykey2"]);
}
}
}

 
If your application is heavy, to avoid overhead of having it loaded twice, you can make a simple separate .exe just loading the app domain setup and running the heavy app with wanted config (also needed if your application can't herit from MarshalByRefObject which is needed).
 
Hope that helps.
/tharn
GeneralRe: Other Section and SectionGroupsmemberMr. Noname30 Dec '10 - 7:28 
or simply: (albeit entirely framework-dependent)
 
static void Main(string[] args)
{
  ((AppDomainSetup)typeof(AppDomain).GetProperty("FusionStore", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(AppDomain.CurrentDomain, null)).ConfigurationFile = @"C:\....";
  ...

Questionencrypting ConnectionStrings section in App.Config file?memberRakesh.Gunijan15 Mar '07 - 3:37 
How to do this???
Jokeworkable option (c#) [modified]memberdvhh3 Jul '06 - 14:30 
for .NET 1.1
 
Hashtable runtimeConfig;
XmlDocument runtimeConfigXML;
DictionarySectionHandler dsh=new DictionarySectionHandler();
 
runtimeConfigXML=new XmlDocument();
runtimeConfigXML.Load("yourfile.config");
 
runtimeConfig=(Hashtable)dsh.Create(null,null,runtimeConfigXML.FirstChild );
 
-- modified at 6:04 Tuesday 4th July, 2006
 
the code given by braditude only work on .NET 2.0
coders should give framework version their code is working on.
GeneralRe: workable option (c#)memberJürgen Müller (jmse)4 Jul '06 - 2:09 
Hi,
 
this works and will do so far.
 
Regards
 
Jürgen
GeneralRe: workable option (c#)memberJürgen Müller (jmse)4 Jul '06 - 23:00 
I'm using .NET 2.0 - nervertheless, it's not working Frown | :(
Questionnot workingmemberJürgen Müller (jmse)3 Jul '06 - 1:36 
Hi, braditude.
 
I'm trying to use your code but it doesn't work.
It seems that the file is not loaded. If I use keys which are directly written
into the app.config file the values can be read - if I try to uses the keys
in the MySettings.xml file, it doesn't work (there are no keys at all).
Any ideas?
 
Reagrds
 
Jürgen
 
My code:
Configuration config = ConfigurationManager.OpenExeConfiguration( ConfigurationUserLevel.None);
config.AppSettings.File = @"c:\temp\MySettings.xml";
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
string s = config.AppSettings.Settings["myKey"].Value;
s = config.AppSettings.Settings["anotherKey"].Value;


QuestionRe: not workingmemberanand vivek29 Sep '08 - 3:46 
Any body got the solution for this....

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 15 Jun 2006
Article Copyright 2006 by braditude
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid