Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.Configuration
Imports System.Collections
Imports System.Collections.Specialized
Imports System.Diagnostics

' The following example shows how to use the ConfigurationManager 
' class in a console application.
'
' IMPORTANT: To compile this example, you must add to the project 
' a reference to the System.Configuration assembly.
'
Namespace Samples.Aspnet
#Region "Auxiliary Classes"

    ' Define a custom configuration element to be 
    ' contained by the ConsoleSection. This element 
    ' stores background and foreground colors that
    ' the application applies to the console window.
    Public Class ConsoleConfigElement
        Inherits ConfigurationElement
        ' Create the element.
        Public Sub New()
        End Sub

        ' Create the element.
        Public Sub New(ByVal fColor As ConsoleColor, _
                       ByVal bColor As ConsoleColor)
            ForegroundColor = fColor
            BackgroundColor = bColor
        End Sub

        ' Get or set the console background color.
        <ConfigurationProperty("background", _
            DefaultValue:=ConsoleColor.Black, IsRequired:=False)> _
        Public Property BackgroundColor() As ConsoleColor
            Get
                Return DirectCast(Me("background"), ConsoleColor)
            End Get
            Set(ByVal value As ConsoleColor)
                Me("background") = value
            End Set
        End Property

        ' Get or set the console foreground color.
        <ConfigurationProperty("foreground", _
            DefaultValue:=ConsoleColor.White, IsRequired:=False)> _
        Public Property ForegroundColor() As ConsoleColor
            Get
                Return DirectCast(Me("foreground"),  _
                  ConsoleColor)
            End Get
            Set(ByVal value As ConsoleColor)
                Me("foreground") = value
            End Set
        End Property
    End Class

    ' Define a custom section that is used by the application
    ' to create custom configuration sections at the specified 
    ' level in the configuration hierarchy.
    ' This enables the the user that has the proper access 
    ' rights, to make changes to the configuration files.
    Public Class ConsoleSection
        Inherits ConfigurationSection
        ' Create a configuration section.
        Public Sub New()
        End Sub

        ' Set or get the ConsoleElement. 
        <ConfigurationProperty("consoleElement")> _
        Public Property ConsoleElement() _
            As ConsoleConfigElement
            Get
                Return (DirectCast(Me("consoleElement"),  _
                        ConsoleConfigElement))
            End Get
            Set(ByVal value As ConsoleConfigElement)
                Me("consoleElement") = value
            End Set
        End Property
    End Class
#End Region

