Вопрос

При чтении стандарта возникло редкое исключение .Настройки сетевого пользователя (это те, которые находятся в разделе "свойства проекта" в версии 2008):

System.Configuration.ConfigurationErrorsException was caught
  Message="Configuration system failed to initialize"
  Source="System.Configuration"
  BareMessage="Configuration system failed to initialize"
  Line=0
  StackTrace:
       at System.Configuration.ConfigurationManager.PrepareConfigSystem()
       at System.Configuration.ConfigurationManager.GetSection(String sectionName)
       at System.Configuration.PrivilegedConfigurationManager.GetSection(String sectionName)
       at System.Diagnostics.DiagnosticsConfiguration.GetConfigSection()
       at System.Diagnostics.DiagnosticsConfiguration.Initialize()
       at System.Diagnostics.DiagnosticsConfiguration.get_IndentSize()
       at System.Diagnostics.TraceInternal.InitializeSettings()
       at System.Diagnostics.TraceInternal.get_Listeners()
  InnerException: System.Configuration.ConfigurationErrorsException
       Message="Unexpected end of file has occurred. The following elements are not closed: setting, SettingsTest.Properties.Settings, userSettings, configuration. Line 7, position 1. (C:\\Documents and Settings\\USER\\Local Settings\\Application Data\\Hitcents\\SettingsTest.vshost.exe_Url_ghwhc20utv4toanuinmj0pfsljthcugo\\1.0.0.0\\user.config line 7)"
       Source="System.Configuration"
       BareMessage="Unexpected end of file has occurred. The following elements are not closed: setting, SettingsTest.Properties.Settings, userSettings, configuration. Line 7, position 1."
       Filename="C:\\Documents and Settings\\USER\\Local Settings\\Application Data\\Hitcents\\SettingsTest.vshost.exe_Url_ghwhc20utv4toanuinmj0pfsljthcugo\\1.0.0.0\\user.config"
       Line=7
       StackTrace:
            at System.Configuration.ConfigurationSchemaErrors.ThrowIfErrors(Boolean ignoreLocal)
            at System.Configuration.BaseConfigurationRecord.ThrowIfParseErrors(ConfigurationSchemaErrors schemaErrors)
            at System.Configuration.BaseConfigurationRecord.ThrowIfInitErrors()
            at System.Configuration.ClientConfigurationSystem.OnConfigRemoved(Object sender, InternalConfigEventArgs e)
       InnerException: System.Xml.XmlException
            Message="Unexpected end of file has occurred. The following elements are not closed: setting, SettingsTest.Properties.Settings, userSettings, configuration. Line 7, position 1."
            Source="System.Xml"
            LineNumber=7
            LinePosition=1
            SourceUri=""
            StackTrace:
                 at System.Xml.XmlTextReaderImpl.Throw(Exception e)
                 at System.Xml.XmlTextReaderImpl.Throw(String res, String arg)
                 at System.Xml.XmlTextReaderImpl.Throw(Int32 pos, String res, String arg)
                 at System.Xml.XmlTextReaderImpl.ThrowUnclosedElements()
                 at System.Xml.XmlTextReaderImpl.ParseElementContent()
                 at System.Xml.XmlTextReaderImpl.Read()
                 at System.Xml.XmlTextReader.Read()
                 at System.Xml.XmlTextReaderImpl.Skip()
                 at System.Xml.XmlTextReader.Skip()
                 at System.Configuration.XmlUtil.StrictSkipToNextElement(ExceptionAction action)
                 at System.Configuration.BaseConfigurationRecord.ScanSectionsRecursive(XmlUtil xmlUtil, String parentConfigKey, Boolean inLocation, String locationSubPath, OverrideModeSetting overrideMode, Boolean skipInChildApps)
                 at System.Configuration.BaseConfigurationRecord.ScanSectionsRecursive(XmlUtil xmlUtil, String parentConfigKey, Boolean inLocation, String locationSubPath, OverrideModeSetting overrideMode, Boolean skipInChildApps)
                 at System.Configuration.BaseConfigurationRecord.ScanSections(XmlUtil xmlUtil)
                 at System.Configuration.BaseConfigurationRecord.InitConfigFromFile()
            InnerException: 

