Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What causes user.config to empty? And how do I restore without restarting?

Tags:

c#

app-config

I have noticed on a few machines in which my application's user.config file is somehow becoming corrupted and is empty when opening. I can't seem to figure out why this is happened. Is there a common thing that would cause this? Any way to safely prevent this?

My second question is how to do I restore the state? I catch the exception and delete the user.config file, but I cannot find a way to restore the configuration without restarting the application. Everything I do on the Properties object causes the following error:

"Configuration system failed to initialize"

Reset, Reload, and Upgrade all do nothing to solve the problem.

Here is my code for deleting after exception:

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);
}
like image 936
JeremyK Avatar asked Mar 05 '12 18:03

JeremyK


4 Answers

We had this issue in our app - and I was not able to find out WHY (my guess was that I was writing to Properties.Settings too often but I'm not sure). Anyway, my workaround for is below. The key is to delete corrupted file and call 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);
    }
}
like image 123
avs099 Avatar answered Oct 19 '22 11:10

avs099


I have a similar situation. For me, once I delete the bad configuration file, I just let the application continue. The next access of the settings will use the application defaults.

like image 45
Matt Avatar answered Oct 19 '22 12:10

Matt


This might be a bit late, but I've done some more research on this. The user.config file seems to get corrupted for an unknown reason and doesn't let the app start. you could put a small try/catch logic in your app.xaml.cs and check when it launches to make sure this problem is caught at the source. When the app launches and tries to programatically reload settings.default, and fails, it'll go to the exception giving the user an option to delete the file.

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
}

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

Hope this helps someone :)

like image 4
Arun Avatar answered Oct 19 '22 13:10

Arun


Here is how we solved the problem. This function must be called BEFORE ANY use of Properties.Settings... Else you would be stucked (as described by tofutim and 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;
    }
like image 1
Emmanuel Sellier Avatar answered Oct 19 '22 11:10

Emmanuel Sellier