是什么导致user.config为空?如何在不重新启动的情况下恢复?

时间:2012-03-05 18:54:38

标签: c# app-config

我注意到在我的应用程序的user.config文件以某种方式损坏并且打开时为空的几台机器上。我似乎无法弄清楚为什么会这样。是否有一个常见的事情会导致这种情况?有什么方法可以安全地防止这种情况发生?

我的第二个问题是如何恢复状态?我捕获异常并删除user.config文件,但我找不到一种方法来恢复配置而不重新启动应用程序。我在Properties对象上执行的所有操作都会导致以下错误:

“配置系统无法初始化”

重置,重新加载和升级都无法解决问题。

以下是我在异常后删除的代码:

catch (System.Configuration.ConfigurationErrorsException ex)
{
    string fileName = "";
    if (!string.IsNullOrEmpty(ex.Filename))
        fileName = ex.Filename;
    else
    {
        System.Configuration.ConfigurationErrorsException innerException = ex.InnerException as System.Configuration.ConfigurationErrorsException;
        if (innerException != null && !string.IsNullOrEmpty(innerException.Filename))
            fileName = innerException.Filename;
    }
    if (System.IO.File.Exists(fileName))
        System.IO.File.Delete(fileName);
}

4 个答案:

答案 0 :(得分:18)

我们在我们的应用程序中遇到了这个问题 - 我无法找到原因(我的猜测是我写的很常见,但是我不太确定)。无论如何,我的解决方法是在下面。关键是删除损坏的文件并调用Properties.Settings.Default.Upgrade()

try
{
     ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
}
catch (ConfigurationErrorsException ex)
{
    string filename = ex.Filename;
    _logger.Error(ex, "Cannot open config file");

    if (File.Exists(filename) == true)
    {
        _logger.Error("Config file {0} content:\n{1}", filename, File.ReadAllText(filename));
        File.Delete(filename);
        _logger.Error("Config file deleted");
        Properties.Settings.Default.Upgrade();
        // Properties.Settings.Default.Reload();
        // you could optionally restart the app instead
    }
    else
    {
        _logger.Error("Config file {0} does not exist", filename);
    }
}

答案 1 :(得分:4)

我有类似的情况。对我来说,一旦删除了错误的配置文件,我就让应用程序继续运行。下次访问设置将使用应用程序默认值。

答案 2 :(得分:4)

这可能有点晚了,但我已经对此做了更多的研究。 user.config文件似乎因未知原因而损坏,并且不会让应用程序启动。您可以在app.xaml.cs中放置一个小的try / catch逻辑,并检查它何时启动以确保在源处捕获此问题。当应用程序启动并尝试以编程方式重新加载settings.default并失败时,它将转到异常,为用户提供删除文件的选项。

try {
Settings.Default.Reload();
} 
catch ( ConfigurationErrorsException ex ) 
{ 
  string filename = ( (ConfigurationErrorsException)ex.InnerException ).Filename;

if ( MessageBox.Show( "<ProgramName> has detected that your" + 
                      " user settings file has become corrupted. " +
                      "This may be due to a crash or improper exiting" + 
                      " of the program. <ProgramName> must reset your " +
                      "user settings in order to continue.\n\nClick" + 
                      " Yes to reset your user settings and continue.\n\n" +
                      "Click No if you wish to attempt manual repair" + 
                      " or to rescue information before proceeding.",
                      "Corrupt user settings", 
                      MessageBoxButton.YesNo, 
                      MessageBoxImage.Error ) == MessageBoxResult.Yes ) {
    File.Delete( filename );
    Settings.Default.Reload();
    // you could optionally restart the app instead
} else
    Process.GetCurrentProcess().Kill();
    // avoid the inevitable crash
}

信用 - http://www.codeproject.com/Articles/30216/Handling-Corrupt-user-config-Settings

希望这有助于某人:)

答案 3 :(得分:0)

这是我们解决问题的方式。 在使用Properties.Settings之前,必须先调用此函数。否则,您将被卡住(如tofutim和avs099所述)。

private bool CheckSettings()
    {
        var isReset = false;
        string filename = string.Empty;

        try
        {
            var UserConfig = System.Configuration.ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.PerUserRoamingAndLocal);
            filename = UserConfig.FilePath;
            //"userSettings" should be replaced here with the expected label regarding your configuration file
            var userSettingsGroup = UserConfig.SectionGroups.Get("userSettings");
            if (userSettingsGroup != null && userSettingsGroup.IsDeclared == true)
                filename = null; // No Exception - all is good we should not delete config in Finally block
        }
        catch (System.Configuration.ConfigurationErrorsException ex)
        {
            if (!string.IsNullOrEmpty(ex.Filename))
            {
                filename = ex.Filename;
            }
            else
            {
                var innerEx = ex.InnerException as System.Configuration.ConfigurationErrorsException;
                if (innerEx != null && !string.IsNullOrEmpty(innerEx.Filename))
                {
                    filename = innerEx.Filename;
                }
            }
        }
        catch (System.ArgumentException ex)
        {
            Console.WriteLine("CheckSettings - Argument exception");
        }
        catch (SystemException ex)
        {
            Console.WriteLine("CheckSettings - System exception");

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

                    try
                    {
                        Properties.Settings.Default.Upgrade();                          
                    } catch(SystemException ex)
                    {
                        Console.WriteLine("CheckSettings - Exception" + ex.Message);
                    }
                }
            } 
        }
        return isReset;
    }