您的位置:首页 > 移动开发

【MSDN文摘】Persisting Application Settings in the .NET Framework

2007-03-02 15:37 651 查看
Persisting Application Settings in the .NET Framework

Jeff Danner

Microsoft Corporation

June 2002

Summary:
How to persist applications settings at run time in the Microsoft .NET
Framework by saving them to the registry or serializing them to a
configuration file. (20 printed pages)

Contents

Introduction
Prerequisites to Saving Application Settings
Using the Registry to Store Data

Saving Data to the Registry

Retrieving Data From the Registry

Creating a Custom Application Configuration Class
Using Your Application Settings Class with Your Application

Loading Saved Application Settings

Saving Application Settings
Conclusion

Introduction

Saving
application settings is a common task. In the past you would have saved
your settings in an INI file or in the registry. With the Microsoft®
.NET Framework, you have the additional option of serializing the
application settings into an XML file and easily updating and
retrieving those settings. Microsoft Visual Studio® .NET uses the System.Configuration.AppSettingsReader class to read its DynamicProperties,
which are stored in a configuration file. However, the dynamic
properties are read-only at run time, so you cannot persist the changes
made by the user. This paper describes how to serialize your data and
write it out to a file as well as how to read and deserialize the data.
How and where you store your data depends on what you want to store, I
will discuss how to save your data in the appropriate locations, based
upon its type.

Prerequisites to Saving Application Settings

The Windows Forms Application
class contains several properties that allow easy navigation to the
appropriate part of the registry or user data folder. In order to use
these properties correctly, you must set the AssemblyCompany, AssemblyProduct and AssemblyVersion attributes.

These attributes set values that are exposed by the Control class through the CompanyName, ProductName and ProductVersion properties.

The following is a simple Windows form that sets the assembly attributes and displays them in a Label:

//C#
using System;
using System.Windows.Forms;
using System.Reflection;

// Set the assembly attributes.
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("MyApplication")]
[assembly: AssemblyVersion("1.0.1")]
public class AboutDialogBox : Form
{
public AboutDialogBox()
{
// Display the assembly information in a Label.
Label label1 = new Label();
label1.Text = this.CompanyName + " "
+ this.ProductName + " Version: "
+ this.ProductVersion;
label1.AutoSize = true;
this.Controls.Add(label1);
}

[STAThread]
static void Main()
{
Application.Run(new AboutDialogBox());
}
}


Using the Registry to Store Data

You
may not want to simply serialize data that is viewed as sensitive or
vital to the application, since anyone can view or edit the data with a
text editor; the registry makes the data less accessible. The registry
provides a robust store for application and user settings. Most back-up
programs automatically back up the registry settings, and when you put
information in the right place in the registry, you automatically get
user isolation when storing settings. Although users can edit the
registry, they generally tend not to, and this makes your settings more
stable. Overall, when Microsoft Windows® Logo guidelines for registry
usage are followed, it is a reasonable place to store application
settings.

Your application will require Create and Write registry permissions to write to the registry and Read permission to read the registry. For more information working with registry keys, see the documentation for the GetValue and SetValue methods of the Microsoft.Win32.RegistryKey class and the System.Security.Permissions.RegistryPermissionAccess enumeration documentation in the .NET Framework SDK documentation.

To save information to the registry, use the UserAppDataRegistry or CommonAppDataRegistry property of the Application class. These properties return a RegistryKey object that can be used to store application data, based on the user type:

The UserAppDataRegistry property
returns the registry key that is used to store roaming data (settings
that are specific to a user but machine independent) for each user; the
registry key takes the form HKEY_CURRENT_USER\Software\[Control.CompanyName]\[Control.ProductName]\[Control.ProductVersion].

The CommonAppDataRegistry
property returns the registry key that is used to store non-user
specific and non-roaming data for the machine; the registry key takes
the form HKEY_LOCAL_MACHINE\Software\[Control.CompanyName]\[Control.ProductName]\[Control.ProductVersion].

These two properties are read-only; however, the RegistryKey object they return has several methods that enable you to read, update, or create registry keys and their values.

Saving Data to the Registry

The following example saves the connection string to the registry when the form is closed, if it has changed

// C#
private bool appSettingsChanged;
private string connectionString;

private void Form1_Closing(object sender, CancelEventArgs e)
{
if(appSettingsChanged)
{
try
{
// Save the connection string to the registry, if it has changed.
Application.UserAppDataRegistry.SetValue("ConnString",
connectionString);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message );
}
}
}


Retrieving Data From the Registry

The following example retrieves a connection string from the registry when the form loads.

// C#
private bool appSettingsChanged;
private string connectionString;

