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 associated with each of the programs. Basically program A is just a wrapper class that calls different console applications. 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've 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>
8
  • How are you launching these other .exe programs? Commented Jul 6, 2016 at 14:26
  • They are all console application Commented Jul 6, 2016 at 14:26
  • So a simple Applicaton.Run() call? Commented Jul 6, 2016 at 14:28
  • Will I not need an app.config file in the same directory too? Currently I just call the main method from program A Commented Jul 6, 2016 at 14:29
  • That's what I'm asking, copy paste the line of code of how you're opening program2 from program1. Commented Jul 6, 2016 at 14:30

4 Answers 4

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;
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

updated the question .. this answer was right in the context before... but i guess the question was not clear enough
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>

1 Comment

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

2 Comments

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?
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.
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 Program.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;
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.