C# Settings.Default.Save() not saving? [duplicate]

2020-02-09 01:06发布

this bug is pretty unusual. Basically my code will change the Settings.Default.Example then save and restart the program. Then when it loads, it shows a message box. However oddly, it shows a empty value when the form loads.

Here is my code:

Main.cs
    private void Button1_Click(object sender, EventArgs e)
    {
        Settings.Default.Example = "Somevalue"; //Sets a value to the settings
        Settings.Default.Save(); // Save it
        MessageBox.Show(Settings.Default.Example); //Confirming it has been saved
        Application.Restart();
    }

    private void Main_Load(object sender, EventArgs e)
    {
        MessageBox.Show(Settings.Default.Example); // Here is the weird part, it shows empty.
    }

The MessageBox will show "Somevalue" when the button was clicked then the applcation restarts and the MessageBox that showed was empty. However repeating the process by clicking the button once more and restarting it does show the "Somevalue" MessageBox. Please help! Many Thanks!

标签: c# settings
10条回答
The star\"
2楼-- · 2020-02-09 01:45

Beware of calling

Settings.Default.Reload();

after each

Settings.Default.Save();

Save() function actually saves your changes to the file but it is not reflected to your running code. Thus, your code keeps the copy of the previous version of the file.

When you call Save() at another location in your code, it writes over your first change, effectively reverting your first change back to original value. Very hard to pin down even when debugging.

查看更多
smile是对你的礼貌
3楼-- · 2020-02-09 01:45

I had the same problem.

To sort out the problem.

Go to the custom class in Visual Studio. Open the class and Check whether the constructor method.

If you have a constructor method, it should be parameterless. If you have a constructor with parameters, don;t worry. Create another constructor class without an parameters.

Repeat this for all sub classes within the class.

Rebuild and run. Now your settings should save.

查看更多
对你真心纯属浪费
4楼-- · 2020-02-09 01:54

Using Visual Studio 2013 - there is nothing I could do to make it work reliably, I would call Save and it did not save. Save and then immediately Reload and it still would not retain the values on subsequent runs (probably related to when I stopped debugging could not identify the root cause) - very frustrating, likely there is an underlying bug but I cannot prove it.

To avoid getting crazy with this I decided to use the registry - the most fundamental way to keep app settings for an app. Recommended for you all. Here is the code:

public static class RegistrySettings
{

private static RegistryKey baseRegistryKey = Registry.CurrentUser;
private static string _SubKey = string.Empty;

public static string SubRoot 
{
    set
    { _SubKey = value; }
}

public static string Read(string KeyName, string DefaultValue)
{
    // Opening the registry key 
    RegistryKey rk = baseRegistryKey;

    // Open a subKey as read-only 
    RegistryKey sk1 = rk.OpenSubKey(_SubKey);

    // If the RegistrySubKey doesn't exist return default value
    if (sk1 == null)
    {
        return DefaultValue;
    }
    else
    {
        try
        {
            // If the RegistryKey exists I get its value 
            // or null is returned. 
            return (string)sk1.GetValue(KeyName);
        }
        catch (Exception e)
        {
            ShowErrorMessage(e, String.Format("Reading registry {0}", KeyName.ToUpper()));
            return null;
        }
    }
}

public static bool Write(string KeyName, object Value)
{
    try
    {
        // Setting
        RegistryKey rk = baseRegistryKey;
        // I have to use CreateSubKey 
        // (create or open it if already exits), 
        // 'cause OpenSubKey open a subKey as read-only
        RegistryKey sk1 = rk.CreateSubKey(_SubKey);
        // Save the value
        sk1.SetValue(KeyName, Value);

        return true;
    }
    catch (Exception e)
    {
        ShowErrorMessage(e, String.Format("Writing registry {0}", KeyName.ToUpper()));
        return false;
    }
}

private static void ShowErrorMessage(Exception e, string Title)
{
    if (ShowError == true)
        MessageBox.Show(e.Message,
                Title
                , MessageBoxButtons.OK
                , MessageBoxIcon.Error);
}
}

Usage:

private void LoadDefaults()
{
    RegistrySettings.SubRoot = "Software\\Company\\App";

    textBoxInputFile.Text = RegistrySettings.Read("InputFileName");
}

private void SaveDefaults()
{
    RegistrySettings.SubRoot = "Software\\Company\\App";

    RegistrySettings.Write("InputFileName", textBoxInputFile.Text);
}
查看更多
戒情不戒烟
5楼-- · 2020-02-09 01:56

Please have a look at this Question

Especially, try out the following code from an answer there:

using System.Configuration;  // Add a reference to System.Configuration.dll
...
var path = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath;

Also, check out this overview, perhaps you ran into some limitation which is not easy to tell from your question.

This codeproject article might be of some help.

查看更多
登录 后发表回答