By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,142 Members | 1,878 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,142 IT Pros & Developers. It's quick & easy.

Where can I store these settings?

P: n/a

Hi,

I am developing an application that needs to store some machine-specific
settings. The application is going to be published on the network in
order to keep the clients on the latest version.
Because of this, I am unable to store these settings in the App.Config
file, as this gets updated every time the application does, and there
doesn't appear to be a way of preventing this.

Most of my application settings are kept in the database, but there are
some that I need before the database connection is established.

What I need is a way of storing these so that they can be changed on
each machine, and that can preferably be edited with a text editor.
(I don't want to put them in the registry, because I want it to be easy
to copy the settings from one machine to another)

Is there any support for INI files in .Net?
Is there a better solution?
Thanks.

Paul Cheetham

May 24 '06 #1
Share this Question
Share on Google+
10 Replies


P: n/a
On Wed, 24 May 2006 11:02:54 +0100, Paul Cheetham
<PA******@dsl.pipex.com> wrote:

Hi,

I am developing an application that needs to store some machine-specific
settings. The application is going to be published on the network in
order to keep the clients on the latest version.
Because of this, I am unable to store these settings in the App.Config
file, as this gets updated every time the application does, and there
doesn't appear to be a way of preventing this.

Most of my application settings are kept in the database, but there are
some that I need before the database connection is established.

What I need is a way of storing these so that they can be changed on
each machine, and that can preferably be edited with a text editor.
(I don't want to put them in the registry, because I want it to be easy
to copy the settings from one machine to another)

Is there any support for INI files in .Net?
Is there a better solution?
Thanks.

Paul Cheetham


Maybe you can write a Settings class with the required properties, and
serialize/deserialize it to an xml file (XmlSerializer)?

--
Ludwig Stuyck
http://www.coders-lab.be
May 24 '06 #2

P: n/a
Having come to C#/.Net from a Delphi background I thought the ease of
storing local options was a bit lacking so I have created a class that does
just the type of thing you want.

1. You need to take the code below and create Settings.cs

2. Then in your program create a new class descended from SettingsObjectBase
that has all the settings you need to store in it. You can even have
collections etc.

public class MyAppSettings : SettingsObjectBase
{
public string Name;
public string Address;
public List<MyStuff> MyList = new List<MyStuff>();
}

3. Then at the start of your program do this:
SettingsStore<MyAppSettings> MySettingsStore = new
SettingsStore<MyAppSettings>(SettingsStoreLocation .UserApplicationLevel)

4. It will auto load as soon as you decclare it (if it can). But after this
you can do SettingsStore.Load() and SettingsStore.Save()

5. Then all you need to do is work with MyAppSettings throughout your
program to access your settings.

Let me know if this class is useful to anyone.
Code for Settings.cs:

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Windows.Forms;