private void Form1_Load(object sender, EventArgs e)
{
try
{
// Get the connection string from the registry.
if(Application.UserAppDataRegistry.GetValue("ConnString") != null)
{
connectionString =
Application.UserAppDataRegistry.GetValue(
"ConnString").ToString();
statusBar1.Text = "ConnectionString: " +
connectionString;
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}


Creating a Custom Application Configuration Class

The
application configuration class described in this paper serializes an
instance of itself as XML. Serialization is the process of converting
an object or a graph of objects into a linear sequence of bytes for
either storage or transmission to another location. Deserialization is
the process of taking in stored or transmitted information and
recreating objects from it. You can serialize an object as text (XML
being text with a hierarchical structure) or in a binary format. For
more information on serialization, see Serializing Objects in the .NET Framework Developer's Guide.

Windows Forms classes that derive from Control
cannot be easily serialized as XML since they contain objects that have
dynamic states, such as a window handle (HWND). Since controls cannot
easily be entirely serialized, and because you generally do not need to
persist every property exposed by the control, you should create a
small XML-serializable class to store the desired property values. For
example, you might only need to store the form's BackColor, the last directory where the user saved a file, or the Location of the form when it was last closed. Your application will require Write permissions to write or create the XML file and Read permission to read the XML file. For more information, see the documentation for the StreamWriter constructor and the System.Security.Permissions.FileIOPermissionAccess enumeration documentation in the .NET Framework SDK. Some types cannot be serialized as XML without first being converted. For example, a System.Drawing.Color must be converted to an integer using its ToArgb
method to convert it to a value that can be serialized as XML. Type
converters can also be used to convert types to string representations.
For more information on type converters, see the TypeConverter class documentation and Implementing a Type Converter in the .NET Framework SDK Documentation.

Several properties of the Application class provide the application storage paths that can be used to store application data:

The UserAppDataPath property is used to
store roaming data (settings that are specific to a user but machine
independent) for each user; the path takes the form [UserName]\Application Data\[Control.CompanyName]\[Control.ProductName]\[Control.ProductVersion].

The LocalUserAppDataPath property is used to store non-roaming data for each user; the path takes the form [UserName]\Local Settings\Application Data\[Control.CompanyName]\[Control.ProductName]\[Control.ProductVersion].

The CommonAppDataPath
property is used to store non-user specific, non-roaming data for the
machine; the path takes the form All Users\Application Data\[Control.CompanyName]\[Control.ProductName]\[Control.ProductVersion].

Note The UserName value used in the data paths is retrieved from the UserName property of the System.Environment class.

Typically,
the roaming store holds smaller data such as window settings while the
non-roaming store holds larger data, for example a cache of large
bitmaps.

The following example includes a class that stores settings for an application. The class provides the SaveAppSettings and LoadAppSettings methods to load (deserialize) and save (serialize) your application settings. The BackColor
property value is stored as an integer so it can be serialized. The
example saves the serialized data to a file named MyApplication.config.
Note that this is not the same file as the App.config file used by
Visual Studio .NET.

Create the class and add a Boolean variable that
specifies whether the application settings have changed. Be sure to add
a reference to the System.Xml.Serialization and System.IO namespaces, as well as references to any other namespaces you might need to use to store your data.

// C#
using System;
using System.Xml.Serialization;
using System.IO;
using System.Drawing;

namespace Samples
{
public class ApplicationSettings
{
private bool appSettingsChanged;
}
}


Add private variables to store the application settings and create public properties to access them.

// C#
// Variables used to store the application settings.
private string m_defaultDirectory;
private int m_backColor;
private Point m_formLocation;

// Properties used to access the application settings variables.
public string DefaultDirectory
{
get{return m_defaultDirectory;}
set
{
if(value != m_defaultDirectory)
{
m_defaultDirectory = value;
appSettingsChanged = true;
}
}
}

public int BackColor
{
get{return m_backColor;}
set
{
if(value != m_backColor)
{
m_backColor = value;
appSettingsChanged = true;
}
}
}

public Point FormLocation
{
get{return m_formLocation;}
set
{
if(value != m_formLocation)
{
m_formLocation = value;
appSettingsChanged = true;
}
}
}


Add a method to serialize the application settings and save them to the configuration file.

// C#
// Serializes the class to the config file
// if any of the settings have changed.
public bool SaveAppSettings()
{
if(this.appSettingsChanged)
{
StreamWriter myWriter = null;
XmlSerializer mySerializer = null;
try
{
// Create an XmlSerializer for the
// ApplicationSettings type.
mySerializer = new XmlSerializer(
typeof(ApplicationSettings));
myWriter =
new StreamWriter(Application.LocalUserAppDataPath
+ @"\myApplication.config",false);
// Serialize this instance of the ApplicationSettings
// class to the config file.
mySerializer.Serialize(myWriter, this);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
// If the FileStream is open, close it.
if(myWriter != null)
{
myWriter.Close();
}
}
}
return appSettingsChanged;
}


Add a method to deserialize the application settings from the configuration file.

// C#
// Deserializes the class from the config file.
public bool LoadAppSettings()
{
XmlSerializer mySerializer = null;
FileStream myFileStream = null;
bool fileExists = false;

try
{
// Create an XmlSerializer for the ApplicationSettings type.
mySerializer = new XmlSerializer(typeof(ApplicationSettings));
FileInfo fi = new FileInfo(Application.LocalUserAppDataPath
+ @"\myApplication.config");
// If the config file exists, open it.
if(fi.Exists)
{
myFileStream = fi.OpenRead();
// Create a new instance of the ApplicationSettings by
// deserializing the config file.
ApplicationSettings myAppSettings =
(ApplicationSettings)mySerializer.Deserialize(
myFileStream);
// Assign the property values to this instance of
// the ApplicationSettings class.
this.m_backColor = myAppSettings.BackColor;
this.m_formLocation = myAppSettings.FormLocation;
this.m_defaultDirectory = myAppSettings.DefaultDirectory;
fileExists = true;
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
// If the FileStream is open, close it.
if(myFileStream != null)
{
myFileStream.Close();
}
}

if(m_defaultDirectory == null)
{
// If myDirectory is not set, default
// to the user's "My Documents" directory.
m_defaultDirectory = Environment.GetFolderPath(
System.Environment.SpecialFolder.Personal);
this.appSettingsChanged = true;
}
return fileExists;
}


Using Your Application Settings Class with Your Application

You
only need to add a few lines of code to your application to use the
application settings class to serialize and deserialize values you
would like to persist.

Loading Saved Application Settings

You must have a variable of the type defined to hold your application setting; in this example it is an ApplicationSettings
class named
applicationSettings. In the appropriate place in your code, call the method that deserializes the data; in this example, the method is named LoadAppSettings(), and it is called in the Load event of the form. You could call this method in the constructor after any other initialization code, or in the Load event handler. You then assign the stored values to the corresponding properties of your application.

The following example loads the application settings in the Load
event of the form and assigns the values to their corresponding
properties. This example assumes that your form has a variable named defaultDirectory.

// C#
// If the LoadAppSettings method is successful, assign the
// ApplicationSettings properties to their corresponding form properties.
private void Form1_Load(object sender, EventArgs e)
{
if(this.applicationSettings.LoadAppSettings() )
{
// Create a Color from the integer (ARGB) value.
this.BackColor = Color.FromArgb(applicationSettings.BackColor);
this.Location = applicationSettings.FormLocation;
this.defaultDirectory = applicationSettings.DefaultDirectory;
}
}


Saving Application Settings

You must have a variable of the type defined to hold your application setting; in this example it is an ApplicationSettings
class named
applicationSettings.
In the appropriate place in your code, you assign the property values
you want to persist to the corresponding properties in the application
settings class. If the properties you are persisting have a changed
event such as the BackColorChanged event, you can update the
corresponding property in your application settings class in that event
handler. This updates the instance of your applications settings class
every time the user or your application changes the property.

Before closing the application, call the method that serializes the data; in this example the method is named SaveAppSettings(), and it is called in the Closing event of the form. You could call this method in the Closing event handler or overload the Close method to take a Boolean value to specify whether to save the application settings.

The following example updates the properties in the application settings class and saves the application settings in the Closing event of the form.

// C#
// Save the new location to the ApplicationSettings
// object when it is changed.
private void Form1_LocationChanged(object sender, EventArgs e)
{
applictionSettings.FormLocation = this.Location;
}

// Save the new BackColor to the ApplicationSettings
// object when it is changed.
private void Form1_BackColorChanged(object sender, EventArgs e)
{
applicationSettings.BackColor = this.BackColor.ToArgb();
}

// Save the new default directory to the ApplicationSettings object
// before serializing the class settings and closing the form.
private void Form1_Closing(object sender, CancelEventArgs e)
{
applicationSettings.DefaultDirectory = this.defaultDirectory;
applicationSettings.SaveAppSettings();
}


Conclusion

As
in the past, you can read from and write to the registry with the
appropriate permissions; however, you should try to limit the amount of
data stored in the registry. With minimal implementation and
customization, the .NET Framework gives you the ability to easily
serialize your application settings and store the data as XML. Unlike
the application configuration model that Visual Studio .NET provides,
the serialized data can be read and updated.

The application
data and registry data paths used in this document complies with the
Windows logo guidelines. To ensure your application complies with all
the Windows logo guidelines, see Designed for Microsoft Windows XP Application Specification section of the Designed for Windows Logo Program on the Microsoft Web site.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