3

Update: I had a question below but actually my problem would be solved by asking a slightly different question. Why on some machines does my application throw the error:

Configuration system failed to initialize - System.Configuration -    at     System.Configuration.ConfigurationManager.PrepareConfigSystem()

where as on other machines it does not. The error as described also here .NET 3.5 - Configuration system failed to initialize exception is caused by a missing configSections element at the top of my app.config. Of course, the problem would be resolved by putting this section in but for some reason the app.config in my projects solution which has this section is not the one which gets created in the appdata folder once it is deployed.

Original Question:

Why would my user config file be missing this section when deployed on some machines and not others? How can I ensure it is not missing.

<configSections>
    <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
        <section name="NameOfAddin_Add_in.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
    </sectionGroup>
</configSections>

Some background. I'm deploying a vsto add-in through a click once visual studio installer on win 7 machines running outlook 2007 and 2010.

The add-in reads and writes some settings to the app.config file which unlike an exe gets stored in the local users appdata folder.

On some machines however I'm getting an error "Configuration system failed to initialize - System.Configuration - at System.Configuration.ConfigurationManager.PrepareConfigSystem()" which in my case is being caused by the above missing element in the xml. However on other machines the configSections is not missing. The problem is unrelated to the Outlook version being used.

Community
  • 1
  • 1
user48408
  • 3,234
  • 11
  • 39
  • 59

2 Answers2

2

I've had the same issue in my VSTO DLL project yesterday and I still don't understand the reason why the with name="userSettings" is sometimes missing. But I can provide my solution: I've made a function which copies the missing XML part (if it's missing) from the fixed ".dll.config" file to the config file in the ROAMING directory:

    /// <summary>
    /// Corrects the roaming settings file if needed because sometimes the node "configSections" is missing in the settings file. 
    /// Correct this by taking this node out of the default config file.
    /// </summary>
    private static void CorrectRoamingSettingsFileIfNeeded()
    {
        const string NODE_NAME_CONFIGURATION = "configuration";
        const string NODE_NAME_CONFIGSECTIONS = "configSections";
        const string NODE_NAME_USERSETTINGS = "userSettings";
        const string ADDIN_DLL_FILENAME = "MyAddIn.dll";

        //Exit if no romaing config (file) to correct...
        var configRoaming = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoaming);
        if (configRoaming == null) return;
        if (!configRoaming.HasFile) return;

        //Check for the <sectionGroup> with name="userSettings"
        //Note: Used ugly iteration because "configRoaming.GetSectionGroup(sectionGroupName)" throws ArgumentException.
        ConfigurationSectionGroup sectionGroupUserSettings = null;
        foreach (ConfigurationSectionGroup sectionGroup in configRoaming.SectionGroups)
        {
            if (sectionGroup.Name.Equals(NODE_NAME_USERSETTINGS))
            {
                sectionGroupUserSettings = sectionGroup;
                break;
            }
        }

        //Exit if the needed section group is found...
        if (sectionGroupUserSettings != null && sectionGroupUserSettings.IsDeclared) return;

        //Do correction actions...
        var xDoc = XDocument.Load(configRoaming.FilePath);
        var userSettingsNode = xDoc.Element(NODE_NAME_CONFIGURATION).Element(NODE_NAME_USERSETTINGS);

        var addInDllConfigFullFilename = AppDomain.CurrentDomain.BaseDirectory + ADDIN_DLL_FILENAME;
        var configDefault = ConfigurationManager.OpenExeConfiguration(addInDllConfigFullFilename);
        var xDocDefault = XDocument.Load(configDefault.FilePath);
        var configSectionsNode = xDocDefault.Element(NODE_NAME_CONFIGURATION).Element(NODE_NAME_CONFIGSECTIONS);

        userSettingsNode.AddBeforeSelf(configSectionsNode);
        xDoc.Save(configRoaming.FilePath);
    }
jreichert
  • 1,466
  • 17
  • 31
2

The [app name].exe.config file is an installation-time configuration file, and the user.config file is a file that gets created/overwritten somewhere inside the user's AppData folder when you save user settings within your application at runtime.

I just determined experimentally that when the .exe.config file is installed with my app, then when the app saves its user.config file, it thinks that it doesn't need to write the <configSections><sectionGroup name="userSettings"... section of XML in the user.config file, because that section of XML is already defined in the installed .exe.config file. However, if I don't install that .exe.config file with my app, then when the app saves its user.config file, it writes the <configSections><sectionGroup name="userSettings"... section of XML to the user.config file, since there is no .exe.config file to define that section.

A problem happens when there is an existing user.config file on a user's computer that was created by a previously installed version of the app that did have an .exe.config file installed, and then if you re-install the app without an .exe.config file installed, then the <configSections><sectionGroup name="userSettings"... section of XML is not defined in either a .exe.config file or in the existing user.settings file, which causes the program to be unable to read the section from the user.config file, so it throws a System.Configuration.ConfigurationErrorsException the first time the program tries to access a user setting.

chinookf
  • 301
  • 2
  • 7