namespace YourCompanyName.General
{
/// <summary>
/// Where to place the settings store
/// </summary>
public enum SettingsStoreLocation
{
/// <summary>
/// In the file specified
/// </summary>
SpecifiedFile,
/// <summary>
/// In the user home directory in the product folder
/// </summary>
UserProductLevel,
/// <summary>
/// In the user home directory in the product/appname folder
/// </summary>
UserApplicationLevel,
/// <summary>
/// In the common home directory in the product folder
/// </summary>
AllUsersProductLevel,
/// <summary>
/// In the common home directory in the product/appname folder
/// </summary>
AllUsersApplicationLevel
}

/// <summary>
/// Generic class for storing settings in XML
/// </summary>
public class SettingsStore<T> where T : SettingsObjectBase, new()
{
#region Construction
/// <summary>
/// Constructor for standard storage location + part file name
/// </summary>
/// <param name="Location">The place to store the settings</param>
/// <param name="FileName">The last part of the file name excluding
the
/// path unless using SpecifiedFile in which case this is the
/// full file name</param>
public SettingsStore(SettingsStoreLocation Location, string
FileName)
{
SetupLocation(Location, FileName);
}

/// <summary>
/// Constructor for standard storage location
/// </summary>
/// <param name="Location">The place to store the settings</param>
public SettingsStore(SettingsStoreLocation Location)
{
SetupLocation(Location, string.Empty);
}

/// <summary>
/// Constructor for specified storage location with full file name
/// </summary>
/// <param name="FileName">The full filename for where to store the
/// settings</param>
public SettingsStore(string FileName)
{
SetupLocation(SettingsStoreLocation.SpecifiedFile, FileName);
}

/// <summary>
/// Constructor for a specified file location that you do not know
yet.
/// You must set the FileName propery before calling Save/Load.
/// </summary>
/// <param name="Location"></param>
public SettingsStore()
{
SetupLocation(SettingsStoreLocation.SpecifiedFile,
string.Empty);
}

// Setup where the file will be stored
void SetupLocation(SettingsStoreLocation Location, string FileName)
{
_Location = Location;

if (_Location != SettingsStoreLocation.SpecifiedFile)
if (FileName.Trim() == string.Empty)
FileName = "Settings.xml";

switch (_Location)
{
case SettingsStoreLocation.SpecifiedFile:
_FileName = FileName;
break;
case SettingsStoreLocation.UserProductLevel:
_FileName = Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData) +
Path.DirectorySeparatorChar +
Application.CompanyName +
Path.DirectorySeparatorChar +
_ProductName + Path.DirectorySeparatorChar +
FileName;
break;
case SettingsStoreLocation.UserApplicationLevel:
_FileName = Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData) +
Path.DirectorySeparatorChar +
Application.CompanyName +
Path.DirectorySeparatorChar +
_ProductName + Path.DirectorySeparatorChar +
Path.GetFileNameWithoutExtension(Application.Execu tablePath)
+
Path.DirectorySeparatorChar +
FileName;
break;
case SettingsStoreLocation.AllUsersProductLevel:
_FileName = Environment.GetFolderPath(
Environment.SpecialFolder.CommonApplicationData) +
Path.DirectorySeparatorChar +
Application.CompanyName +
Path.DirectorySeparatorChar +
_ProductName + Path.DirectorySeparatorChar +
FileName;
break;
case SettingsStoreLocation.AllUsersApplicationLevel:
_FileName = Environment.GetFolderPath(
Environment.SpecialFolder.CommonApplicationData) +
Path.DirectorySeparatorChar +
Application.CompanyName +
Path.DirectorySeparatorChar +
_ProductName + Path.DirectorySeparatorChar +
Path.GetFileNameWithoutExtension(Application.Execu tablePath)
+
Path.DirectorySeparatorChar +
FileName;
break;
}

if ((_FileName != string.Empty) && (File.Exists(_FileName)))
Load();
else
Reset();
}
#endregion

#region Settings Access
// Internal store of settings object
T _Settings;
/// <summary>
/// The settings object holding the actual settings
/// </summary>
public T Settings
{
get
{
return _Settings;
}
}
#endregion

#region Storage
SettingsStoreLocation _Location;
/// <summary>
/// Where the settings will be stored
/// </summary>
public SettingsStoreLocation Location
{
get
{
return _Location;
}
}

string _FileName;
/// <summary>
/// The filename where the settings will be stored
/// </summary>
public string FileName
{
get
{
return _FileName;
}
set
{
_FileName = value;
_Location = SettingsStoreLocation.SpecifiedFile;
}
}

string _ProductName = Application.ProductName;
/// <summary>
/// This defaults to Application.ProductName but you can change it
/// e.g. if you want to create a shared product name to hold
settings
/// shared between a group of products
/// </summary>
public string ProductName
{
get
{
return _ProductName;
}
set
{
_ProductName = value;
}
}

/// <summary>
/// Save the settings to disk
/// </summary>
public void Save()
{
if (FileName.Trim() == string.Empty)
throw new Exception("No FileName has been specified");

Directory.CreateDirectory(Path.GetDirectoryName(_F ileName));

using (StreamWriter Writer = new StreamWriter(_FileName))
{
XmlSerializer Serializer = new XmlSerializer(typeof(T));

Serializer.Serialize(Writer, _Settings);
}

}

