C# - 用户设置已损坏

jon*_*ers 10 .net c# settings application-settings

在阅读标准.Net用户设置时,我们遇到了罕见的异常(这是VS 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: 
Run Code Online (Sandbox Code Playgroud)

*注意:这是从测试应用程序重新创建的.

我拉起了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();
Run Code Online (Sandbox Code Playgroud)

我们如何使用它有什么问题吗?两个调用都有一个try-catch,它放置了一些默认值,但是这些值需要能够从我们的应用程序重置.

在这种状态下,我们的应用程序无法保存新设置 - 我无法找到以编程方式恢复的好方法.我不得不手动找到user.config并删除它.

我也尝试调用Settings.Reset()等,但得到相同的异常.

有想法该怎么解决这个吗?或者我们最好还是编写自己的设置系统或以其他方式保存持久性设置?

编辑:解决方法是从代码中删除文件,如果您得到ConfigurationErrorsException.

任何人都知道如何获取user.config文件的完整路径?

tof*_*tim 14

这是一个解决方案,不需要您退出应用程序与Jarle(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;
    }
Run Code Online (Sandbox Code Playgroud)

本质上,不是依赖于Sitting来抛出错误,而是使用ConfigurationManager读取文件,这样系统的版本就不会陷入糟糕的状态.


Rob*_*ney 11

以编程方式恢复的方法是执行您手动执行的操作 - 删除用户设置文件. 然后打电话Settings.Reset.(您也可以使用默认值编写新的用户设置文件,而不是删除它,但如果您正确使用配置管理器,则基本上是相同的.)

这种情况非常罕见,但并非完全闻所未闻.编写用户设置文件时,程序不仅会崩溃,文件本身也是用户可写的,因此用户运行的其他程序可能会弄乱它.

要避免此特定漏洞,请在具有事务完整性的持久存储中保留用户设置,即数据库.(你仍然会有漏洞,而不是这个漏洞.)对于大多数情况下可靠性的微小改进而言,这是很多工作.但"在大多数情况下"并不意味着"在所有情况下"; 你可以保证.

  • 删除文件后调用Reset()将导致抛出相同的异常.删除配置文件后,必须重新启动应用程序.详情请访问:http://connect.microsoft.com/VisualStudio/feedback/details/497189/user-config-file-corruptions-will-cause-exceptions-that-are-unrecoverable (4认同)