代码之家  ›  专栏  ›  技术社区  ›  Keithius

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

  •  5
  • Keithius  · 技术社区  · 14 年前

    有时在使用默认配置系统的.NET(2.0)WinForm桌面应用程序中, user.config 文件将损坏,无法再加载(当配置系统尝试加载时,它将引发 System.Xml.XmlException )

    抛开“为什么文件首先会被破坏”这个问题(可能是宇宙射线,或者硬盘问题,或者其他你无法控制的问题),这个问题就变成了“如何捕捉这个异常并用它做一些有意义的事情?”

    Microsoft's Connect site has a report on this sort of problem . 不幸的是,他们的报告没什么帮助。

    是否可以捕获源自默认配置系统加载程序本身的异常?或者您必须滚动自己的配置系统才能捕获这种异常?

    5 回复  |  直到 11 年前
        1
  •  1
  •   Community CDub    7 年前

    原来你 可以 捕获此异常。我需要的提示来自这个问题:

    C# - User Settings broken

    在我的例子中,(winforms-app),我在父(startup)表单中的异常处理程序捕获了这个异常。但是我想你可以用 MyApplication_UnhandledException 处理程序在 ApplicationEvents 也。最重要的是,您需要某种高级的“未处理的异常”处理程序来捕获它。

    此外,您可以查看异常的innerException并查看它是否属于类型 System.Configuration.ConfigurationErrorsException . 如果是,那么你可以看看 .FileName 属性获取user.config文件的完整文件名。

    一旦你有了这个,你可以做一些事情-尝试检查它的内容,看看它有什么问题,或者(最坏的情况)删除它并重新启动应用程序,这样它就可以用所有默认设置重新创建。

    正如我之前所说,这是一个 非常 罕见的例外情况,可能是由系统突然关闭或其他不可控事件(如停电)引起的。不过,能最终做到这一点还是很好的 某物 关于它。

        2
  •  1
  •   Uwe Wittig    11 年前

    我也有同样的问题。框架中必须有一个错误,因为没有其他人写入该文件。 我创建了一个可以解决大部分问题的小类。

    唯一要做的就是在程序开始时调用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;
        }
    }
    
        3
  •  0
  •   Hans Olsson    14 年前

    一个简单的方法是拥有一个“加载器”应用程序,它所做的就是检查真实应用程序的配置文件是否存在,否则创建它,然后启动真实应用程序。

    可能是我不知道的更整洁的方式。

        4
  •  0
  •   Jason Williams    14 年前

    有问题-可能是您的应用程序正在编写空白的user.config文件。这是一个需要调查和修复的错误。可能是您的应用程序没有干净地退出(所以有时它会悄悄地擦除app.config,所以我先看看关机顺序。另外,在文件上粘贴第三方文件实用程序可能有助于您准确地了解文件何时何地损坏)。

    如果你不能解决这个问题,那么我能想到的最好的解决方法就是使用一个独立的XML配置文件(放弃自动app.config方法),然后你就可以完全控制何时何地加载和保存它了。

    但是,从根本上讲,这里有一种很大的代码味道,我想知道为什么在我的应用程序中,当标准XML配置方法在数千个其他应用程序中运行良好时,它不起作用。

        5
  •  0
  •   Seba Illingworth    13 年前
    [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();
        }
    }