/// <summary>
/// Load the settings from disk. This happens automatically if you
/// specify a location when creating the object.
/// </summary>
public void Load()
{
if (FileName.Trim() == string.Empty)
throw new Exception("No FileName has been specified");

if (!File.Exists(_FileName))
throw new Exception("The file does not exist");

using (FileStream Reader = new FileStream(_FileName,
FileMode.Open))
{
XmlSerializer Serializer = new XmlSerializer(typeof(T));

_Settings = (T)Serializer.Deserialize(Reader);
}
}

/// <summary>
/// Reset the settings to their default state
/// </summary>
public void Reset()
{
_Settings = new T();
}

/// <summary>
/// Resets the settings to their default state and deletes the
storage file
/// </summary>
public void Delete()
{
if (File.Exists(_FileName))
File.Delete(_FileName);

Reset();
}
#endregion
}

/// <summary>
/// Base class for settings objects.
/// You must inherit your settings object from this.
/// </summary>
public abstract class SettingsObjectBase
{
}

}
--
Andrew Cutforth - AJC Software - www.ajcsoft.com
The best folder synchronize and directory compare tool available.
AJC Active Backup instantly archives every file you edit giving you
unlimited undo and automatic revision control. Never lose your data again.
May 24 '06 #3

P: n/a

Thanks Andrew.
That looks like a useful class, although it's a bit of overkill for what
I'm doing here, as I only need to read 3 or 4 settings at program startup.
I already have a settings class that pulls its information from a
database table. (If you want this let me know and I can send you the code)
I think I'll fall back to the good old ini files.
Paul.

Andrew wrote:
Having come to C#/.Net from a Delphi background I thought the ease of
storing local options was a bit lacking so I have created a class that does
just the type of thing you want.

1. You need to take the code below and create Settings.cs

2. Then in your program create a new class descended from SettingsObjectBase
that has all the settings you need to store in it. You can even have
collections etc.

public class MyAppSettings : SettingsObjectBase
{
public string Name;
public string Address;
public List<MyStuff> MyList = new List<MyStuff>();
}

3. Then at the start of your program do this:
SettingsStore<MyAppSettings> MySettingsStore = new
SettingsStore<MyAppSettings>(SettingsStoreLocation .UserApplicationLevel)

4. It will auto load as soon as you decclare it (if it can). But after this
you can do SettingsStore.Load() and SettingsStore.Save()

5. Then all you need to do is work with MyAppSettings throughout your
program to access your settings.

Let me know if this class is useful to anyone.
Code for Settings.cs:

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Windows.Forms;