#Region "ConfigurationManager Interaction Class"

    ' The following code uses the ConfigurationManager class to 
    ' perform the following tasks:
    ' 1) Get the application roaming configuration file.
    ' 2) Get the application configuration file.
    ' 3) Access a specified configuration file through mapping.
    ' 4) Access the machine configuration file through mapping. 
    ' 5) Read a specified configuration section.
    ' 6) Read the connectionStrings section.
    ' 7) Read or write the appSettings section.
    Public Class UsingConfigurationManager
        ' Get the roaming configuration file associated 
        ' with the application.
        ' Note.This function uses the OpenExeConfiguration(
        ' ConfigurationUserLevel userLevel) method to 
        ' get the configuration file.
        Public Shared Sub GetRoamingConfiguration()
            ' Define the custom section to add to the
            ' configuration file.
            Dim sectionName As String = "consoleSection"
            Dim cSection As ConsoleSection = Nothing

            ' Get the roaming configuration 
            ' that applies to the current user.
            Dim roamingConfig As Configuration = _
            ConfigurationManager.OpenExeConfiguration( _
            ConfigurationUserLevel.PerUserRoaming)

            ' Map the roaming configuration file. This
            ' enables the application to access 
            ' the configuration file using the
            ' System.Configuration.Configuration class
            Dim configFileMap As New ExeConfigurationFileMap()
            configFileMap.ExeConfigFilename = roamingConfig.FilePath

            ' Get the mapped configuration file.
            Dim config As Configuration = _
                ConfigurationManager.OpenMappedExeConfiguration( _
                configFileMap, ConfigurationUserLevel.None)

            Try
                cSection = DirectCast(config.GetSection(sectionName),  _
                ConsoleSection)

                If cSection Is Nothing Then
                    ' Create a custom configuration section.
                    cSection = New ConsoleSection()

                    ' Define where in the configuration file 
                    ' hierarchy the associated 
                    ' configuration section can be declared.
                    cSection.SectionInformation.AllowExeDefinition = _
                    ConfigurationAllowExeDefinition.MachineToLocalUser

                    ' Allow the configuration section to be 
                    ' overridden by other configuration files.
                    cSection.SectionInformation.AllowOverride = True

                    ' Force the section to be saved.
                    cSection.SectionInformation.ForceSave = True

                    ' Store console settings for roaming users.
                    cSection.ConsoleElement.BackgroundColor = _
                    ConsoleColor.Blue
                    cSection.ConsoleElement.ForegroundColor = _
                    ConsoleColor.Yellow

                    ' Add configuration information to 
                    ' the configuration file.
                    config.Sections.Add(sectionName, cSection)
                    config.Save(ConfigurationSaveMode.Modified)
                    ' Force a reload of the changed section. This 
                    ' makes the new values available for reading.
                    ConfigurationManager.RefreshSection(sectionName)
                End If
            Catch e As ConfigurationErrorsException
                Console.WriteLine("[Exception error: {0}]", _
                                  e.ToString())
            End Try

            ' Set console properties using values
            ' stored in the configuration file.
            Console.BackgroundColor = _
            cSection.ConsoleElement.BackgroundColor
            Console.ForegroundColor = _
            cSection.ConsoleElement.ForegroundColor
            ' Apply the changes.
            Console.Clear()

            ' Display feedback.
            Console.WriteLine()
            Console.WriteLine("Performed the following tasks:")
            Console.WriteLine("Created roaming configuration file {0}", config.FilePath)
            Console.WriteLine("Created custom ConsoleSection.")
            Console.WriteLine( _
            "Stored background (blue) and foreground (yellow) colors.")
            Console.WriteLine( _
            "Added the section to the configuration file.")
            Console.WriteLine( _
            "Read stored colors from the configuration file.")
            Console.WriteLine( _
            "Applied the colors to the console window.")
            Console.WriteLine()

        End Sub

        ' Get the application configuration file.
        ' Note. This function uses the 
        ' OpenExeConfiguration(string)method 
        ' to get the application configuration file. 
        Public Shared Sub GetAppConfiguration()
            ' Get the application path needed to obtain
            ' the application configuration file.
            Dim applicationName As String = _
            Environment.GetCommandLineArgs()(0) + ".exe"

            Dim exePath As String = _
            System.IO.Path.Combine(Environment.CurrentDirectory, _
                                   applicationName)

            ' Get the configuration file. The file name has
            ' this format appname.exe.config.
            Dim config As System.Configuration.Configuration = _
            ConfigurationManager.OpenExeConfiguration(exePath)

            Try
                ' Create a custom configuration section
                ' having the same name used in the 
                ' roaming configuration file.
                ' This is possible because the configuration 
                ' section can be overridden by other 
                ' configuration files. 
                Dim sectionName As String = "consoleSection"
                Dim customSection As New ConsoleSection()

                If config.Sections(sectionName) Is Nothing Then
                    ' Store console settings.
                    customSection.ConsoleElement.BackgroundColor = _
                    ConsoleColor.Black
                    customSection.ConsoleElement.ForegroundColor = _
                    ConsoleColor.White

                    ' Add configuration information to the
                    ' configuration file.
                    config.Sections.Add(sectionName, customSection)
                    config.Save(ConfigurationSaveMode.Modified)
                    ' Force a reload of the changed section.
                    ' This makes the new values available for reading.
                    ConfigurationManager.RefreshSection(sectionName)
                End If
                ' Set console properties using values
                ' stored in the configuration file.
                customSection = DirectCast(config.GetSection(sectionName),  _
                ConsoleSection)
                Console.BackgroundColor = _
                customSection.ConsoleElement.BackgroundColor
                Console.ForegroundColor = _
                customSection.ConsoleElement.ForegroundColor
                ' Apply the changes.
                Console.Clear()
            Catch e As ConfigurationErrorsException
                Console.WriteLine("[Error exception: {0}]", e.ToString())
            End Try

            ' Display feedback.
            Console.WriteLine()
            Console.WriteLine("Performed the following tasks:")
            Console.WriteLine( _
            "Created the application configuration file {0}", _
            config.FilePath)
            Console.WriteLine("Created custom ConsoleSection.")
            Console.WriteLine( _
            "Stored background (black) and foreground (white) colors.")
            Console.WriteLine( _
            "Added the section to the configuration file.")
            Console.WriteLine( _
            "Read stored colors from the configuration file.")
            Console.WriteLine( _
            "Applied the colors to the console window.")
            Console.WriteLine()
        End Sub

        ' Get the AppSettings section.        
        ' This function uses the AppSettings property
        ' to read the appSettings configuration 
        ' section.
        Public Shared Sub ReadAppSettings()
            Try
                ' Get the AppSettings section.
                Dim appSettings As NameValueCollection = _
                ConfigurationManager.AppSettings

                ' Get the AppSettings section elements.
                Console.WriteLine()
                Console.WriteLine("Performed the following tasks:")
                Console.WriteLine("Read application settings:")
                Console.WriteLine()

                If appSettings.Count = 0 Then
                    Console.WriteLine( _
                    "[ReadAppSettings: {0}]", _
                    "AppSettings is empty Use GetSection command first.")
                End If
                Dim i As Integer = 0
                While i < appSettings.Count
                    Console.WriteLine("#{0} Key: {1} Value: {2}", i, _
                            appSettings.GetKey(i), appSettings(i))
                    System.Math.Max( _
                    System.Threading.Interlocked.Increment(i), i - 1)
                End While
            Catch e As ConfigurationErrorsException
                Console.WriteLine("[ReadAppSettings: {0}]", _
                                  e.ToString())
            End Try
        End Sub

        ' Get the ConnectionStrings section.        
        ' This function uses the ConnectionStrings 
        ' property to read the connectionStrings
        ' configuration section.
        Public Shared Sub ReadConnectionStrings()

            ' Get the ConnectionStrings collection.
            Dim connections _
            As ConnectionStringSettingsCollection = _
            ConfigurationManager.ConnectionStrings

            If connections.Count <> 0 Then

                Console.WriteLine()
                Console.WriteLine("Performed the following tasks:")
                Console.WriteLine("Read connection strings:")
                Console.WriteLine()

                ' Get the collection elements.
                For Each connection _
                As ConnectionStringSettings In connections
                    Dim name As String = connection.Name
                    Dim provider As String = connection.ProviderName
                    Dim connectionString As String = _
                    connection.ConnectionString

                    Console.WriteLine("Name:               {0}", _
                                      name)
                    Console.WriteLine("Connection string:  {0}", _
                                      connectionString)
                    Console.WriteLine("Provider:            {0}", _
                                      provider)
                Next
            Else
                Console.WriteLine()
                Console.WriteLine( _
                "No connection string is defined.")
                Console.WriteLine()
            End If
        End Sub


        ' Create the AppSettings section.
        ' The function uses the GetSection(string)method 
        ' to access the configuration section. 
        ' It also adds a new element to the section 
        ' collection.
        Public Shared Sub CreateAppSettings()
            ' Get the application configuration file.
            Dim config As System.Configuration.Configuration = _
            ConfigurationManager.OpenExeConfiguration( _
            ConfigurationUserLevel.None)

            Dim sectionName As String = "appSettings"

            ' Add an entry to appSettings.
            Dim appStgCnt As Integer = _
            ConfigurationManager.AppSettings.Count
            Dim newKey As String = "NewKey" + appStgCnt.ToString()

            Dim newValue As String = _
            DateTime.Now.ToLongDateString() + " " + _
            DateTime.Now.ToLongTimeString()

            config.AppSettings.Settings.Add(newKey, newValue)

            ' Save the configuration file.
            config.Save(ConfigurationSaveMode.Modified)

            ' Force a reload of the changed section. This 
            ' makes the new values available for reading.
            ConfigurationManager.RefreshSection(sectionName)

            ' Get the AppSettings section.
            Dim appSettingSection As AppSettingsSection = _
            DirectCast(config.GetSection(sectionName),  _
            AppSettingsSection)

            ' Display raw xml.
            Console.WriteLine()
            Console.WriteLine("Performed the following tasks:")
            Console.WriteLine("Created AppSettings section.")
            Console.WriteLine("Added new element to the section.")
            Console.WriteLine("Read the following settings:")
            Console.WriteLine()

            ' Get the AppSettings XML.
            Console.WriteLine( _
            appSettingSection.SectionInformation.GetRawXml())
        End Sub

        ' Access a configuration file using mapping.
        ' This function uses the OpenMappedExeConfiguration 
        ' method to access the roaming and the application
        ' configuration files.   
        ' It then uses the the custom ConsoleSection from
        ' each file to console window colors.
        Public Shared Sub MapExeConfiguration()
            ' Cotains the selected configuration.
            Dim config As System.Configuration.Configuration

            ' Get the roaming configuration file.
            Dim roamingConfig As Configuration = _
            ConfigurationManager.OpenExeConfiguration( _
            ConfigurationUserLevel.PerUserRoaming)

            ' Get the application configuration file.
            Dim appConfig As Configuration = _
            ConfigurationManager.OpenExeConfiguration( _
            ConfigurationUserLevel.None)

            ' To map the selected configuration file.
            Dim configFileMap As New ExeConfigurationFileMap()

            ' Map roaming configuration. This allows
            ' access to the roaming configuration file.
            configFileMap.ExeConfigFilename = roamingConfig.FilePath

            ' Get the mapped configuration file
            config = _
            ConfigurationManager.OpenMappedExeConfiguration( _
            configFileMap, ConfigurationUserLevel.None)

            Dim sectionName As String = "consoleSection"

            Dim customSection As ConsoleSection = _
            DirectCast(config.GetSection(sectionName),  _
            ConsoleSection)

            ' Set console properties using the 
            ' configuration values contained in the 
            ' mapped configuration file.
            Console.BackgroundColor = _
            customSection.ConsoleElement.BackgroundColor
            Console.ForegroundColor = _
            customSection.ConsoleElement.ForegroundColor
            Console.Clear()

            Console.WriteLine()
            Console.WriteLine("Performed following tasks:")
            Console.WriteLine( _
            "Mapped roaming configuration file: {0}", config.FilePath)
            Console.WriteLine( _
            "Set console colors from stored configuration values.")
            Console.WriteLine()
            Console.Write( _
            "Press Enter to switch to default colors.....")
            Console.ReadLine()

            ' Map roaming configuration. This allows
            ' access to the application configuration file.
            configFileMap.ExeConfigFilename = appConfig.FilePath

            ' Get the mapped configuration file
            config = _
            ConfigurationManager.OpenMappedExeConfiguration( _
            configFileMap, ConfigurationUserLevel.None)

            customSection = _
            DirectCast(config.GetSection(sectionName),  _
            ConsoleSection)

            If customSection Is Nothing Then
                customSection = New ConsoleSection()

                ' Store console settings.
                customSection.ConsoleElement.BackgroundColor = _
                ConsoleColor.Black
                customSection.ConsoleElement.ForegroundColor = _
                ConsoleColor.White

                ' Add configuration information to the
                ' configuration file.
                config.Sections.Add(sectionName, customSection)
                config.Save(ConfigurationSaveMode.Modified)
                ' Force a reload of the changed section.
                ' This makes the new values available for reading.
                ConfigurationManager.RefreshSection(sectionName)
            End If
            ' Set console properties using the 
            ' configuration values contained in the 
            ' mapped configuration file.
            Console.BackgroundColor = _
            customSection.ConsoleElement.BackgroundColor
            Console.ForegroundColor = _
            customSection.ConsoleElement.ForegroundColor
            Console.Clear()

            Console.WriteLine( _
            "Mapped application configuration file: {0}", _
            config.FilePath)
            Console.WriteLine( _
            "Set console colors from stored configuration values.")
            Console.WriteLine()
        End Sub

        ' Access the machine configuration file using mapping.
        ' The function uses the OpenMappedMachineConfiguration 
        ' method to access the machine configuration. 
        Public Shared Sub MapMachineConfiguration()
            ' Get the machine.config3 file.
            Dim machineConfig As Configuration = _
            ConfigurationManager.OpenMachineConfiguration()
            ' Get the machine.config file path.
            Dim configFile _
            As New ConfigurationFileMap(machineConfig.FilePath)

            ' Map the application configuration file to the machine 
            ' configuration file.
            Dim config As Configuration = _
            ConfigurationManager.OpenMappedMachineConfiguration( _
            configFile)

            ' Get the AppSettings section.
            Dim appSettingSection As AppSettingsSection = _
            DirectCast(config.GetSection("appSettings"),  _
            AppSettingsSection)
            appSettingSection.SectionInformation.AllowExeDefinition = _
            ConfigurationAllowExeDefinition.MachineToRoamingUser

            ' Display the configuration file sections.
            Dim sections As ConfigurationSectionCollection = _
            config.Sections

            Console.WriteLine()
            Console.WriteLine( _
            "Using OpenMappedMachineConfiguration.")
            Console.WriteLine( _
            "Sections in machine.config:")

            ' Get the sections in the machine.config.
            For Each section As ConfigurationSection In sections
                Dim name As String = section.SectionInformation.Name
                Console.WriteLine("Name: {0}", name)
            Next

        End Sub
    End Class
