Shima.Y
Shima.Y

Reputation: 383

Changing values of settings files runtime

I'm working on a windows based project , in this project we used multiple settings files in order to set text of controls for example buttons.settings, lables.settings and .....

now I need to change the content of these settings files with other values at run time, for this reason we created same settings files with same column "Name" but different values, now I really have problem with changing content of these settings files.

I tried to change content of my tow settings file by loading and saving them as xmlDocument, but unfortunately my app.config doesnt change by new values. I also used ConfigurationManager.RefreshSection ...

plz help me thnx in advance

Upvotes: 1

Views: 3236

Answers (3)

Kapoor
Kapoor

Reputation: 1428

Perhaps its the problem with xmlDocument as mentioned here Changing App.config at Runtime

Please keep the setup same as my last response of label.settings & label2.settings.

And try this implementation

{

        // 1. Open the settings xml file present in the same location
        string settingName = "Lables2.SETTINGS";  // Setting file name
        XmlDocument docSetting = new XmlDocument();
        docSetting.Load(Application.StartupPath + Path.DirectorySeparatorChar + settingName);
        XmlNodeList labelSettings = docSetting.GetElementsByTagName("Settings")[0].ChildNodes;


        Console.WriteLine("Code {0} Group{1} Name{2}", Lables.Default.Code, Lables.Default.Group, Lables.Default.Name); //prints Code A1 GroupB1 NameC1


        //2. look for all Lables2 settings in Label settings & update
         foreach (XmlNode item in labelSettings)
         {
             var nameItem = item.Attributes["Name"];
             Lables.Default.PropertyValues[nameItem.Value].PropertyValue = item.InnerText;                
         }

         Lables.Default.Save(); // save. this will save it to user.config not app.config but the setting will come in effect in application
         Lables.Default.Reload();

         Console.WriteLine("Code {0} Group{1} Name{2}", Lables.Default.Code, Lables.Default.Group, Lables.Default.Name); //prints Code A2 GroupB2 NameC2

    }

It works for me, & because its without xmldocument, I'm hopeful it'll work at yr end too. Do let me know the result.

Upvotes: 1

Kapoor
Kapoor

Reputation: 1428

I'll start from describing my setup, just to be sure that we are on the same page.

Thats my setting file - Settings1.settings, with just one setting Test, & the default value being DefaultValue

enter image description here

At this point, the default value is also copied to app.config.

Now, I have a template whose settings which shall come into effect at run time, Its in the form of user.config. And this is how it looks like - enter image description here

here is the code from working experiment -

private void button1_Click(object sender, EventArgs e)
    {
        MessageBox.Show(Settings1.Default.Test); // this shows "DefaultValue" in a message box

        // Now change the user.config file with our template file - 

        //1. I get the location of user config
       var fileForUser = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath;

        //2. now I'll Place my template file, where user.config should be present 
       
        // create directory if it doesnt exist
        if(Directory.Exists(Path.GetDirectoryName(fileForUser)) == false) 
           Directory.CreateDirectory(Path.GetDirectoryName(fileForUser)) ; 
       
        // I have kept my template at E:\template.config
        File.Copy(@"E:\template.config", fileForUser, true);
       MessageBox.Show(Settings1.Default.Test); // this still shows "DefaultValue" because the user.config is not reloaded

        //3. Read the new setting 
       Settings1.Default.Reload();
       MessageBox.Show(Settings1.Default.Test); // this shows "Default Value is changed to ABC" because the user.config is now reloaded

    }

The App.config remains as it is & incase I delete the user.config or call Settings1.Default.Reset() then its the App.config which provides the application with default values

Hope it helps. Do let me know if it served yr purpose or not.

Update 1 Supporting the already tried approach by author of the question

Here is the working code to support yr approach, which will bring the settings file's setting in applicaion -