namespace YourCompanyName.General
{
/// <summary>
/// Where to place the settings store
/// </summary>
public enum SettingsStoreLocation
{
/// <summary>
/// In the file specified
/// </summary>
SpecifiedFile,
/// <summary>
/// In the user home directory in the product folder
/// </summary>
UserProductLevel,
/// <summary>
/// In the user home directory in the product/appname folder
/// </summary>
UserApplicationLevel,
/// <summary>
/// In the common home directory in the product folder
/// </summary>
AllUsersProductLevel,
/// <summary>
/// In the common home directory in the product/appname folder
/// </summary>
AllUsersApplicationLevel
}

/// <summary>
/// Generic class for storing settings in XML
/// </summary>
public class SettingsStore<T> where T : SettingsObjectBase, new()
{
#region Construction
/// <summary>
/// Constructor for standard storage location + part file name
/// </summary>
/// <param name="Location">The place to store the settings</param>
/// <param name="FileName">The last part of the file name excluding
the
/// path unless using SpecifiedFile in which case this is the
/// full file name</param>
public SettingsStore(SettingsStoreLocation Location, string
FileName)
{
SetupLocation(Location, FileName);
}

/// <summary>
/// Constructor for standard storage location
/// </summary>
/// <param name="Location">The place to store the settings</param>
public SettingsStore(SettingsStoreLocation Location)
{
SetupLocation(Location, string.Empty);
}

/// <summary>
/// Constructor for specified storage location with full file name
/// </summary>
/// <param name="FileName">The full filename for where to store the
/// settings</param>
public SettingsStore(string FileName)
{
SetupLocation(SettingsStoreLocation.SpecifiedFile, FileName);
}

/// <summary>
/// Constructor for a specified file location that you do not know
yet.
/// You must set the FileName propery before calling Save/Load.
/// </summary>
/// <param name="Location"></param>
public SettingsStore()
{
SetupLocation(SettingsStoreLocation.SpecifiedFile,
string.Empty);
}

// Setup where the file will be stored
void SetupLocation(SettingsStoreLocation Location, string FileName)
{
_Location = Location;

if (_Location != SettingsStoreLocation.SpecifiedFile)
if (FileName.Trim() == string.Empty)
FileName = "Settings.xml";

switch (_Location)
{
case SettingsStoreLocation.SpecifiedFile:
_FileName = FileName;
break;
case SettingsStoreLocation.UserProductLevel:
_FileName = Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData) +
Path.DirectorySeparatorChar +
Application.CompanyName +
Path.DirectorySeparatorChar +
_ProductName + Path.DirectorySeparatorChar +
FileName;
break;
case SettingsStoreLocation.UserApplicationLevel:
_FileName = Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData) +
Path.DirectorySeparatorChar +
Application.CompanyName +
Path.DirectorySeparatorChar +
_ProductName + Path.DirectorySeparatorChar +
Path.GetFileNameWithoutExtension(Application.Execu tablePath)
+
Path.DirectorySeparatorChar +
FileName;
break;
case SettingsStoreLocation.AllUsersProductLevel:
_FileName = Environment.GetFolderPath(
Environment.SpecialFolder.CommonApplicationData) +
Path.DirectorySeparatorChar +
Application.CompanyName +
Path.DirectorySeparatorChar +
_ProductName + Path.DirectorySeparatorChar +
FileName;
break;
case SettingsStoreLocation.AllUsersApplicationLevel:
_FileName = Environment.GetFolderPath(
Environment.SpecialFolder.CommonApplicationData) +
Path.DirectorySeparatorChar +
Application.CompanyName +
Path.DirectorySeparatorChar +
_ProductName + Path.DirectorySeparatorChar +
Path.GetFileNameWithoutExtension(Application.Execu tablePath)
+
Path.DirectorySeparatorChar +
FileName;
break;
}

if ((_FileName != string.Empty) && (File.Exists(_FileName)))
Load();
else
Reset();
}
#endregion

#region Settings Access
// Internal store of settings object
T _Settings;
/// <summary>
/// The settings object holding the actual settings
/// </summary>
public T Settings
{
get
{
return _Settings;
}
}
#endregion

#region Storage
SettingsStoreLocation _Location;
/// <summary>
/// Where the settings will be stored
/// </summary>
public SettingsStoreLocation Location
{
get
{
return _Location;
}
}

string _FileName;
/// <summary>
/// The filename where the settings will be stored
/// </summary>
public string FileName
{
get
{
return _FileName;
}
set
{
_FileName = value;
_Location = SettingsStoreLocation.SpecifiedFile;
}
}

string _ProductName = Application.ProductName;
/// <summary>
/// This defaults to Application.ProductName but you can change it
/// e.g. if you want to create a shared product name to hold
settings
/// shared between a group of products
/// </summary>
public string ProductName
{
get
{
return _ProductName;
}
set
{
_ProductName = value;
}
}

/// <summary>
/// Save the settings to disk
/// </summary>
public void Save()
{
if (FileName.Trim() == string.Empty)
throw new Exception("No FileName has been specified");

Directory.CreateDirectory(Path.GetDirectoryName(_F ileName));

using (StreamWriter Writer = new StreamWriter(_FileName))
{
XmlSerializer Serializer = new XmlSerializer(typeof(T));

Serializer.Serialize(Writer, _Settings);
}

}

/// <summary>
/// Load the settings from disk. This happens automatically if you
/// specify a location when creating the object.
/// </summary>
public void Load()
{
if (FileName.Trim() == string.Empty)
throw new Exception("No FileName has been specified");

if (!File.Exists(_FileName))
throw new Exception("The file does not exist");

using (FileStream Reader = new FileStream(_FileName,
FileMode.Open))
{
XmlSerializer Serializer = new XmlSerializer(typeof(T));

_Settings = (T)Serializer.Deserialize(Reader);
}
}

/// <summary>
/// Reset the settings to their default state
/// </summary>
public void Reset()
{
_Settings = new T();
}

