asna.com Sign In
Using config files with AVR for .NET 8.0 Windows applications 

Download AVR 8.0 example

Windows programs have the built-in ability to read from a config file, in a fashion very similar to that of ASP.NET applications. To read from a configuration file is very simple--it only requires a couple of lines code. The configuration file itself is an XML file that must reside in the same folder as the program's EXE. The configuration file should have this format:

<configuration>
  <appSettings>
    <add key="x" value="y" />
  </appSettings>
</configuration>

where x is a case-sensitive key used to look up the value y. You can specify as many configuration values as you need, just uniquely identify each <add nodes with a unique key value. Generally, you'd create and maintain configuration files with Notepad or some other similar ASCII text editor. Take great care creating and editing these files; XML is very sensitive and if you're off even one character, any attempts to read the configuration will fail. Remember, too, that XML is case sensitive. The nodes of the configuration file must be provided exactly as shown. (Pay particular attention to the appSettings node, it must be specified as shown with the upper-case 'S.'

The config file must be named the same as its corresponding EXE, with ".config" appended to it. For example, for the program MyCoolProgram.exe, the config would be named MyCoolProgram.exe.config. While this file naming isn't case-sensitive, I always take care to keep the file name casing consistent.

Reading from this config file in a Windows program is very easy. There are two prerequisites before you write any code, though:

1. Add a reference the .NET System.Configuration assembly.
2. Add a Using System.Configuration at the top of the class in which you want to read config file values.

From there on, it's very easy to read the config value. For example, to read a value stored with a key value of "top," you'd use this code:

DclFld v Type( *String ) 

v = ConfigurationManager.AppSettings[ "top" ] 

Do note that these instructions are .NET 2.0-specific. Read the configuration documention for AVR for .NET 7.2; a similar, but not identical facility is available there.

Read only?

It's really easy to squirrel away values for read-only access from your Windows programs. However, what if you want to set values in the configuration file at runtime programatically? Sigh. The box stock configuration class doesn't provide for that.

Many Windows programs, though, need the ability to do just that. For example, consider the task of saving a user's window size and position and then restoring it exactly like they left it? That requires writing the top, left, height, and width properties to the config file at FileClosing time and then restoring those property values at FormLoad time.

For those times when you need to write to the config file, you can use the class provided below. It is syntactically compatible with the .NET configuration manager, so files you write with the class below can also be read with the Configuration manager. For semantic completeness, the class below lets you set, and get, a value from the config file with two shared methods: SetAppSetting and GetAppSetting.

Using this class is as easy as calling these shared members. For example, to save the position and size of a give window, and restore it at runtime, you'd only need to do this:

    BegSr Form1_FormClosing Access(*Private) Event(*this.FormClosing)
        DclSrParm sender Type(*Object)
        DclSrParm e Type(System.Windows.Forms.FormClosingEventArgs)
        
        Config.SetAppSetting( "top"   , *This.Top.ToString() ) 
        Config.SetAppSetting( "left"  , *This.Left.ToString() ) 
        Config.SetAppSetting( "height", *This.Height.ToString() ) 
        Config.SetAppSetting( "width" , *This.Width.ToString() )   
    EndSr                             
    
    BegSr Form1_Load Access(*Private) Event(*this.Load)
        DclSrParm sender Type(*Object)
        DclSrParm e Type(System.EventArgs)

        If ( Config.GetAppSetting( "top" ) <> String.Empty )   
            *This.Top     = Config.GetAppSetting( "top" ) 
            *This.Left    = Config.GetAppSetting( "left" ) 
            *This.Height  = Config.GetAppSetting( "height" ) 
            *This.Width   = Config.GetAppSetting( "width" ) 
        EndIf             
    EndSr

Note the If test in the Load event handler. This test checks to see if the key key value "top" exists. If it does not, it's assumed that none of the four values are present. If the value exists in the config file, the value is returned; if the value isn't present, an empty string is returned.

If you attempt to fetch a config file value and a config file isn't found, an application exception is thrown.

The Config class provided could also be easily modified to provide a more general-purpose config file editor. Note that to use the Config class, the user must have write rights to various folders on the PC. If they don't have these rights, you'd need to modfify the Config class so that the config file is stored somewhere in the user's My Documents folder.

Using System
Using System.Text
Using System.Xml 
Using System.Reflection
Using System.IO

BegClass Config Access(*Public)

    BegFunc GetAppSetting Type( *String ) Shared( *Yes ) Access( *Public )     
        //
        // Return appSetting for given key value. If key is not found, 
        // an empty string is returned. An exception is thrown if the 
        // config file doesn't exist.
        // 
        DclSrParm Key Type( *String ) 

        DclFld Xml        Type( XmlDocument )  New()
        DclFld XPath      Type( *String ) Inz( "configuration/appSettings/add[@key='{0}']" ) 
        DclFld KeyElement Type( XmlElement  ) 
        
        If ( NOT File.Exists( Assembly.GetExecutingAssembly().Location + ".config" ) )
            Throw *New System.Exception( ".config file not found" ) 
        EndIf 
        
        Xml.Load( Assembly.GetExecutingAssembly().Location + ".config" ) 
        KeyElement = Xml.SelectSingleNode( String.Format( XPath, Key ) ) *As XmlElement
        If ( KeyElement <> *Nothing ) 
            LeaveSr KeyElement.GetAttribute( "value" )         
        Else
            LeaveSr String.Empty 
        EndIf 
    EndFunc 

    BegSr SetAppSetting Shared( *Yes ) Access( *Public )     
        //
        // Set an appSetting value. If the .config file doesn't exist, one 
        // is created automatically.
        //
        DclSrParm Key   Type( *String ) 
        DclSrParm Value Type( *String ) 
        
        DclFld Xml        Type( XmlDocument )  New()
        DclFld Parent     Type( XmlElement  ) 
        DclFld KeyElement Type( XmlElement  ) 
        
        DclFld Mask       Type( *String )    Inz( "add[@key='{0}']" ) 

        If ( NOT File.Exists( Assembly.GetExecutingAssembly().Location + ".config" ) ) 
            CreateNewConfigFile()        
        EndIf 
        
        Xml.Load( Assembly.GetExecutingAssembly().Location + ".config" ) 
        
        Parent = Xml.SelectSingleNode( "configuration/appSettings" ) *As XmlElement
        KeyElement = Parent.SelectSingleNode( String.Format( Mask, Key ) ) *As XmlElement
        If ( KeyElement = *Nothing )
            KeyElement = Xml.CreateElement( "add" )  
            Parent.AppendChild( KeyElement )                
        EndIF             

        KeyElement.SetAttribute( "key", Key )
        KeyElement.SetAttribute( "value", Value ) 
        
        Xml.Save( Assembly.GetExecutingAssembly().Location + ".config" )         
    EndSr
    
    BegSr CreateNewConfigFile Shared( *Yes ) Access( *Private ) 
        //
        // Create an empty .config file.
        //
        DclFld Xml     Type( XmlDocument ) 
        DclFLd Node    Type( XmlNode ) 
        DclFld Parent  Type( XmlElement ) 
        DclFld Element Type( XmlElement ) 

        Xml = *New XmlDocument()
        
        Node = Xml.CreateNode( XmlNodeType.XmlDeclaration, String.Empty, String.Empty )
        Xml.AppendChild( Node ) 
        
        Element = Xml.CreateElement( "configuration" )
        Parent = Xml.AppendChild( Element ) *As XmlElement
        
        Element = Xml.CreateElement( "appSettings" )
        Parent.AppendChild( Element ) 
        
        Xml.Save( Assembly.GetExecutingAssembly().Location + ".config" )
    EndSr
EndClass
Related Articles
Article Downloads
 
Keywords:
 
Article ID: 398 
Category: ASNA Visual RPG : Web Development 
Applies To:  
Article Date: 1/1/2007