Here is a one class example of the idea. I would add another class just for
the XmlSerializer and serialize/deserialize that class. That way, you can
make the AppConfig ctor() private. That way, only public way to get
instance is with static Load method.
using System;
using System.Xml.Serialization;
using System.IO;
using System.IO.IsolatedStorage;
using System.Reflection;
namespace MyAppConfig
{
/// <summary>
/// AppConfig is loaded and saved to ISO storage as XML. You can
/// use this class to load and save your application settings for
/// your assembly. Just add any fields you need in the class as
/// public fields or public properties with *both get and set accessors
/// as required by XmlSerializer.
///
/// Note: It would be better to create another class just for the
/// serialization such as XmlAppConfig that contains just the
/// public fields you want to save and operate on that. We could
/// then remove the public default constructor below. However this
/// is a simple one class example.
///
/// Code Example:
/// // Load appconfig. Could put in Form Load event.
/// string configFile = "appconfig.xml";
/// AppConfig appConfig = AppConfig.Load(configFile);
///
/// // Update it as your config changes in your app.
/// appConfig.X = 6;
///
/// // Save it to storage. Could put in Form Closing event.
/// appConfig.Save();
/// </summary>
public sealed class AppConfig
{
private string isoFileName;
public int X = 2; // Default.
public int Y = 3; // Default.
// ... Add any others...
public AppConfig() // Default public constructor for XmlSerializer only.
{
}
public string FileName
{
get { return this.isoFileName; }
}
public AppConfig(string isoFileName)
{
this.isoFileName = isoFileName;
}
public void ResetDefaults()
{
AppConfig mac = new AppConfig(this.isoFileName);
mac.Save();
this.X = mac.X;
this.Y = mac.Y;
}
public static AppConfig Load(string file)
{
IsolatedStorageFile isoStore =
IsolatedStorageFile.GetStore(IsolatedStorageScope. Assembly |
IsolatedStorageScope.User, null, null);
if ( ! AppConfig.ISOFileExists(isoStore, file) )
{
AppConfig ac = new AppConfig(file);
ac.Save();
return ac;
}
string xml = AppConfig.ReadFromISOFile(isoStore, file);
Console.WriteLine("Xml:\n"+xml);
try
{
AppConfig mac = AppConfig.FromXmlString(xml);
mac.isoFileName = file;
return mac;
}
catch
{
// Xml not valid - may be corrupted or wrong version, etc.
// Rewrite it with defaults.
AppConfig ac = new AppConfig(file);
ac.Save();
return ac;
}
}
public void Save()
{
string xml = ToXmlString();
IsolatedStorageFile isoStore =
IsolatedStorageFile.GetStore(IsolatedStorageScope. Assembly |
IsolatedStorageScope.User, null, null);
AppConfig.WriteToISOFile(isoStore, isoFileName, xml);
}
public string ToXmlString()
{
string data = null;
XmlSerializer ser = new XmlSerializer(typeof(AppConfig));
using(StringWriter sw = new StringWriter())
{
ser.Serialize(sw, this);
sw.Flush();
data = sw.ToString();
return data;
}
}
public static AppConfig FromXmlString(string xmlString)
{
if ( xmlString == null )
throw new ArgumentNullException("xmlString");
AppConfig mac = null;
XmlSerializer ser = new XmlSerializer(typeof(AppConfig));
using (StringReader sr = new StringReader(xmlString))
{
mac = (AppConfig)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)))
{
writer.Write(data);
}
}
private static string ReadFromISOFile(IsolatedStorageFile isoStore, string
fileName)
{
string sb = null;
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 [MVP]" <st***********@mvps.org> wrote in message
news:uV**************@TK2MSFTNGP14.phx.gbl...
Just use ISO storage and serialize/deserialize your config class with
XmlSerializer. Simple and plenty fast for this usage. If you have to
parse a file anyway, why not let XmlSerializer do it instead of doing it
manually?
--
William Stacey, MVP
http://mvp.support.microsoft.com
"MrNobody" <Mr******@discussions.microsoft.com> wrote in message
news:31**********************************@microsof t.com... PK, thank you for the information. I have been looking around and I
think I found something called "Isolated Storage" which seems to reduce some of the overhead in reading/writing files in your own section of the Documents
and Settings folder you just mentioned. But I thinkI'll go with a
traditional INI style file- seems silly to me to use XML and then use a DataSet to
access the data like I'm finding on some online tutorials- doesn't anyone worry
about overhead, performance or memory footprints anymore?
Thanks again for your reply
"PK" wrote:
The app config file should only be used to store read-only
configuration settings. This makes sense, as the application and the config file are
stored in the "Program Files" directory. Normal users have read-only
access to the "Program Files" directory, so it makes sense to put read-only files in there.
Of course, some hatefull programmers will try to write in there
anyway, forcing me to run their apps as administrator. Very, Very, Very Bad Thing To Do!
Well behaved applications store their machine-wide settings and data
in application-specific folders under the CommonApplicationData folder
and user settings and data under the ApplicationData or LocalApplicationData folder. E.g. Outlook stores you mailbox under the LocalApplicationData folder
(typically C:\Documents and Settings\SomeUser\Local
Settings\Application Data\Microsoft\Outlook).
The difference between AppData and LocalAppData is that anything
placed in AppData is part of the user's roaming profile and follows him to any machine he logs on.
You can get the actual location of these folders from the System.Environment class, e.g:
System.Environment.GetFolderPath(System.Environmen t.SpecialFolder.CommonAppl icationData);
System.Environment.GetFolderPath(System.Environmen t.SpecialFolder.Applicatio nData);
Once you decide where to store the app's settings, you can store them
manually as an XML file, or you can use Microsoft's Configuration Management Application Block
(http://msdn.microsoft.com/library/de...-us/dnbda/html /cmab.asp). The Application Block provides greater flexibility because it allows
you to store the settings in a file, the registry or a database.
BTW, these restrictions are imposed by Windows themselves, not .NET.
In fact, an application that wants to get the "Designed for Windows" logo
must comply with them.