/// <summary>
/// Resets the settings to their default state and deletes the
storage file
/// </summary>
public void Delete()
{
if (File.Exists(_FileName))
File.Delete(_FileName);

Reset();
}
#endregion
}

/// <summary>
/// Base class for settings objects.
/// You must inherit your settings object from this.
/// </summary>
public abstract class SettingsObjectBase
{
}

}

May 24 '06 #4

P: n/a
>
Maybe you can write a Settings class with the required properties, and
serialize/deserialize it to an xml file (XmlSerializer)?

I only have 3 or 4 settings to read once at program startup, so it's a
bit of overkill going to all that trouble.

It looks like ini files are going to be my best bet really...
Thanks.
Paul
May 24 '06 #5

P: n/a
On Wed, 24 May 2006 11:59:17 +0100, Paul Cheetham
<PA******@dsl.pipex.com> wrote:

Maybe you can write a Settings class with the required properties, and
serialize/deserialize it to an xml file (XmlSerializer)?

I only have 3 or 4 settings to read once at program startup, so it's a
bit of overkill going to all that trouble.

It looks like ini files are going to be my best bet really...
Thanks.
Paul


Well it's only one class with 4 properties and a couple of lines of
code to serialize/deserialize it....
--
Ludwig Stuyck
http://www.coders-lab.be
May 24 '06 #6

P: n/a
You can use registry!

"Paul Cheetham" <PA******@dsl.pipex.com> wrote in message
news:uN**************@TK2MSFTNGP05.phx.gbl...

Hi,

I am developing an application that needs to store some machine-specific
settings. The application is going to be published on the network in order
to keep the clients on the latest version.
Because of this, I am unable to store these settings in the App.Config
file, as this gets updated every time the application does, and there
doesn't appear to be a way of preventing this.

Most of my application settings are kept in the database, but there are
some that I need before the database connection is established.

What I need is a way of storing these so that they can be changed on each
machine, and that can preferably be edited with a text editor.
(I don't want to put them in the registry, because I want it to be easy to
copy the settings from one machine to another)

Is there any support for INI files in .Net?
Is there a better solution?
Thanks.

Paul Cheetham

May 24 '06 #7

P: n/a

As I explained in my original post, I don't want to use the registry.
It's too difficult to copy the settings to another machine or make a
backup, and a real pain to manually edit.

Thanks.
Paul M wrote:
You can use registry!

May 24 '06 #8

P: n/a
Paul Cheetham wrote:

Is there any support for INI files in .Net?
Is there a better solution?


I know you already disregarded the XML serialization option in another
message, but you really should reconsider. With XML serialization of a
properties class you easily gain the ability to add new configuration
options. All you need to do is add a new property to the class.

If nothing else it will get you familiar with XML serialization, which
you will find immensely useful when you have a project that requires a
large amount of configuration information to be written out.

Andrew Faust
May 24 '06 #9

P: n/a
Well, firstly, the best place for these really is the registry.

Since you don't want to go that route, the next best would be some kind
of INI file. The .Net framework doesn't support them, but finding a C#
class to read/write them is as simple as a Google search. The one draw
back is that in a perfect world, only Admins would have write
permission on the Program Files tree, so if these settings change, you
should find a different place to put it beside the program folder.

May 24 '06 #10

P: n/a


Paul Cheetham wrote:

Maybe you can write a Settings class with the required properties, and
serialize/deserialize it to an xml file (XmlSerializer)?


I only have 3 or 4 settings to read once at program startup, so it's a
bit of overkill going to all that trouble.

It looks like ini files are going to be my best bet really...
Thanks.
Paul


The next program you write might have 30-40 or 300-400 settings so you might as
well bite the bullet and develop a generalised solution now.

In MFC, I actually use a .ini to store initial settings for the first run of the
program and then the registry from then on.

If users can change settings, you should supply them with a dialog in order to
do so rather than the error-prone method of a text editor.

(I have actually seen programs where the installation instructions say "run
regedit and then go to HKEY_CURRENT_USER and ....") !!!???
May 24 '06 #11

This discussion thread is closed

Replies have been disabled for this discussion.