regret my typo - Lables2.settings, Lables.settings instead of Labels2.settings & Labels.settings

        {
            // 1. Open the settings xml file present in the same location
            string settingName = "Lables2.SETTINGS";  // Setting file name
            XmlDocument docSetting = new XmlDocument();
            docSetting.Load(Application.StartupPath + Path.DirectorySeparatorChar + settingName);
            XmlNodeList labelSettings = docSetting.GetElementsByTagName("Settings")[0].ChildNodes;

            // 2. Open the config file 
            string configFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
            XmlDocument appSettingDoc = new XmlDocument();
            appSettingDoc.Load(configFile);
            XmlNodeList appConfigLabelSettings = appSettingDoc.GetElementsByTagName("userSettings")[0].
                SelectNodes("WindowsFormsApplication2.Lables")[0].ChildNodes;
            //ProjectName.Setting file

            //3. update the config file 
            for (int i = 0; i < appConfigLabelSettings.Count; i++)
            {
                var v = appConfigLabelSettings.Item(i).ChildNodes[0];
                v.InnerText = labelSettings.Item(i).InnerText;
            }

            //4. save & load the settings 
            appSettingDoc.Save(configFile);
            Lables.Default.Reload();


            MessageBox.Show(Lables.Default.Code); // test pass... shows A2
        }

My project settings - enter image description here

Thats the executable folder, where enter image description here

And this is how the labels2.settings look like

enter image description here

Update 2 Approach without xml document

All the setup is same & this is much cleaner. Please try -

 {

        // 1. Open the settings xml file present in the same location
        string settingName = "Lables2.SETTINGS";  // Setting file name
        XmlDocument docSetting = new XmlDocument();
        docSetting.Load(Application.StartupPath + Path.DirectorySeparatorChar + settingName);
        XmlNodeList labelSettings = docSetting.GetElementsByTagName("Settings")[0].ChildNodes;


        Console.WriteLine("Code {0} Group{1} Name{2}", Lables.Default.Code, Lables.Default.Group, Lables.Default.Name); //prints Code A1 GroupB1 NameC1


        //2. look for all Lables2 settings in Label settings & update
         foreach (XmlNode item in labelSettings)
         {
             var nameItem = item.Attributes["Name"];
             Lables.Default.PropertyValues[nameItem.Value].PropertyValue = item.InnerText;                
         }

         Lables.Default.Save(); // save. this will save it to user.config not app.config but the setting will come in effect in application
         Lables.Default.Reload();

         Console.WriteLine("Code {0} Group{1} Name{2}", Lables.Default.Code, Lables.Default.Group, Lables.Default.Name); //prints Code A2 GroupB2 NameC2

    }

Upvotes: 2

Shima.Y
Shima.Y

Reputation: 383

 XmlDocument doc = new XmlDocument();
        //doc.Load(@"C:\Users\***\Documents\Visual Studio 2008\Projects\ChangingLablesRuntime\ChangingLablesRuntime\_Labels2.settings");
        //doc.Save(@"C:\Users\SHYAZDI.IDEALSYSTEM\Documents\Visual Studio 2008\Projects\ChangingLablesRuntime\ChangingLablesRuntime\_Labels.settings");

        doc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);

        var root = doc.GetElementsByTagName("userSettings")[0];
        doc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);

        var Config = System.Configuration.ConfigurationManager.OpenExeConfiguration(@"path of app.config");
        var root = doc.GetElementsByTagName("userSettings")[0];
        doc.GetElementsByTagName("userSettings")[0].SelectSingleNode("Zeus._Labels").InnerText = doc.GetElementsByTagName("userSettings")[0].SelectSingleNode("ChangingLablesRuntime._Labels2").InnerText;


        //var newEml = root.SelectSingleNode("ChangingLablesRuntime._Labels2");
        //var oldEml = root.SelectSingleNode("Zeus._Labels");

        //oldEml.InnerText = newEml.InnerText;

        //oldEml.ParentNode.ReplaceChild(newEml, oldEml);

        doc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);

        Config.Save(ConfigurationSaveMode.Modified);
        ConfigurationManager.RefreshSection("userSettings");

here is my code , lables2 is same as lables1 with different values, after running this code nothing happened.

this is piece of lables1.settings , that I want to replace with lables2.settings: Lables1.settings this is piece of lables2.settings : Lables2.settings

and app.config related code : app.config

app.config

Upvotes: 1

Related Questions