Missing <configSections> in config file after deployment

风格不统一 提交于 2019-12-06 00:53:50

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);
    }

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!