How to write to config file

  • Thread starter Thread starter ALI-R
  • Start date Start date
A

ALI-R

Hi,,
I have two questions :

1) Is it mandatory that config file of a desktop application must be
App.config

2) Is it possible to update config file in your code??

thanks for your help.
ALI
 
Just create your own with strong types as you need. The following could
also me modified with encryption and/or ISO storage, etc.

MyAppConfig mac = new MyAppConfig();
mac.X = 20;
mac.Y = 40;
mac.Save();
MyAppConfig mac2 = MyAppConfig.Load();
Console.WriteLine("Name:"+mac2.Name);
Console.WriteLine("X:"+mac2.X);
Console.WriteLine("Y:"+mac2.Y);


using System;
using System.Xml.Serialization;
using System.IO;
using System.Reflection;

namespace MyNamespace
{
/// <summary>
/// Summary description for MyAppSettings.
/// </summary>
public sealed class MyAppConfig
{
public string Name;
public int X;
public int Y;
// ... Add others...

private static readonly string file;

static MyAppConfig()
{
file = Assembly.GetExecutingAssembly().Location + ".xml";
}

public MyAppConfig()
{
Name = Assembly.GetExecutingAssembly().GetName().Name;
}

public static MyAppConfig Load()
{
using(StreamReader sr = new StreamReader(MyAppConfig.file))
{
string xml = sr.ReadToEnd();
MyAppConfig mac = MyAppConfig.FromXmlString(xml);
return mac;
}
}

public void Save()
{
string myXml = this.ToXmlString();
using(StreamWriter sw = new StreamWriter(MyAppConfig.file))
{
sw.Write(myXml);
}
}

public string ToXmlString()
{
string data = null;
XmlSerializer ser = new XmlSerializer(typeof(MyAppConfig));
using(StringWriter sw = new StringWriter())
{
ser.Serialize(sw, this);
sw.Flush();
data = sw.ToString();
return data;
}
}

public static MyAppConfig FromXmlString(string xmlString)
{
if ( xmlString == null )
throw new ArgumentNullException("xmlString");

MyAppConfig mac = null;
XmlSerializer ser = new XmlSerializer(typeof(MyAppConfig));
using (StringReader sr = new StringReader(xmlString))
{
mac = (MyAppConfig)ser.Deserialize(sr);
}
return mac;
}
}
}
 
This version uses static methods and ISO storage for your assembly settings.
Potentially more usefull and don't need to worry about file path locations
or user stepping on the file. Scope is assembly and user specific so
different user's can have different settings. New assembly versions will
also have their own settings and not conflict with each other (i.e. user
running parallel versions.)

Usage example:
-------------------------
MyAssemConfig mac = MyAssemConfig.GetAssemConfig();
mac.X = 20;
mac.Y = 40;
MyAssemConfig.SetAppConfig(mac);

MyAssemConfig mac2 = MyAssemConfig.GetAssemConfig();
Console.WriteLine("Name:"+mac2.Name);
Console.WriteLine("X:"+mac2.X);
Console.WriteLine("Y:"+mac2.Y);

The Class:
---------------------
using System;
using System.Xml.Serialization;
using System.IO;
using System.IO.IsolatedStorage;
using System.Reflection;

