4

I'm currently working on a VSTO project for which I have 5 .settings files:

  • Settings.settings (Default)
  • s201213.settings
  • s201314.settings
  • s201415.settings
  • s201516.settings

Over time there will be more settings files included following the same naming convention ('s' followed by a tax year).

I know I can iterate through a settings file, but is there a way to iterate through the actual settings files themselves?

I've tried things such as:

 public void Example()
        {
            System.Collections.IEnumerator testSetting = MyAddIn.Properties.s201213.Default.Properties.GetEnumerator();

            while (testSetting.MoveNext())
            {
                System.Diagnostics.Debug.WriteLine("Setting:\t" + testSetting.Current.ToString());
            } 
        }  

Which obviously only iterates through a single settings file, but I can't seem to figure out the logic of iterating through all the settings files as a collection, without explicitly naming each one in the code. I hope that makes sense, any help is appreciated.


Update:
I think I'm getting somewhere with the following code:

foreach(Type test in Assembly.GetExecutingAssembly().GetTypes())
            {
                if (System.Text.RegularExpressions.Regex.IsMatch(test.Name, "^s[0-9]{6}$"))
                {
                    PropertyInfo value = test.GetProperty("LEL");

                    try
                    {
                        System.Diagnostics.Debug.WriteLine("Name:\t" + test.Name + 
                                                            "\nNameSpace:\t" + test.Namespace + 
                                                            "\nProperty:\t" + test.GetProperty("LEL").ToString() +
                                                            "\n");
                    }
                    catch(Exception e)
                    {
                        System.Diagnostics.Debug.WriteLine(e.Message);
                    }
                }   
            }  

Which seems to be recognising the settings files and the stored values:

Output:

Name:   s201213
NameSpace:  MyAddIn.Properties
Property:   Double LEL

Name:   s201314
NameSpace:  MyAddIn.Properties
Property:   Double LEL

Name:   s201415
NameSpace:  MyAddIn.Properties
Property:   Double LEL

Name:   s201516
NameSpace:  MyAddIn.Properties
Property:   Double LEL  

However I can't seem to get the actual value of the "LEL" setting which should return a Double?


2nd Update
I've actually given up and decided to use a local DB instead - but I would still like to know if this is possible, and I think other people would like to know too so I'm going to throw a bounty at it to try and generate some interest.

Jeremy Thompson
  • 61,933
  • 36
  • 195
  • 321
SierraOscar
  • 17,507
  • 6
  • 40
  • 68

3 Answers3

1

Jeremy's answer got me to the finish post, but thought I'd post the final code I used so that it can be seen in context:

public void GetLEL()
{
    var fileMap = new ConfigurationFileMap(AppDomain.CurrentDomain.BaseDirectory + @"CustomAddIn.dll.config");
    var configuration = ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
    var sectionGroup = configuration.GetSectionGroup("userSettings");
    var section = (ClientSettingsSection)sectionGroup.Sections.Get("MyAddIn.s201213");
    var setting = section.Settings.Get("LEL");
    System.Diagnostics.Debug.WriteLine(setting.Value.ValueXml.InnerXml);
    // Prints "107" as expected.
}
SierraOscar
  • 17,507
  • 6
  • 40
  • 68
0

I believe you can use the System.IO namespace classes for iterating through files with the same extension. There is no built-in mechanisms or properties for that.

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • I've had a play around with `System.IO` namespace but still can't see anything to grab an enumerator for project files. I'm starting to think that I may have to concoct some sort of workaround :( – SierraOscar Jul 22 '15 at 09:35
  • The `System.IO` namespace doesn't provide anything special for the *.settings files. But it allows to find all files with the specified extension and go through each of them. – Eugene Astafiev Jul 22 '15 at 10:52
  • Okay, I think I follow your logic - let me have a play around some more. Cheers! – SierraOscar Jul 22 '15 at 10:56
  • Did you downvote me? The times match and your answer doesn't factor in that the settings are written to the app.config, hence this answer you have provided is completely off the mark and if anything this answer should be getting downvotes. – Jeremy Thompson Jul 24 '15 at 10:28
  • Ok, apologies. Usually I find your answers to be high quality. – Jeremy Thompson Jul 24 '15 at 10:52
0

The answer is really simple once you see it (no need to iterate through Types nor use System.IO directory):

using System.Configuration; //Add a reference to this DLL

...

var fileMap = new ConfigurationFileMap(Application.StartupPath + @"\GetSettingFilesValues.exe.config");
var configuration = ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
var sectionGroup = configuration.GetSectionGroup("applicationSettings"); // This is the section group name, change to your needs, ie application or user
var section = (ClientSettingsSection)sectionGroup.Sections.Get("GetSettingFilesValues.Properties.s201415"); //This is the section name, change to your needs (you know the tax years you need)
var setting = section.Settings.Get("LEL");
System.Diagnostics.Debug.WriteLine(setting.Value.ValueXml.InnerXml);

I agree with your approach to use the dB, though I'm sure this will benefit other people too.

Jeremy Thompson
  • 61,933
  • 36
  • 195
  • 321
  • Thanks, I'll try this when I'm back at my own PC shortly - so if I understand, is this parsing the XML config file for the values instead? Never thought of that... _(tag edit also appreciated, cheers!)_ – SierraOscar Jul 24 '15 at 06:49
  • Please excuse my ignorance as I'm still learning the basics of C# and VS - the `GetSettingFilesValues.exe.config` doesn't exist in `XLSTART` or in `Assembly.GetExecutingAssembly.BaseDirectory` so I've hard coded the path to my `app.config` file for the moment. Is this correct? I'm getting an exception on `section.Settings.Get("LEL")` stating "Object reference not set to an instance of an object". – SierraOscar Jul 24 '15 at 08:19
  • Yes, that's correct for VSTO, the AddIns config file is what you want. In my example I used a winform app. For web developers they'd use a path to their web.config. – Jeremy Thompson Jul 24 '15 at 08:21
  • To overcome the exception, debug the code double check everything: the file path is correct, your using Application vs User settings, etc. The settings get written to the config file when you compile the app, so App.Config might not be correct, check in the Bin\Debug folder for the compiled App.Config... – Jeremy Thompson Jul 24 '15 at 08:32
  • 1
    One last tip that always trips me up is about **.config file context**, see my explanation about it here: http://stackoverflow.com/a/11535980 – Jeremy Thompson Jul 24 '15 at 08:45
  • ^^ Last tip helped, I was pointing at a config file within a class rather than the project. – SierraOscar Jul 24 '15 at 08:54