#End Region

#Region "User Interaction Class"

    ' Obtain user's input and provide feedback.
    ' This class contains the application Main() function.
    ' It calls the ConfigurationManager methods based 
    ' on the user's selection.
    Class ApplicationMain
        ' Display user's menu.
        Public Shared Sub DisplayUserMenu()
            Dim applicationName As String = _
            Environment.GetCommandLineArgs()(0)

            If Not applicationName.Contains(".exe") Then
                applicationName = _
                [String].Concat(applicationName, ".exe")
            End If

            Dim buffer As New StringBuilder()

            buffer.AppendLine()
            buffer.AppendLine("Application: " + applicationName)
            buffer.AppendLine("Please, make your selection.")
            buffer.AppendLine("Q,q  -- Exit the application.")
            buffer.Append("1    -- Set console window colors")
            buffer.AppendLine(" to blue and yellow")
            buffer.AppendLine("        from the roaming configuration.")
            buffer.AppendLine("2    -- Ceate appSettings section.")
            buffer.AppendLine("3    -- Read appSettings section.")
            buffer.AppendLine("        Values merged from application config.")
            buffer.Append("4    -- Set console window colors")
            buffer.AppendLine(" to black and white")
            buffer.AppendLine("        from the application configuration.")
            buffer.AppendLine("5    -- Read connectionStrings section.")
            buffer.AppendLine("        Values merged from machine.config.")
            buffer.AppendLine("6    -- Get specified configuration file.")
            buffer.Append("        Set console window colors")
            buffer.AppendLine(" from configured values.")
            buffer.AppendLine("7    -- Get machine.config file.")
            buffer.AppendLine()

            Console.Write(buffer.ToString())
        End Sub

        ' Obtain user's input and provide
        ' feedback.
        Shared Sub Main(ByVal args As String())
            ' Define user selection string.
            Dim selection As String = ""

            ' Get the name of the application.
            Dim appName As String = _
            Environment.GetCommandLineArgs()(0)

            While selection.ToLower() <> "q"
                ' Process user's input.
                Select Case selection
                    Case "1"
                        ' Show how to use OpenExeConfiguration
                        ' using the configuration user level.
                        UsingConfigurationManager.GetRoamingConfiguration()
                        Exit Select
                    Case "2"
                        ' Show how to use GetSection.
                        UsingConfigurationManager.CreateAppSettings()
                        Exit Select
                    Case "3"
                        ' Show how to use AppSettings.
                        UsingConfigurationManager.ReadAppSettings()
                        Exit Select
                    Case "4"
                        ' Show how to use OpenExeConfiguration
                        ' using the configuration file path.
                        UsingConfigurationManager.GetAppConfiguration()
                        Exit Select
                    Case "5"
                        ' Show how to use ConnectionStrings.
                        UsingConfigurationManager.ReadConnectionStrings()
                        Exit Select
                    Case "6"
                        ' Show how to use OpenMappedExeConfiguration.
                        UsingConfigurationManager.MapExeConfiguration()
                        Exit Select
                    Case "7"
                        ' Show how to use OpenMappedMachineConfiguration.
                        UsingConfigurationManager.MapMachineConfiguration()
                        Exit Select
                    Case Else

                        ' DisplayUserMenu();
                        Exit Select
                End Select
                DisplayUserMenu()
                Console.Write("> ")
                selection = Console.ReadLine()
            End While
        End Sub
    End Class
#End Region
End Namespace