处理损坏的 "user.config" 设置






4.78/5 (43投票s)
构建一个简单的处理程序,用于处理程序中损坏的用户设置。
引言
Settings
类自 .NET 2.0 以来就存在,并且仍然是为应用程序存储用户设置的最简单和首选方式。但是,Settings
机制存在一个挥之不去的问题,微软尚未令人满意地解决。
此外,我花了很长时间才真正找到解决方案。幸运的是,结果比我的一些尝试要容易得多,虽然我在搜索中没有找到任何提及,但我在调试时偶然发现了它。
事实上,回想起来它是如此简单,以至于你们中的许多人可能已经解决了这个问题,并没有多想,但既然我花了一段时间才意识到解决方案(并且确实一开始就存在问题),我认为其他人可能会从明确地阐述它中受益。
所以,事不宜迟,这就是问题和解决方案。
问题
问题是:如果 user.config 文件损坏(我发生过不止一次,完全是它自己损坏的),似乎没有办法以编程方式恢复,并且您的程序会在访问 Settings
的那一刻崩溃,每次运行时都会崩溃。更糟糕的是,我们甚至无法调用 Settings.Default.Reset()
,因为该方法只会抛出相同的异常。到目前为止,我唯一的选择是指示用户通过在其用户帐户中的各种隐藏设置文件夹中查找来手动删除其 user.config 文件。 这不是新手用户会喜欢做的事情。
使这如此困难的原因是 user.config 文件的实际位置非常复杂,以至于无法手动确定。 例如,这是我的 OrangeNote 用户设置文件的路径
C:\Users\Logan\AppData\Local\The_Little_Software_Compa\
OrangeNote.exe_Url_wxcnyrmstqy3oj1qwckdjq3gjqkq4fel\1.0.0.0\user.config
我不知道你怎么想,但其中的哈希代码让我感到害怕,我不喜欢自己搞清楚这个。 该路径也会根据程序集是否使用强名称签名而改变,以及诸如当前版本、可执行文件名、公司名称等其他因素。 由于硬编码任何类型的算法将是一个痛苦,并且会引入大量的依赖关系,因此存在潜在的故障点,我不认为这是一个选择。
解决方案
显然,解决方案是修复或简单地删除 user.config 文件,但我们必须先找到它才能这样做。 我不会深入讨论修复,因为据我所知,没有简单的方法可以做到这一点。 在大多数情况下,删除用户的应用程序设置虽然不方便,但并不是世界末日,只要事先警告用户即将发生这种情况即可。 当然,您可以采取其他措施。
事实证明,user.config 文件的路径一直都在异常中! 但是,它巧妙地隐藏在 InnerException
中,也许这就是它最初让我迷惑的原因。 所以,请允许我展示一段代码,它将以通用的方式处理这种情况。 您应该将此代码块放在应用程序启动附近的某个位置,在调用 Settings
之前
try {
Settings.Default.Reload();
} catch ( ConfigurationErrorsException ex ) { //(requires System.Configuration)
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
}
您需要添加对 System.Configuration
的引用才能使用 ConfigurationErrorsException
类型。 上面的代码使用 WPF 版本的 MessageBox
;如果您使用的是 Windows Forms,则需要对其进行调整。
试用
要试用它,您只需在文本编辑器中打开有效的 user.config 文件,并进行一些解析引擎不喜欢的更改,例如向根添加一些数据,或删除结束标记。 然后,只需启动您的应用程序,您现在应该会收到适当的警告。
关注点
如果有人有任何替代解决方案,请不要犹豫分享!
历史
- 2008 年 10 月 17 日 - 首次发布。