locked
Config file on Class Library ??

    Question

  • Got a solution with 3 projects, a Web Service, a WinForms (MyUI), and a Class Library (Foo).

    MyUI calls methods in the DLL that access the web service.  The DLL has project config settings that store the URL of the web service.  I compile the solution and it compiles all 3 projects. In the DLL's bin dir it puts the foo.dll and foo.dll.config files.  However, in the WinForms bin dir it puts the MyUI.exe, MyUI.exe.config, and foo.dll;  it doesn't include the foo.dll.config.  When I run the MyUI.exe from its bin dir, it appears to work, and is obviously getting the config settings from somewhere because it doesn't crash and successfully contacts the web service.  However, if I copy the foo.dll.config file into the MyUI's bin dir, and change config settings and re-run, it appears to ignore my changes completely.

    In the Class Library I setup the config settings through the project properties dialog under the Settings tab.  I access them from code using My.Settings.

    What is going on here?  How do I modify the config settings post-compile?

    Thursday, March 16, 2006 5:18 PM

Answers

  • For a client application (i.e. a windows forms application) you normally have one configuration file, and that file is associated with the .exe (appname.exe.config).
    There is not a separate .config file for each dll.

    So why does it work, you ask? Well, since the URL of the web service is stored in a settings designer generated setting, and the settings designer also bakes in a DefaultSettingsValue (http://msdn2.microsoft.com/en-us/library/system.configuration.defaultsettingvalueattribute.aspx) for each setting unless you tell it not to, your application will still be able to find that value.

    If you want to override the value, you have to copy the appropriate entries from the dll's config file into the main exe's config file (including the sectionGroup element). For example, if I had a MyURL setting in my dll, I would copy the following info:

        <configSections>
            <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
                <section name="WindowsApplication236.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
            </sectionGroup>
        </configSections>


        <applicationSettings>
            <WindowsApplication236.My.MySettings>
                <setting name="MyURL" serializeAs="String">
                    <value>http://foo.bar.com</value>
                </setting>
            </WindowsApplication236.My.MySettings>
        </applicationSettings>

    Best regards,
    Johan Stenberg

    Thursday, March 16, 2006 9:49 PM
    Moderator
  • You can't mix'n match appSettings and applicationSettings.

    Using System.Configuration.ConfigurationSettings.AppSettings won't work, because that looks in the appSettings section of the config file, whereas the new configuration API uses the ApplicationSettings section

    Try accessing the setting from the dll's settings class (My.Settings.test_setting)

    Best regards,
    Johan Stenberg

    Monday, March 20, 2006 6:25 PM
    Moderator

All replies

  • For a client application (i.e. a windows forms application) you normally have one configuration file, and that file is associated with the .exe (appname.exe.config).
    There is not a separate .config file for each dll.

    So why does it work, you ask? Well, since the URL of the web service is stored in a settings designer generated setting, and the settings designer also bakes in a DefaultSettingsValue (http://msdn2.microsoft.com/en-us/library/system.configuration.defaultsettingvalueattribute.aspx) for each setting unless you tell it not to, your application will still be able to find that value.

    If you want to override the value, you have to copy the appropriate entries from the dll's config file into the main exe's config file (including the sectionGroup element). For example, if I had a MyURL setting in my dll, I would copy the following info:

        <configSections>
            <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
                <section name="WindowsApplication236.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
            </sectionGroup>
        </configSections>


        <applicationSettings>
            <WindowsApplication236.My.MySettings>
                <setting name="MyURL" serializeAs="String">
                    <value>http://foo.bar.com</value>
                </setting>
            </WindowsApplication236.My.MySettings>
        </applicationSettings>

    Best regards,
    Johan Stenberg

    Thursday, March 16, 2006 9:49 PM
    Moderator
  • Thank you for your reply. I had the same problem and after your reply all works fine.
    But I want to aks one more question, because my solution has more than 20 projects, and each project results in *.dll and *.dll.config.
    It is too complicated and too boring to copy-paste all 20 config files in the resulting app.config.
    So, this is my qeustion - Is it possible to "include" external config files in app.config but not do this time-wasting copy-pasting?
    I found something on the followed link
    http://blogs.msdn.com/junfeng/archive/2005/02/08/369662.aspx
    but it doesn't work for me.
    Any help or comment will be very appreciated.

    With best regards,
    Andrew Balan.
    Friday, March 17, 2006 11:56 AM
  • I still can't get this to work.  This is what I've done to recreate my problem:

    1) Create WinForms project (VB.Net).  I called mine ConfigTest_UI

    2) Add a new Class Library project (VB.Net).  I called mine ConfigTestDLL

    3) In the class library go to project properties -> Settings and add an application scope setting: test_setting = "foo - DLL"

    4) Add a method to the class1 in Class Library project:
    Public Function GetSetting() As String
        Return My.Settings.test_setting
    End Function

    5) Add a reference in the WinForms project to the Class Library project

    6) Add a button to Form1 in the WinForms project with the following code in the click event:
    Dim foo As New ConfigTestDLL.Class1
    MessageBox.Show(foo.GetSetting())

    When I run this project it works as expected, you click the button and it displays "foo".  But I can't figure out how to change the test_setting value post-compile using a config file.


    I'm running the application from the bin directory of the WinForms project.

    I tried adding a project setting to the WinForms project with the same name (test_setting) and a different value.  I then compiled and ran the exe, but the message is still pulling the value that I setup in the Class Library, not the WinForms setting.  However, I now have a .exe.config file in the bin directory, but changing its value appears to have no effect on the application.

    I notice that in the bin directory for the Class Library project there is a .dll.config file.  I tried copying this to the bin directory of the WinForms project, modifying its value, then running the exe in the same directory, but it had no effect on the application.

    I tried changing the code in the Class Library to retrieve the setting using: System.Configuration.ConfigurationSettings.AppSettings("test_setting").  But now it can't find any data and returns a blank string.

    I tried changing the code in the Class Library to retrieve the setting using:
    System.Configuration.ConfigurationManager.AppSettings("test_setting"). But it still returns an empty string.

    I tried copy-pasting the data from the dll.config file into the exe.config file, the resulting section looked like this:

    <applicationSettings>
        <ConfigTest_UI.My.MySettings>
            <setting name="test_setting" serializeAs="String">
                <value>foo - WinForms</value>
            </setting>
        </ConfigTest_UI.My.MySettings>
        <ConfigTestDLL.My.MySettings>
            <setting name="test_setting" serializeAs="String">
                <value>foo - DLL</value>
            </setting>
        </ConfigTestDLL.My.MySettings>
    </applicationSettings>

    When I try to run the application now, when I click the button it gives me the error: "Configuration System failed to initialize".  Under details it says: "System.Configuration.ConfigurationErrorsException: Configuration system failed to initialize ---> System.Configuration.ConfigurationErrorsException: Unrecognized configuration section applicationSettings/ConfigTestDLL.My.MySettings."

    It seems the only way it will work is using My.Settings in the DLL, but then I can't figure out how I can change the config setting post-compile.

    Friday, March 17, 2006 4:09 PM
  • You got almost all the way when you copied the entries from the dll's config to the app's config file - but as the error message indicates, you also need to copy the section declarations from the <configSections>. Take a closer look at my previous post in this thread.

    Using System.Configuration.ConfigurationSettings.AppSettings won't work, because that looks in the appSettings section of the config file, whereas the new configuration API uses the ApplicationSettings section (and, as a side not, the ConfigurationSettings class is only retained for backward compatibility - new applications should be using the ConfigurationManager or WebConfigurationManager classes instead)

    Best regards,
    Johan Stenberg

    Saturday, March 18, 2006 2:43 AM
    Moderator
  • Still a no go.  My Config file looks like this now:

     

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

    <configSections>

    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >

    <section name="ConfigTest_UI.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />

    <section name="ConfigTestDLL.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />

    </sectionGroup>

    </configSections>

    <system.diagnostics>

    <sources>

    <!-- This section defines the logging configuration for My.Application.Log -->

    <source name="DefaultSource" switchName="DefaultSwitch">

    <listeners>

    <add name="FileLog"/>

    <!-- Uncomment the below section to write to the Application Event Log -->

    <!--<add name="EventLog"/>-->

    </listeners>

    </source>

    </sources>

    <switches>

    <add name="DefaultSwitch" value="Information" />

    </switches>

    <sharedListeners>

    <add name="FileLog"

    type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"

    initializeData="FileLogWriter"/>

    <!-- Uncomment the below section and replace APPLICATION_NAME with the name of your application to write to the Application Event Log -->

    <!--<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="APPLICATION_NAME"/> -->

    </sharedListeners>

    </system.diagnostics>

    <applicationSettings>

    <ConfigTest_UI.My.MySettings>

    <setting name="test_setting" serializeAs="String">

    <value>Old Winforms Config Setting</value>

    </setting>

    </ConfigTest_UI.My.MySettings>

    <ConfigTestDLL.My.MySettings>

    <setting name="test_setting" serializeAs="String">

    <value>New DLL Config Setting</value>

    </setting>

    </ConfigTestDLL.My.MySettings>

    </applicationSettings>

    </configuration>

     

    I'm still getting an empty string returned when I use ConfigurationManager.AppSettings()

    Monday, March 20, 2006 3:02 PM
  • You can't mix'n match appSettings and applicationSettings.

    Using System.Configuration.ConfigurationSettings.AppSettings won't work, because that looks in the appSettings section of the config file, whereas the new configuration API uses the ApplicationSettings section

    Try accessing the setting from the dll's settings class (My.Settings.test_setting)

    Best regards,
    Johan Stenberg

    Monday, March 20, 2006 6:25 PM
    Moderator
  • Thanks, I got it figured out now.  I didn't realize that My.Settings and System.Configuration.AppSettings use 2 different layouts of the config files.

    After copying the DLL's config settings into the exe's config file, and changing my dll code back to use my.settings I managed to make it work.

    Tuesday, March 21, 2006 10:30 PM
  • Have you figured out a way? I have the same problem. I was wondering if ConfigurationManager.OpenExeConfiguration could help.

    Friday, April 14, 2006 8:29 PM
  • Why doesn't the solution suggested in this thread work for you?

    Best regards,
    Johan Stenberg

    Saturday, April 15, 2006 1:06 AM
    Moderator
  • This is frustrating. I have a Windows Service, a Windows Service Controller app (windows forms) and a class library where I store a number of settings using the My.Settings.etc syntax. The settings are wrapped around a number of public properties which are exposed to both the Windows Service and the controller app. The controller app needs to read and write to the settings while the service app only needs to read from them.

    I am able to propogate changes to the settings from the controller app. When I open the config file directly, the settings look unmodified. When I start the controller app up again, it recalls the changes - so I know they are stored somewhere (but I can't figure out where). I've tried various changes to the config files based on the previous posts, but nothing seems to work.

    The Windows Service app always and only sees the default settings regardless of what I try to do. So 2 questions:

    1. Where is the actual config file that the controller app uses to store settings?

    2. How can I modify my config file(s) so that both executables can see the same settings (or is this a fundamentally poor design pattern)?

     

    Thanks,

    Jim

     

     

    Monday, April 24, 2006 11:27 PM
  • Could you please explain this :
     
    settings designer also bakes in a DefaultSettingsValue (http://msdn2.microsoft.com/en-us/library/system.configuration.defaultsettingvalueattribute.aspx) for each setting unless you tell it not to
     
     
    Thursday, May 11, 2006 9:45 AM
  • Thursday, May 11, 2006 5:48 PM
    Moderator
  • You indicated that it is not possible to mix and match appSettings and applicationSettings. Given this, how should settings be accessed within the Class Library when it will be referenced by both a Web Application and a Windows Service?

     

    Unless I am missing something a Web.Config is completely different structure to an App.Config and only supports appSettings.

     

    I tried, e.g.

     

    Try

      myFolder = My.Settings.MyFolder

    Catch

      myFolder = System.Configuration.ConfigurationManager.AppSettings("myFolder")

    End Try

     

    though this doesn't work as the My.Settings doesn't raise an exception. It just returns nothing. 

     

    Alternatively

     

    If Not (My.Settings.MyFolder) Is Nothing Then

      myFolder = My.Settings.MyFolder

    Else

      myFolder = System.Configuration.ConfigurationManager.AppSettings("MyFolder")

    End If

    though this feels clunky and a fudge.

     

    Any suggestions?

     

    Tuesday, July 3, 2007 10:48 AM
  • To be clear, you *can* mix'n match appSettings and applicationSettings in the same configuration file, but don't expect the applicationSettings infrastructure to read settings defined in appSettings or the old appSettings stuff to pick things up from applicationSettings.

     

    Regarding the differences between app.config and web.config, the file formats are the same. The only difference is that there is a bunch of stuff in the web environment that is driven by the configuration file (i.e. how to compile an ASP.NET web site, debug settings) and other thingies that don't really apply for a client application.

     

    Application settings are supported in a web application as long as you stay away from user scoped settings (user scoped settings don't make much sense in the way that application settings treat them by default since the user in question is the user under which account the application - that is, IIS - is running). So, for a class library that is supposed to be consumable for a web application, just make sure that you use application scoped settings and things should work out just fine...

     

    Best regards,

    Johan Stenberg

     

     

    Tuesday, July 3, 2007 5:20 PM
    Moderator
  • Thanks for the tips, it worked fine for me too :)

    But I wonder why it is not automatic with Visual Studio ?!

    If there are several class projects linked to the main project, it has to be done for every project, at each compilation !
    Tuesday, May 12, 2009 1:19 PM
  • If you add the above changes to App.config in the main application project, then you don't have to redo the *.exe.config files with each compilation. 

    You only have to make changes to App.config when you change settings in one of the linked class library projects.  This allows you to decouple the settings for a specific application from the default settings for the class library.

    I agree that would be a good idea for Visual Studio to add this automatically to the main App.config file, at least as an option that is on by default.  The current behavior (VS2008) is unhelpful.
    -dwellingbrook
    • Proposed as answer by mbostrom Thursday, September 24, 2009 4:29 PM
    Thursday, September 24, 2009 4:21 PM
  • Hi Johan,

    Thanks a lot, for sharing information with us. It is working for me !!!

     

    Wednesday, October 13, 2010 7:13 AM
  • I am a long time VB6 programmer who finally gets to convert over to VB.net.

    I have a program that in VB6 had an extensive ini file driving it.  and i was told to convert it to use the settings or the app.config file.  so i have an app.config file that has a couple group sections with several sections in each.   I was wondering if there was a sample code clip to show how to access the section properties so they can be assigned adn assigned to.

    Thursday, March 1, 2012 11:27 PM
  • After spending multiple days combing through microsofts developer files and receiving absolutely NO HELP here, i have decided to drop DOT.NET .

    John Carp

    Sunday, March 11, 2012 10:34 PM
  • After spending multiple days combing through microsofts developer files and receiving absolutely NO HELP here, i have decided to drop DOT.NET .
    Maybe you should have started a new thread instead of jumping into an old one, which is often ignored.

    Armin

    Sunday, March 11, 2012 10:41 PM