1

I have a console program 'A' that at a given point will run program 'B' and program 'C'. However I'm having an issue with the app.config associate with each of the program. Basically program A is just a wrapper class that calls different console application, It should not have any app.config but it should use the current running program's app config. So in theory there should be only 2 app.config one for Program B and another for program C.

So if we run Program A and program B gets executed, it should use program B's app.config to get the information and after when program C gets executed it should use Program C's app.config.

Is there a way to do this? Currently i'm doing this:

var value =  ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location).AppSettings.Settings["ProgramBKey"].Value;

It does not seem to work. I checked the debug on Assembly.GetExecutingAssembly().Location it's variable is the \bin\Debug\ProgramB.exe and 'ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location).AppSettings' has setting with Count=0 when there are key values as seen below.

sample code Program A:

static void Main(string[] args)
{
    if(caseB)
        B.Program.Main(args)
    else if(caseC)
        C.Program.Main(args)
}

sample app.config for Program B:

<?xml version="1.0"?>
<configuration>
  <appSettings> 
    <add key="ProgramBKey" value="Works" />
  </appSettings>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
  </startup>
</configuration>
civic.sir
  • 400
  • 1
  • 9
  • 26

4 Answers4

3

Edit: the following answer pertains to this question from the original post, "Is it possible to compile the app.config for B and C within the exe of the program."

You can use the "Embedded Resource" feature. Here's a small example of using an XML file that's been included as an embedded resource:

public static class Config
{
    static Config()
    {
        var doc = new XmlDocument();
        using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Fully.Qualified.Name.Config.xml"))
        {
            if (stream == null)
            {
                throw new EndOfStreamException("Failed to read Fully.Qualified.Name.Config.xml from the assembly's embedded resources.");
            }

            using (var reader = new StreamReader(stream))
            {
                doc.LoadXml(reader.ReadToEnd());
            }
        }

        XmlElement aValue = null;
        XmlElement anotherValue = null;

        var config = doc["config"];
        if (config != null)
        {
            aValue = config["a-value"];
            anotherValue = config["another-value"];
        }

        if (aValue == null || anotheValue == null)
        {
            throw new XmlException("Failed to parse Config.xml XmlDocument.");
        }

        AValueProperty = aValue.InnerText;
        AnotherValueProperty = anotherValue.InnerText;
    }
}
Dan Forbes
  • 2,734
  • 3
  • 30
  • 60
  • 1
    updated the question .. this answer was right in the context before... but i guess the question was not clear enough – civic.sir Jul 06 '16 at 16:01
1

You can have multiple application using the same config file. That way when you switch applications, they can both find their own parts of the config file.

The way I usually do it is... first let each application "do its own thing", then copy the relevant sections of config file A into config file B.

It will look like this:

<configSections>
    <sectionGroup>
         <sectionGroup name="applicationSettings"...A>
         <sectionGroup name="userSettings"...A>
         <sectionGroup name="applicationSettings"...B>
         <sectionGroup name="userSettings"...B>

<applicationSettings>
    <A.Properties.Settings>
    <B.Properties.Settings>

<userSettings>
    <A.Properties.Settings>
    <B.Properties.Settings>
egray
  • 390
  • 1
  • 4
  • Only problem with this is that if there any changes to Program B config file we will have to also update Program A's config file for the part that was changed no? So there needs to be a update to app.config (for ProgramA) every time there is a change in any of the programs – civic.sir Jul 06 '16 at 15:16
0

For me, the whole thing sounds like a "design issue". Why should you want to open Programm B with the config of Programm A?

Are you the author of all those Programms? You might want to use a dll-file instead. This will save you the trouble as all code runs with the config of the Programm running.

Woozar
  • 1,000
  • 2
  • 11
  • 35
  • The reason why it's running from A is because Program B can be a stand alone console application itself. Thats why i couldn't make it a dll. But if i had made them into a dll (yes i'm author of all the programs) would that solve the issue for app.config? – civic.sir Jul 06 '16 at 14:39
  • for example a user can run program B independent from any other. Program A is just a helper to figure out if B needs to run or C needs to run or both. – civic.sir Jul 06 '16 at 14:40
0

Here how you can do it:

  • Make App.config as "Embedded Resource" in the properties/build action

  • Copy to output Directory : Do not copy

  • Add this code to Proram.cs Main

          if (!File.Exists(Application.ExecutablePath + ".config"))
          {
              File.WriteAllBytes(Application.ExecutablePath + ".config", ResourceReadAllBytes("App.config"));
              Process.Start(Application.ExecutablePath);
              return;
          }
    

Here are the needed functions:

    public static Stream GetResourceStream(string resName)
    {
        var currentAssembly = Assembly.GetExecutingAssembly();
        return currentAssembly.GetManifestResourceStream(currentAssembly.GetName().Name + "." + resName);
    }


    public static byte[] ResourceReadAllBytes(string resourceName)
    {
        var file = GetResourceStream(resourceName);
        byte[] all;

        using (var reader = new BinaryReader(file))
        {
            all = reader.ReadBytes((int)file.Length);
        }
        file.Dispose();
        return all;
    }