Solved

C# Code To Store Settings

Posted on 2011-03-25
11
536 Views
Last Modified: 2013-12-17
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
Comment
Question by:NewMacAdmin
11 Comments
 
LVL 2

Accepted Solution

by:
ericpeckham earned 400 total points
Comment Utility
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
 

Author Comment

by:NewMacAdmin
Comment Utility
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
 
LVL 2

Expert Comment

by:ericpeckham
Comment Utility
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
 

Author Comment

by:NewMacAdmin
Comment Utility
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
 
LVL 2

Expert Comment

by:ericpeckham
Comment Utility
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
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 

Author Comment

by:NewMacAdmin
Comment Utility
How can I do that in my code then?  Some of the data will be sensitive. Thanks
0
 
LVL 7

Expert Comment

by:nbove
Comment Utility
If you are storing sensitive data, you should probably be using a database like SQL Server or Oracle.
0
 
LVL 2

Expert Comment

by:ericpeckham
Comment Utility
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
 
LVL 2

Assisted Solution

by:_valkyrie_
_valkyrie_ earned 100 total points
Comment Utility
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
 
LVL 69

Expert Comment

by:Éric Moreau
Comment Utility
0
 

Author Comment

by:NewMacAdmin
Comment Utility
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

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Code enhancement 5 12
DataGridview Currency Formating? 22 37
Code works but how can I download the file? 20 44
String manipulation 15 49
This article describes relatively difficult and non-obvious issues that are likely to arise when creating COM class in Visual Studio and deploying it by professional MSI-authoring tools. It is assumed that the reader is already familiar with the cla…
Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.
The viewer will learn how to use and create keystrokes in Netbeans IDE 8.0 for Windows.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now