namespace MyNamespace
{
/// <summary>
/// Summary description for MyAppSettings.
/// </summary>
public sealed class MyAssemConfig
{
public string Name;
public int X;
public int Y;
// ... Add others...

//private static readonly string file;
private static readonly string isoFileName;

static MyAssemConfig()
{
//file = Assembly.GetExecutingAssembly().Location + ".xml";
isoFileName = "AssemConfig.xml";
}

public MyAssemConfig()
{
Name = Assembly.GetExecutingAssembly().GetName().Name;
}

public static MyAssemConfig Reset()
{
MyAssemConfig mac = new MyAssemConfig();
MyAssemConfig.SetAppConfig(mac);
return mac;
}

public static MyAssemConfig GetAssemConfig()
{
IsolatedStorageFile isoStore =
IsolatedStorageFile.GetStore(IsolatedStorageScope.Assembly |
IsolatedStorageScope.User, null, null);

if ( ! MyAssemConfig.ISOFileExists(isoStore, isoFileName) )
return new MyAssemConfig();

string xml = MyAssemConfig.ReadFromISOFile(isoStore, isoFileName);
try
{
MyAssemConfig mac = MyAssemConfig.FromXmlString(xml);
return mac;
}
catch
{
// Xml not valid - probably corrupted. Rewrite it with defaults.
return MyAssemConfig.Reset();
}
}

public static void SetAppConfig(MyAssemConfig appConfig)
{
if ( appConfig == null )
throw new ArgumentNullException("appConfig");
string xml = appConfig.ToXmlString();

IsolatedStorageFile isoStore =
IsolatedStorageFile.GetStore(IsolatedStorageScope.Assembly |
IsolatedStorageScope.User, null, null);
MyAssemConfig.WriteToISOFile(isoStore, isoFileName, xml);
}

// public static MyAppConfig Load()
// {
// using(StreamReader sr = new StreamReader(MyAppConfig.file))
// {
// string xml = sr.ReadToEnd();
// MyAppConfig mac = MyAppConfig.FromXmlString(xml);
// return mac;
// }
// }

// public void Save()
// {
// string myXml = this.ToXmlString();
// using(StreamWriter sw = new StreamWriter(MyAppConfig.file))
// {
// sw.Write(myXml);
// }
// }

public string ToXmlString()
{
string data = null;
XmlSerializer ser = new XmlSerializer(typeof(MyAssemConfig));
using(StringWriter sw = new StringWriter())
{
ser.Serialize(sw, this);
sw.Flush();
data = sw.ToString();
return data;
}
}

public static MyAssemConfig FromXmlString(string xmlString)
{
if ( xmlString == null )
throw new ArgumentNullException("xmlString");

MyAssemConfig mac = null;
XmlSerializer ser = new XmlSerializer(typeof(MyAssemConfig));
using (StringReader sr = new StringReader(xmlString))
{
mac = (MyAssemConfig)ser.Deserialize(sr);
}
return mac;
}

private static bool ISOFileExists(IsolatedStorageFile isoStore, string
fileName)
{
if ( isoStore == null )
throw new ArgumentNullException("isoStore");
if ( fileName == null || fileName.Length == 0 )
return false;

string[] names = isoStore.GetFileNames("*");
foreach(string name in names)
{
if ( string.Compare(name, fileName, true) == 0 )
return true;
}
return false;
}

private static void WriteToISOFile(IsolatedStorageFile isoStore, string
fileName, string data)
{
// Assign the writer to the store and the file TestStore.
using(StreamWriter writer = new StreamWriter(new
IsolatedStorageFileStream(fileName, FileMode.Create, isoStore)))
{
// Have the writer write "Hello Isolated Storage" to the store.
writer.Write(data);
}
}

private static string ReadFromISOFile(IsolatedStorageFile isoStore, string
fileName)
{
string sb = null;
// This code opens the TestStore.txt file and reads the string.
using(StreamReader reader = new StreamReader(new
IsolatedStorageFileStream(fileName, FileMode.Open, isoStore)))
{
sb = reader.ReadToEnd();
}
return sb.ToString();
}
}
}
 
ALI-R said:
1) Is it mandatory that config file of a desktop application must be
App.config

This is a Visual Studio-ism. This is not what the configuration file ends
up getting called, this is just what it's called inside a Visual Studio .NET
project.

If you look in the build output directory (the bin\Release or bin\Debug
directory for C# projects, the bin directory for VB.NET projects) you'll see
that there is a file called MyApp.exe.config, where MyApp.exe is whatever
you've chosen to call your application executable.

This Whatever.exe.config file is a copy of the App.Config file. VS.NET
copies it so that you don't need to maintain a seperate debug and release
version of this file. And they use the name App.config because that's the
magic name they've chosen for this behaviour. :-)


2) Is it possible to update config file in your code??

Sometimes yes, but not always, so you shouldn't rely on being able to do
this.

Why might you not be able to? Well remember that the config file ends up in
the same directory as your executable. If it's installed as a normal
Windows app, this will be something like c:\Program
Files\Yourcompany\Yourapp.

