• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 591
  • Last Modified:

C# Code To Store Settings

What would be some example code to store data for future use in a C# 2010 program? (ie: check boxes on a form left checked, or unchecked, and text that was left in a field, so when reponening the program, the text is still there) Thanks
0
NewMacAdmin
Asked:
NewMacAdmin
2 Solutions
 
ericpeckhamCommented:
For example, add a checkbox to a form, as follows:

 The checkbox on the form
You can bind its value to a value saved in a user settings file, as in the following image.  I created the saved value "SaveMe" by clicking on "New..." at the bottom of the drop-down window:

 checkBox1 properties
Then all you have to do is make sure you save the settings, as in this example, when the main window is being closed:

namespace WindowsFormsApplication1
{
      public partial class Form1 : Form
      {
            public Form1()
            {
                  InitializeComponent();
            }

            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                  WindowsFormsApplication1.Properties.Settings.Default.Save();
            }
      }
}
0
 
NewMacAdminAuthor Commented:
Where will that settings file be placed, what will it's name/file extension be?  Can I encrypt it to prevent the data from being tampered with?
0
 
ericpeckhamCommented:
I assumed you were using Visual Studio with a WinForms application.  Here's the code that the designer generated for the checkbox (from Form1.Designer.cs):

                  // checkBox1
                  //
                  this.checkBox1.AutoSize = true;
                  this.checkBox1.Checked = global::WindowsFormsApplication1.Properties.Settings.Default.SaveMeValue;
                  this.checkBox1.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::WindowsFormsApplication1.Properties.Settings.Default, "SaveMeValue", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
                  this.checkBox1.Location = new System.Drawing.Point(27, 24);
                  this.checkBox1.Name = "checkBox1";
                  this.checkBox1.Size = new System.Drawing.Size(69, 17);
                  this.checkBox1.TabIndex = 1;
                  this.checkBox1.Text = "Save Me";
                  this.checkBox1.UseVisualStyleBackColor = true;

Here's the code VS generated for the setting to be saved (from Properties\Settings.Designer.cs):

namespace WindowsFormsApplication1.Properties {
   
   
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
       
        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
       
        public static Settings Default {
            get {
                return defaultInstance;
            }
        }
       
        [global::System.Configuration.UserScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("False")]
        public bool SaveMeValue {
            get {
                return ((bool)(this["SaveMeValue"]));
            }
            set {
                this["SaveMeValue"] = value;
            }
        }
    }
}

0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
NewMacAdminAuthor Commented:
It doesn't seem to five much option for encrypting the settings file.  Is there a manual way to save settings such as text in a txtbox or a checkbox check status?
0
 
ericpeckhamCommented:
Here's a brief description of how user settings files work.

When VS builds the app, it places a file containing default application settings in the same directory as the application - in this case the file is named WindowsFormsApplication1.exe.config.

When the settings are first saved (in this case the first time the window is closed), .NET creates a file under the user's AppData directory, which looks a lot like the .config file above, except it has the actual saved settings instead of the default settings.  On my computer, it was saved at C:\Users\eric\AppData\Local\Microsoft\WindowsFormsApplication1._Url_31h2hba23faolvxzzag45mwubsv0qqk3\1.0.0.0\user.config.  If this file exists when the application first looks for a value, it will look to see if this file exists, and if so, it loads those settings.  If it's not there, it uses the default settings in the app directory.

I think there may be a way to encrypt this data, although you normally shouldn't need to worry about that as the user area of a hard drive is usually off limits to other users.  If you need to encrypt sensitive data, you will need to do that in your code before it's saved, and then decrypt it when it is being loaded.
0
 
NewMacAdminAuthor Commented:
How can I do that in my code then?  Some of the data will be sensitive. Thanks
0
 
Nathan BoveSoftware EngineerCommented:
If you are storing sensitive data, you should probably be using a database like SQL Server or Oracle.
0
 
ericpeckhamCommented:
nbove makes a good point.  We could probably be more helpful if you were to explain exactly what you need to do.  I would appreciate it if you would accept my answer, as I have answered your original question.  This encryption thing should probably be another question, and I would be glad to help with that.
0
 
