How do you write out a blank version of your config when a program is first run? [closed]
Asked Answered
B

2

1

I've been making a command line tool in c# and we've ended up using a config for some parameters that will only really need setting once. Rather than provide a UI for these I was told to just set up a blank config and if the values weren't set provide a message to say where the config was and to go set them.

This turned out to be remarkably difficult!

The things I needed to be able to do were as follows:

  • get the path to the config
  • save a blank config with stubs for the relevant properties

The tool was being released using CC.net and an msi created using wix. Unfortunately this was relevant!

Bred answered 13/1, 2014 at 10:51 Comment(1)
If settings.settings is xml-file (sorry, not using it), then you could remove all entries from there manually (only leave <xml> </xml>and supply this config with installer. On a first run, upon deserialization xml-file, if parameter is missing, then default value of that parameter will be taken.Matelot
B
0

Get the path to the config

This bit turned out to be very easy:

you just use something like this:

    public string FileLocation
    {
        get { return Configuration.FilePath; }
    }

    private static Configuration Configuration
    {
        get { return OpenConfig(ConfigurationUserLevel.PerUserRoamingAndLocal); }
    }

    private static Configuration OpenConfig(ConfigurationUserLevel userLevel)
    {
        return ConfigurationManager.OpenExeConfiguration(userLevel);
    }

There are two other values for the enum passed in there: None seems to point to where the app.config would be and PerUserRoaming always seems to point to somewhere that doesnt exist. I couldnt find out any more details about when this may be appropriate to use but in my case it appears not to be.

As just touched on above one of the confusing things about this call is that it will return the path of the file should one be saved/exist. This means that often this file wont exist! The unclear relationship between the ConfigurationManager and Settings (the autogenerated class derived from ApplicationSettingsBase) is what caused me a lot of pain!

save a blank config

A few stumbling blocks were as follows:

if you add a settings.Settings class this will also add an app.config. Unless you ship this with your installed program then you will see different behaviour between the installed version of the program and the dev version - one will create settings files using values from the app.config and the other wont. The simplest solution for me was to delete the app.config altogether.

I was trying to use the save method on Configuration which lets you specify that you save all properties (regardless of value being default) and lets you specify to save even if the configuration has not been modified. However calling this method with both flags set wont do anything - it appears that the settings you create in the designer in some way arent real until they get set - Configuration and ConfigurationManager are the older way of doing things and while ApplicationSettingsBase probably uses one or both of them they dont integrate nicely.

To make it more confusing, if you query the settings then they will have values (for strings they will have ""). However if you save the settings then these settings aren't saved to the location specified in the file! In fact no file will be created at all! Although if you have an app.config a file will be created if you use the force save method above as the defaults are specified in the app.config!

The solution appears to be to check for the default value in each of the properties and then set the default value. This looks like it should be a no-op but the getter doesnt follow the logic of 'if I dont have a setting I'll create it when queried' instead it just pretends one exists with the default value. Setting any value seems to actually create the setting.

        var somethingUnSet = _settings.Something == "";
        if (somethingUnset)
            _settings.Something = "";

        if(somethingUnset|| somethingElseUnset)
        {
            _settings.Save();
            ExitWithError("config needs setting up at " + _settings.FileLocation);
            return;
        }  

Finally this gave me the desired result - a file gets saved in the location specified by config manager with the empty properties that need filling in. Think a UI would have been quicker!!!

I was using a wrapped Settings object to facilitate changing values in tests without having to deal with a singleton. This also has the nice side effect that you can tack on extra code (like the file location) and not have to worry about the code gen overwriting stuff when you add more settings.

Bred answered 13/1, 2014 at 10:51 Comment(0)
O
0

Just set all the Items in the .config File to nothing by first start like:

ConfigurationManager.appSettings["item1"] = ""; 

and check for the Value.

But why didn´t you just check if the parameters is set and if not Throw an error, i think you not need to clear a config file to check if its first start

Orff answered 13/1, 2014 at 11:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.