Normal users will not be able to write to this directory. (At least not if
it's on an NTFS volume.) Windows protects the Program Files directory so
that only Administrators and Power Users are allowed to write into it.

So if you are relying on being able to write to your config file, you just
made it impossible for anyone not running as an admin or power user to run
your application!

Also, if you were thinking of putting user settings in there, you also just
made life difficult for anyone who has multiple users using the machine.

And if you think multi-user machines are unusual, they're not *that*
unusual. It doesn't have to be multiple concurrent users... If different
logins exist, storing user settings in the app config file doesn't work
well.

You should look at the Environment.GetFolder API to see where you should be
putting settings.
 
Hi,
Thanks for your complete answer.

About my first question ,,you mean in deployment I should change its name
from app.config to myapp.exe.config?? right??
 
thanks ,your answer is so complete and self-explanatory,
William Stacey said:
This version uses static methods and ISO storage for your assembly settings.
Potentially more usefull and don't need to worry about file path locations
or user stepping on the file. Scope is assembly and user specific so
different user's can have different settings. New assembly versions will
also have their own settings and not conflict with each other (i.e. user
running parallel versions.)

Usage example:
-------------------------
MyAssemConfig mac = MyAssemConfig.GetAssemConfig();
mac.X = 20;
mac.Y = 40;
MyAssemConfig.SetAppConfig(mac);

MyAssemConfig mac2 = MyAssemConfig.GetAssemConfig();
Console.WriteLine("Name:"+mac2.Name);
Console.WriteLine("X:"+mac2.X);
Console.WriteLine("Y:"+mac2.Y);

The Class:
---------------------
using System;
using System.Xml.Serialization;
using System.IO;
using System.IO.IsolatedStorage;
using System.Reflection;

namespace MyNamespace
{
/// <summary>
/// Summary description for MyAppSettings.
/// </summary>
public sealed class MyAssemConfig
{
public string Name;
public int X;
public int Y;
// ... Add others...

//private static readonly string file;
private static readonly string isoFileName;

static MyAssemConfig()
{
//file = Assembly.GetExecutingAssembly().Location + ".xml";
isoFileName = "AssemConfig.xml";
}

public MyAssemConfig()
{
Name = Assembly.GetExecutingAssembly().GetName().Name;
}

public static MyAssemConfig Reset()
{
MyAssemConfig mac = new MyAssemConfig();
MyAssemConfig.SetAppConfig(mac);
return mac;
}

public static MyAssemConfig GetAssemConfig()
{
IsolatedStorageFile isoStore =
IsolatedStorageFile.GetStore(IsolatedStorageScope.Assembly |
IsolatedStorageScope.User, null, null);

if ( ! MyAssemConfig.ISOFileExists(isoStore, isoFileName) )
return new MyAssemConfig();

string xml = MyAssemConfig.ReadFromISOFile(isoStore, isoFileName);
try
{
MyAssemConfig mac = MyAssemConfig.FromXmlString(xml);
return mac;
}
catch
{
// Xml not valid - probably corrupted. Rewrite it with defaults.
return MyAssemConfig.Reset();
}
}

public static void SetAppConfig(MyAssemConfig appConfig)
{
if ( appConfig == null )
throw new ArgumentNullException("appConfig");
string xml = appConfig.ToXmlString();

IsolatedStorageFile isoStore =
IsolatedStorageFile.GetStore(IsolatedStorageScope.Assembly |
IsolatedStorageScope.User, null, null);
MyAssemConfig.WriteToISOFile(isoStore, isoFileName, xml);
}

// public static MyAppConfig Load()
// {
// using(StreamReader sr = new StreamReader(MyAppConfig.file))
// {
// string xml = sr.ReadToEnd();
// MyAppConfig mac = MyAppConfig.FromXmlString(xml);
// return mac;
// }
// }

// public void Save()
// {
// string myXml = this.ToXmlString();
// using(StreamWriter sw = new StreamWriter(MyAppConfig.file))
// {
// sw.Write(myXml);
// }
// }

public string ToXmlString()
{
string data = null;
XmlSerializer ser = new XmlSerializer(typeof(MyAssemConfig));
using(StringWriter sw = new StringWriter())
{
ser.Serialize(sw, this);
sw.Flush();
data = sw.ToString();
return data;
}
}

public static MyAssemConfig FromXmlString(string xmlString)
{
if ( xmlString == null )
throw new ArgumentNullException("xmlString");

MyAssemConfig mac = null;
XmlSerializer ser = new XmlSerializer(typeof(MyAssemConfig));
using (StringReader sr = new StringReader(xmlString))
{
mac = (MyAssemConfig)ser.Deserialize(sr);
}
return mac;
}

private static bool ISOFileExists(IsolatedStorageFile isoStore, string
fileName)
{
if ( isoStore == null )
throw new ArgumentNullException("isoStore");
if ( fileName == null || fileName.Length == 0 )
return false;

string[] names = isoStore.GetFileNames("*");
foreach(string name in names)
{
if ( string.Compare(name, fileName, true) == 0 )
return true;
}
return false;
}

private static void WriteToISOFile(IsolatedStorageFile isoStore, string
fileName, string data)
{
// Assign the writer to the store and the file TestStore.
using(StreamWriter writer = new StreamWriter(new
IsolatedStorageFileStream(fileName, FileMode.Create, isoStore)))
{
// Have the writer write "Hello Isolated Storage" to the store.
writer.Write(data);
}
}

private static string ReadFromISOFile(IsolatedStorageFile isoStore, string
fileName)
{
string sb = null;
// This code opens the TestStore.txt file and reads the string.
using(StreamReader reader = new StreamReader(new
IsolatedStorageFileStream(fileName, FileMode.Open, isoStore)))
{
sb = reader.ReadToEnd();
}
return sb.ToString();
}
}
}

--
William Stacey, MVP
http://mvp.support.microsoft.com

William Stacey said:
Just create your own with strong types as you need. The following could
also me modified with encryption and/or ISO storage, etc.

MyAppConfig mac = new MyAppConfig();
mac.X = 20;
mac.Y = 40;
mac.Save();
MyAppConfig mac2 = MyAppConfig.Load();
Console.WriteLine("Name:"+mac2.Name);
Console.WriteLine("X:"+mac2.X);
Console.WriteLine("Y:"+mac2.Y);


using System;
using System.Xml.Serialization;
using System.IO;
using System.Reflection;

namespace MyNamespace
{
/// <summary>
/// Summary description for MyAppSettings.
/// </summary>
public sealed class MyAppConfig
{
public string Name;
public int X;
public int Y;
// ... Add others...

private static readonly string file;

static MyAppConfig()
{
file = Assembly.GetExecutingAssembly().Location + ".xml";
}

public MyAppConfig()
{
Name = Assembly.GetExecutingAssembly().GetName().Name;
}

public static MyAppConfig Load()
{
using(StreamReader sr = new StreamReader(MyAppConfig.file))
{
string xml = sr.ReadToEnd();
MyAppConfig mac = MyAppConfig.FromXmlString(xml);
return mac;
}
}

public void Save()
{
string myXml = this.ToXmlString();
using(StreamWriter sw = new StreamWriter(MyAppConfig.file))
{
sw.Write(myXml);
}
}

public string ToXmlString()
{
string data = null;
XmlSerializer ser = new XmlSerializer(typeof(MyAppConfig));
using(StringWriter sw = new StringWriter())
{
ser.Serialize(sw, this);
sw.Flush();
data = sw.ToString();
return data;
}
}

public static MyAppConfig FromXmlString(string xmlString)
{
if ( xmlString == null )
throw new ArgumentNullException("xmlString");

MyAppConfig mac = null;
XmlSerializer ser = new XmlSerializer(typeof(MyAppConfig));
using (StringReader sr = new StringReader(xmlString))
{
mac = (MyAppConfig)ser.Deserialize(sr);
}
return mac;
}
}
}
 
Yes, when deployed you need to make sure that the App.config file is renamed
myapp.exe.config. I thought (but could be wrong) that a VS.NET Setup and
Deployment project would do this automatically. But if you're doing your
own installer you'll need to do this.

Of course, the simple thing is just to install what VS.NET builds into the
bin\release directory - it will already have copied and renamed the file for
you. And you usually need to install everything that's in that directory...
 
No,it installs the file as it is.I mean it dosn't change the name of the
file.it keeps app.config and that was why mt application couldn't get the
settings from that in runtime.
 
Back
Top