_valkyrie_Commented:
You could use a collection of settings, serialize it and encrypt it during that process.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;

namespace WpfApplication1
{
    [Serializable()]
    public class Settings : Dictionary<string,string>
    {
        private const string Salt = "911BE5F6-B97B-4156-99F5-DC70DB585B33";

        public Settings() { }

        public Settings(SerializationInfo info, StreamingContext context) : base(info, context) { }
            
        #region " Class Storage "
        public static void Save(Settings settings, string filename, string password)
        {
            RijndaelManaged algorithm = Settings.SetupEncryptionAlgorithm(password);

            using (FileStream output = new FileStream(filename, FileMode.Create))
            {
                using (CryptoStream encryptedStream = 
                    new CryptoStream(output, algorithm.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    BinaryFormatter serializer = new BinaryFormatter();
                    serializer.Serialize(encryptedStream, settings);
                }
            }
        }

        public static Settings Load(string filename, string password)
        {
            if (!File.Exists(filename))
                return new Settings();
            Settings toReturn;

            RijndaelManaged algorithm = Settings.SetupEncryptionAlgorithm(password);

            using (FileStream input = new FileStream(filename, FileMode.Open))
            {
                using (CryptoStream decryptedStream = 
                    new CryptoStream(input, algorithm.CreateDecryptor(), CryptoStreamMode.Read))
                {
                    BinaryFormatter serializer = new BinaryFormatter();
                    toReturn = (Settings)serializer.Deserialize(decryptedStream);
                }
            }

            return toReturn;
        }

        private static RijndaelManaged SetupEncryptionAlgorithm(string password)
        {
            RijndaelManaged algorithm = new RijndaelManaged();
            Rfc2898DeriveBytes key =
                new Rfc2898DeriveBytes(password, Encoding.ASCII.GetBytes(Settings.Salt));
            algorithm.Key = key.GetBytes(algorithm.KeySize / 8);
            algorithm.IV = key.GetBytes(algorithm.BlockSize / 8);
            return algorithm;
        }
        #endregion

    }
}

Open in new window


I attached the full example project which includes a UI that saves 1 string from a textbox. The password is hard-coded (terrible idea but just for a quick example).


Ok, it won't let me attach the zip file. So here is the WPF Window code:
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" SizeToContent="Height" Width="525" Closing="Window_Closing">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <TextBox Name="txtData" Grid.ColumnSpan="2" Margin="5" />
        <Button Content="Save" HorizontalAlignment="Right" Name="btnSave" Grid.Row="1"  Margin="0,0,5,5" IsDefault="True" Grid.Column="0" Click="btnSave_Click" />
        <Button Content="Load" HorizontalAlignment="Right" Name="btnLoad" Grid.Row="1"  Margin="0,0,5,5" Grid.Column="1" Click="btnLoad_Click" />
    </Grid>
</Window>

Open in new window

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private Settings settings;
        private const string MyFirstKey = "MyFirstSetting";

        public MainWindow()
        {
            InitializeComponent();
            this.settings = Settings.Load("test.cfg", "MyPassword");
            if (this.settings.ContainsKey(MyFirstKey))
                this.txtData.Text = this.settings[MyFirstKey];
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            if (this.settings.ContainsKey(MyFirstKey))
                this.settings[MyFirstKey] = this.txtData.Text;
            else
                this.settings.Add(MyFirstKey, this.txtData.Text);
        }

        private void btnLoad_Click(object sender, RoutedEventArgs e)
        {
            if (this.settings.ContainsKey(MyFirstKey))
                this.txtData.Text = this.settings[MyFirstKey];
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Settings.Save(this.settings, "test.cfg", "MyPassword");
        }
    }
}

Open in new window

0
 
Éric MoreauSenior .Net ConsultantCommented:
0
 
NewMacAdminAuthor Commented:
I am simply storing a checkbox to determine if a string should be saved.  The string is a seed to generate a unique password for a machine (from a previously asked question of mine).  The encryption is just to protect the seed.

ericpeckham is correct in that he did answer my original question.  I will however award a few points for the answer to my follow up question. Thanks
0

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now