如何在加载.NET WinForm app user.config文件时捕获异常?

有时在使用默认配置系统的.NET(2.0)WinForm桌面应用程序中,
user.config
文件将被破坏并且无法再加载(当配置系统尝试加载它时,它会抛出一个
System.Xml.XmlException
)。 抛开“为什么文件首先被破坏”的问题(可能是宇宙射线,或HDD问题,或者你无法控制的其他东西),问题就变成了“怎么能抓住这个异常和做一些有意义的事情吗? Microsoft的Connect站点有关于此类问题的报告。不幸的是,他们的报告不是很有帮助。 是否有可能捕获源自默认配置系统加载器本身的异常?或者您是否必须推出自己的配置系统才能捕获此类异常?     
已邀请:
事实证明你可以捕获这个例外。我需要的提示来自这个问题: C# - 用户设置已损坏 在我的情况下,(WinForms应用程序),我在父(启动)表单中的异常处理程序捕获此异常。但我想你也可以使用
ApplicationEvents
中的
MyApplication_UnhandledException
处理程序。最重要的是,你需要某种高级“未处理的异常”处理程序来捕获它。 另外,您可以查看异常的InnerException,看看它是否为
System.Configuration.ConfigurationErrorsException
类型。如果是,则可以查看此InnerException的
.FileName
属性以获取user.config文件的完整文件名。 一旦你有了这个,你可以做一些事情 - 尝试检查它的内容,看看它有什么问题,或(最坏的情况)删除它并重新启动应用程序,以便使用所有默认设置重新创建它。 正如我之前所说,这是一个非常罕见的例外,可能是由突然的系统关闭或其他无法控制的事件(例如停电)引起的。尽管如此,最终能够对此做些什么是件好事。     
我有同样的问题。框架中必须存在错误,因为没有其他人编写该文件。 我创建了一个可以治愈大部分问题的小课程。 您唯一需要做的就是在程序开始时调用HealUserSettings并在保存设置时调用BackupUserSettings。 如果您愿意,可以删除消息框,通知您的用户他的所有设置都已丢失。
public static class SettingsFileRecovery
{
    public static void HealUserSettings()
    {
        string file;
        try
        {
            file = GetUserSettingsFile();
        }
        catch (ConfigurationException ex)
        {
            file = ex.Filename;
            if (File.Exists(file))
            {
                if (!RestoreUserSettings(file))
                {
                    MessageBox.Show("Settings are lost.", "Error", MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);

                    // must delete wrong file
                    File.Delete(file);
                }
                Application.Restart();
            }
        }

        // does not exist
        if (!File.Exists(file))
        {
            if (RestoreUserSettings(file))
            {
                Application.Restart();
            }
        }


    }

    public static string GetUserSettingsFile()
    {
        Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
        return config.FilePath;
    }

    public static string GetBackupFile(string file)
    {
        return file + ".bak";
    }

    public static void BackupUserSettings()
    {
        try
        {
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
            config.SaveAs(GetBackupFile(config.FilePath));
        }
        catch (Exception)
        {
            // file is corrupt but no problem because no backup is written
        }
    }

    public static bool RestoreUserSettings(string file)
    {
        string backupFile = GetBackupFile(file);
        if (File.Exists(backupFile))
        {
            File.Copy(backupFile, file, true);
            return true;
        }
        return false;
    }
}
    
一个简单的方法是拥有一个“加载器”应用程序,它所做的只是检查真实应用程序的配置文件是否存在,否则创建它,然后启动真正的应用程序。 可能是一些更简洁的做法,但我不知道。     
有些问题 - 可能是您的应用程序正在写一个空白的user.config文件。这是一个调查和修复的错误。可能是你的应用程序没有干净地退出(所以它有时会默默地擦除app.config,所以我首先看看关机顺序。另外,在文件上粘贴第三方文件实用程序可能对你有所帮助赶紧查看它被破坏的确切时间和地点。 如果您无法解决问题,那么我能想到的最佳解决方法是使用独立的XML配置文件(放弃自动app.config方法) - 然后您就可以完全控制加载和保存的时间和位置。 但是,从根本上说,有一个很大的代码味道,我想知道为什么标准的xml配置方法在我的应用程序中无法工作,当它在成千上万的其他工作正常。     
[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();
    }
}
    

要回复问题请先登录注册