C# - User Settings broken

后端 未结 3 1711
情话喂你
情话喂你 2021-01-04 12:53

We had a rare exception occur when reading the standard .Net user settings (this are the ones found in \"project properties\" in VS 2008):

System.Configurati         


        
相关标签:
3条回答
  • 2021-01-04 13:27

    The way to programmatically recover is to do what you did manually - delete the user settings file. Then call Settings.Reset. (You could also write a new user settings file with default values instead of deleting it, but if you're using the configuration manager properly that's essentially the same thing.)

    This is a pretty rare occurrence, but it's not totally unheard of. Not only can your program crash while writing the user settings file, the file itself is user-writeable, so other programs the user runs could mess with it.

    To avoid this particular vulnerability, persist user settings in a durable store with transactional integrity, i.e. a database. (You'll still have vulnerabilities, just not this one.) That's a lot of work for what in most cases will be a marginal improvement in reliability. But "in most cases" doesn't mean "in all cases;" yours may warrant it.

    0 讨论(0)
  • 2021-01-04 13:30

    Here's a solution that does not require you to exit the application with kudos to Jarle (http://www.codeproject.com/Articles/30216/Handling-Corrupt-user-config-Settings?msg=3608682#xx3608682xx). Early on, before Settings ever gets called, use this

        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;
        }
    

    Essentially, rather than relying on Sittings to throw the error, read the file with the ConfigurationManager, that way the system's version never gets into a bad state.

    0 讨论(0)
  • 2021-01-04 13:37
    [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();
        }
    }
    
    0 讨论(0)
提交回复
热议问题