*ПРИМЕЧАНИЕ:это воссоздано из тестового приложения.

Я поднял файл user.config, и половина из него отсутствовала.

Я ожидаю, что наше приложение было внезапно прекращено по той или иной причине.

Это кажется очень редким, вот как мы взаимодействуем с настройками:

//How we read
Settings settings = Settings.Default;
_ourStaticMemberVariable = settings.OurValue;

//How we save
Settings settings = Settings.Default;
settings.OurValue = "Our Value";
settings.Save();

Есть ли что-то не так в том, как мы это используем?Оба вызова имеют функцию try-catch, которая устанавливает некоторые значения по умолчанию, но значения должны иметь возможность сбрасываться из нашего приложения.

Находясь в этом состоянии, наше приложение не может сохранить новые настройки - и я не могу найти хороший способ программного восстановления.Мне пришлось вручную найти user.config и удалить его.

Я также попытался вызвать настройки.Сброс () и т.д.но получите то же самое исключение.

Есть какие-нибудь идеи о том, как это исправить?Или нам лучше написать нашу собственную систему настроек или сохранить постоянные настройки другим способом?

Редактировать: Обходной путь заключается в удалении файла из кода, если вы получаете исключение ConfigurationErrorsException.

Кто-нибудь знает, как получить полный путь к файлу user.config?

Это было полезно?

Решение

Способ программного восстановления заключается в том, чтобы сделать то, что вы делали вручную - удалить файл пользовательских настроек. Тогда позвонить Settings.Reset.(Вы также могли бы написать новый файл пользовательских настроек со значениями по умолчанию вместо его удаления, но если вы правильно используете configuration Manager, это, по сути, то же самое.)

Это довольно редкое явление, но не совсем неслыханное.Мало того, что ваша программа может аварийно завершать работу при записи файла пользовательских настроек, сам файл доступен для записи пользователем, поэтому другие программы, которые запускает пользователь, могут испортить его.

Чтобы избежать этой конкретной уязвимости, сохраняйте пользовательские настройки в надежном хранилище с сохранением целостности транзакций, т. е.база данных.(У вас все еще будут уязвимости, только не эта.) Это большая работа для того, что в большинстве случаев приведет к незначительному повышению надежности.Но "в большинстве случаев" не означает "во всех случаях"; ваш может это гарантировать.

Другие советы

Вот решение, которое не требует от вас выхода из приложения, слава Ярле (http://www.codeproject.com/Articles/30216/Handling-Corrupt-user-config-Settings?msg=3608682#xx3608682xx).На ранней стадии, до того, как будут вызваны Настройки, используйте это

    public static bool CheckSettings()
    {
        var isReset = false;

        try
        {
            ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
        }
        catch (ConfigurationErrorsException ex)
        {
            string filename = string.Empty;
            if (!string.IsNullOrEmpty(ex.Filename))
            {
                filename = ex.Filename;
            }
            else
            {
                var innerEx = ex.InnerException as ConfigurationErrorsException;
                if (innerEx != null && !string.IsNullOrEmpty(innerEx.Filename))
                {
                    filename = innerEx.Filename;
                }                   
            }

            if (!string.IsNullOrEmpty(filename))
            {
                if (System.IO.File.Exists(filename))
                {
                    var fileInfo = new System.IO.FileInfo(filename);
                    var watcher
                         = new System.IO.FileSystemWatcher(fileInfo.Directory.FullName, fileInfo.Name);
                    System.IO.File.Delete(filename);
                    isReset = true;
                    if (System.IO.File.Exists(filename))
                    {
                        watcher.WaitForChanged(System.IO.WatcherChangeTypes.Deleted);
                    }
                }
            }
        }

        return isReset;
    }

По сути, вместо того, чтобы полагаться на Sittings для выдачи ошибки, прочитайте файл с помощью ConfigurationManager, таким образом, версия системы никогда не перейдет в плохое состояние.

[STAThread]
private static void Main(string[] args)
{
    try
    {
        // ...
    }
    catch (System.Configuration.ConfigurationErrorsException ex)
    {   
        var config = ((System.Configuration.ConfigurationErrorsException)ex.InnerException).Filename;
        // notify user, ask them to restart
        System.IO.File.Delete(config);
        Application.Exit();
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top