Client Settings FAQ posted

We have been getting lots of feedback on the new Whidbey Settings feature that I have blogged about in the past. Since there are a set of questions many people ask as they begin to delve into the API, I thought it might be useful to post an FAQ that I can point folks to that should answer most of these questions. I posted this as an article instead of a regular blog post so I can update it off and on in the future.

If you have any suggestions for questions to add to the FAQ, please feel free to leave a comment here.

Comments

  • Anonymous
    July 28, 2005
    Hi Prabhu,

    I had seen your "client settings" blog from part1 to part3, in all of these you are explaining about the ApplicationSettingsBase but I want to write my own custom SettingsProvider class. please help me out in
    How to write a custom SettingsProvider class?I am asking this question as we could not able to get any links explaining it in better way. If you can provide any samples that will be helpful and also please provide us a solution how to set this custom SettingsProvider to the application, so that application reads the settings from the custom SettingsProvider rather than default LocalFileSettingsProvider

    Thanks
    MDeevi.

  • Anonymous
    July 29, 2005
    There are a couple of sample SettingsProvider implementations in the Beta 2 SDK samples. These should get you started. Let me know if you could not find them.

  • Anonymous
    July 30, 2005
    Sorry! Prabhu, I could not able to find the samples in Beta2 SDK. Can u please get me the links or sample code so that i will try to change according to our requirement.

    Thanks
    MDeevi.

  • Anonymous
    August 01, 2005
    They are located in the .Net SDK documentation under .Net Framework SDK / Samples and QuickStarts / Samples / Technology Samples / Windows Forms Controls Samples.

    Binding to Client Settings Sample
    Demonstrates how to bind to application settings to reflect user changes.

    Client Settings Web Service Client Sample
    Shows how to use a Web service client to change application settings.

    RegistrySettingsProvider Sample
    Demonstrates how to persist application settings in the registry.

  • Anonymous
    August 01, 2005
    Thanks Prabhu, Got the path for samples and could able to write custom SettingsProvider class. But there is a problem we are getting an error saying that

    "Failed to load provider type: MyCustomSettingsProvider"

    I configured my settingsprovider in the following way in Settings.CS file as

    [SettingsProvider("MyCustomSettingsProvider", "MyCustomSettingsProvider")]
    class Settings : ApplicationSettingsBase
    {
    . . . . . .
    . . . . . .
    }
    Please try to help me out how to get rid of this error.

    Thanks
    MDeevi.

  • Anonymous
    August 01, 2005
    You need to provide an assembly qualified type name to the attribute, something like:

    [SettingsProvider("MyCustomSettingsProvider, MyAssembly, Version=1.0.0.0...")]
    (replace ... with full assembly information)

    Alternately, it is easier to use the other overload that takes a type:
    [SettingsProvider(typeof(MyCustomSettingsProvider)]

  • Anonymous
    August 01, 2005
    Thanks Prabhu for your quick response. Its working fine when I changed that to

    [SettingsProvider("MyCustomSettingsProvider.CustomSettingsProvider", "MyCustomSettingsProvider")]

    and also working if I had given it as

    [SettingsProvider(typeof(CustomSettingsProvider))]

    Thanks for your help. Now I want to use SQL Server 2005 Express to store my settings using the custom SettingsProvider. Can you give me some suggestions how to do that...

    Thanks
    MDeevi.

  • Anonymous
    August 04, 2005
    Here's a scenario I can't figure out how to address. I have a service that is currently using the new .NET 2.0 settings. These settings have application scope. What I want to be able to do is to change them during the installation phase of the service. I'm not having any luck figuring out how to go about doing this though. Can a service even call Save() on the settings? Where would that persist to?

    I can set the value of an application scoped setting by doing:

    Properties.Settings.Default["SettingName"] = "Blah"

    Upon calling Properties.Settings.Default.Save() though, the value disappears. Any suggestions?

  • Anonymous
    August 09, 2005
    Application scoped settings are read-only and cannot be saved at runtime. See the FAQ linked above for more details.

  • Anonymous
    August 09, 2005
    Can the path returned by Application.LocalUserAppDataPath and the path used by LocalFileSettingsProvider be the same? I need to store additional files, and it would make supporting the application alot easier if they could reside in the same directory (<AppPath>My Company<exe> versus <AppPath>My_Company<exe>_<signatures>).

  • Anonymous
    August 10, 2005
    Blair: Unfortunately not. As I have explained in the FAQ linked above, the user.config file path needs to meet certain isolation and robustness requirements that are not met by Application.LocalUserAppDataPath. The latter cannot be changed due to compatibility reasons.

    However, if your app is Clickonce deployed, both will be redirected to the Clickonce data directory and the only difference will be that the config file path will have a version dir.

  • Anonymous
    August 11, 2005
    Could there be a way to get the path that the LocalFileSettingsProvider uses? For example, Properties.Settings.ApplicationPath and Properties.Settings.UserPath?

    It really doesn't matter to me what the directory is. It just would be nice to put everything in same place.

  • Anonymous
    August 11, 2005
    Here is how you can get the config file path.

    First get the Configuration object for the desired level:

    Configuration c = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);

    Now you can access the FilePath property off the Configuration object.

    Note that you need to add a reference to System.Configuration.dll.

  • Anonymous
    August 12, 2005
    Hey, that's great! You should put that into your FAQ.

  • Anonymous
    August 13, 2005
    Good idea - added it to the FAQ.

  • Anonymous
    August 15, 2005
    I created a custom Settings Provider and now I do not want to use the app.config file for the settings. Does it arises any issues if I am not going to use app.config file? Does app.config take priority over the settings class for assigning defaults?

    Is there any mechanism in Visual Studio 2005 that we can tell the settings designer to generate the class but not the app.config values?

    Please let me know about these details....

  • Anonymous
    August 16, 2005
    If you aren't using the default provider, then the app.config file plays no part and is not required.

    I don't know a way to tell the settings designer to not put values in it. However, you could probably just get rid of the app.config before deploying the app.

  • Anonymous
    August 16, 2005
    The comment has been removed

  • Anonymous
    August 17, 2005
    The user config files are per app domain, so it doesn't matter which assembly accesses them, provided it is in the same app domain. So as long as the settings classes have unique full names, you don't have to worry about it.

    Another approach you might find useful here is IPersistComponentSettings. See the docs for more information about this. You will find some info in the comments section of the FAQ as well.

  • Anonymous
    August 18, 2005
    How do we access the GroupName information from GetPropertyValues and SetPropertyValues in the custom SettingsProvider?

  • Anonymous
    August 18, 2005
    You can access it off the SettingsContext: context["GroupName"].

  • Anonymous
    August 21, 2005
    Hi Prabhu,

    We have implemented a simple SqlCustomSettingsProvider based on the Registry example provided in MSDN Samples.

    We have many settings and want to group them. In fact, we want to group them hierarchically, but that is outside the scope of the group name issue.

    We noticed that using multiple settings classes is a logical way to group settings. However, we would like to use a single settings provider for all settings classes. The settings architecture documentation (ApplicationSettingsBase class) states that "each class defines a settings group" and that "if the group name is not explicitly set by decorating the wrapper class with a SettingsGroupNameAttribute, then a name is automatically generated".

    Our design requires us to store the groupname in the settings database. This allows 2 different settings groups to each have a setting with the same name.

    How do we access the GroupName information from GetPropertyValues and SetPropertyValues in the custom SettingsProvider?

    Please kindly provide us some solution so that we can continue the rest of the things.....

  • Anonymous
    August 21, 2005
    My comment above has the answer (repeating here):

    You can access it off the SettingsContext: context["GroupName"].

  • Anonymous
    August 21, 2005
    Thanks Prabhu, We will look into the solution provided by you. If we face any problem we will get back to you.

    Thanks in advance....

  • Anonymous
    October 05, 2005
    I have a big issue with client settings I would appreciate if you could comment on. When using strong names, the expected behavior of ApplicationSettingsBase.Upgrade() is thrown out the window if your version changes because an entirely new directory is created one level above the directory where side-by-side versions are contained, which apparently is the only place the default implementation of Upgrade() looks... Was this considered during the design and is it intentional? What is the recommended work-around? I am considering writing my own provider, because my assembly must be strong-named and I absolutely require upgrading settings with each release.

  • Anonymous
    October 06, 2005
    TheMask: Yes, this was a bug in Beta 2 and has been fixed recently. You should see the fix in the RC and final releases of .NET 2.0.

  • Anonymous
    October 06, 2005
    Unless I'm missin' something, it didn't make it into RC1, did it? I recently tested it and the problem was still there unfortunately. Guess I have to wait until release...

    By the way, thanks for the quick response!

  • Anonymous
    October 06, 2005
    You are right - I just checked and found that the fix missed the RC release by 3 days. Sorry for the confusion.

  • Anonymous
    October 17, 2005
    I would like to have settings which are scoped which can be written by one user and and read by all users.

    The UserScopedSettingsGroup doesn't work because the same user.config isn't read equally by all users. The ApplicationScopedSettingsGroup doesn't work because it is read only.

    I realize I can create my own SettingsProvider but then I seem to lose the .config file location, grouping, heirarchy, and general structure provided by the LocalFileSettingsProvide.

    Do you have any recommendations?

    j

    P.S. I also can't find the samples you mention in the faq on the Visual Studio RC1.
    i.e. / .Net Framework SDK / Samples and QuickStarts / Samples / Technology Samples / Windows Forms Controls Samples

  • Anonymous
    October 17, 2005
    John: This scenario is not supported by the built in provider, so unfortunately, I would have to recommend building your own. However, this is a fairly simple task once you figure out where and how you want to store the settings. Stuff like serialization is taken care of for you by the settings API.

    Here is the online link to the SettingsProvider samples:

    http://msdn2.microsoft.com/en-us/library/ya940ct3(en-us,VS.80).aspx

    Check out 'Client Settings Web Services Sample' and 'RegistrySettingsProvider Sample'.

  • Anonymous
    December 05, 2005
    We have an application that dynamically loads DLLs using reflection. This is essentially a plug-in architecture - it looks for DLLs in a particular directory that implement a particular interface and loads them.

    The question is this: Some DLLs need to have their own configuration data. With Visual Studio 2005, we're allowed to create the settings information for the DLL project, and all of the constituent files are created (app.config, settings.*). However, when the DLLs try to access data using Properties.Settings.Default, the settings are not loaded from dllname.dll.config. How can we cause each DLL's .config file to be loaded (and the Settings.Designer.cs properties to be loaded as a result)?

  • Anonymous
    December 05, 2005
    Config files are supported only for applications (exe), not libraries (dll). As such, dlls need to store their config in the host app's config files. This should happen automatically for you - any settings you write at runtime will get written to the host application's config files. As for default settings, you can either put them in the exe.config of your application, or simply supply them in code by specifying a DefaultSettingValueAttribute (which VS 2005 will do by default).

  • Anonymous
    February 19, 2006
    Hi;

    We have a case where the dll is a Word Add-In and for securtiy reasons some of our customers will not allow any changes to winword.exe.config. They also will not allow any files to be placed in the Office subdirectories.

    So we need to place config information with our dll (which is in a different directory). How can we set things so our dll can read from autotag.dll.config?

    Again, this is a security limitation from some of our customers, we cannot use winword.exe.config.

    thanks - dave

  • Anonymous
    February 20, 2006
    The configuration system does not support config files for dlls, only exes. So to do something like this, you will need to implement a custom SettingsProvider. You can find samples/doc on how to do this on MSDN - it should be fairly easy.

  • Anonymous
    February 21, 2006
    I know that ConfigurationManager.GetSection uses the cached instance of objects inside the ConfigurationManager. I have two questions:

    1. Do the following two ways to access settings:
    string str = Settings.Default.testSetting;
    and
    Settings set = Settings.Default;
    string str = set.testSetting;
    also use cached instances and what's the difference between them?

    2. If I call a class that is inside my configuration class library that calls ConfigurationManager and returns ConfigurationSection instance to my application will there be caching for subsequent class calls in my application?

  • Anonymous
    February 21, 2006
    Hi blog

    I am trying to make an extension to my.settings as I want to save the application password encrypted.

    I am trying to acomplish this by making a partial class:

    Namespace My
     Partial Friend NotInheritable Class MySettings
       Inherits Global.System.Configuration.ApplicationSettingsBase
           Private Function EncryptString(ByVal strPlain As String) As String
             ...
           End Function
           Private Function DecryptString(ByVal strCrypt As String) As String
             ...
           End Function

           <Global.System.Configuration.UserScopedSettingAttribute(), _
            Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
            Global.System.Configuration.DefaultSettingValueAttribute("")> _
           Public Property frmLoginPassword() As String
               Get
                   Return Me.DecryptString(CType(Me("frmLoginPassword"), String))
               End Get
               Set(ByVal value As String)
                   Me("frmLoginPassword") = Me.EncryptString(value)
               End Set
           End Property
     End Class
    End Namespace

    This seems to be working, but every time I modify the Project Application Settings, the frmLoginPassword property is re-created in the original class hence giving a:
    'Public Property frmLoginPassword() As String' has multiple definitions with identical signatures.

    Am I misusing the whole settings concept or is there a workaround?

    Regards

  • Anonymous
    February 22, 2006
    TheXRay:
    1. Yes, they use cached values (both are equivalent). If you wish to force a refresh, you can call Reload().

    2. The config system does cache values, but you can call ConfigurationManager.RefreshSection() to force a read from the config file.

    Muleskinner:
    Yes, modifying designer generated code is not recommended, since it can get overwritten. Instead, you can either wrap this property in your own one or do the encryption/decryption by subscribing to one of the events in ApplicationSettingsBase.

    This is an unfortunate limitation of dealing with designer generated code!

  • Anonymous
    February 26, 2006
    > The configuration system does not support config files for dlls, only exes.

    Will they address this in the future. I think security restrictions will make this more common - especially for Add-Ins.

    thanks - dave

  • Anonymous
    February 26, 2006
    David: I don't know the answer to that, since I work in a different group now. You could request it through MSDN Product Feedback or maybe contact Brad Abrams through his blog (http://blogs.msdn.com/brada/), since I think his team owns this now.

  • Anonymous
    March 01, 2006
    I must admit even after reading the above, I'm still having trouble getting our data layer dll to use the main exe's configuration file for a connection string.


    The exe has a config file and an application setting for connection strings.

    The dll has an application setting for connections strings.  I have tried labelling this the same and different from the the main executable.

    I then alter the config file (the executables) in the test environment, and the application continues to fall over.  It is easily fixed by hardcoding a valid connection string in the dll's settings, but this isn't configurable.

    Help.

  • Anonymous
    March 02, 2006
    The name of a setting in the config file will be a concatination of the full class name and property name, something like MyApp.MySettings.ConnStringSetting. Since the namespace and class name of the dll's settings class are different from that of the main exe, you might be seeing a mismatch.

    Try using the SettingsGroupNameAttribute - it is designed to help in such scenarios. Look it up in MSDN for more info.

  • Anonymous
    April 28, 2006
    The comment has been removed

  • Anonymous
    April 29, 2006
    I recommend using fuslogvw (a tool that ships with the .NET SDK) to track down assembly load problems. Just start it up and set it to catch assembly load issues. Then run through your scenario. You should see an entry in fuslogvw corresponding to your load failure - it should have details on why the load failed.

  • Anonymous
    May 02, 2006
    Sorry for the delay -- I was busy on another project briefly, and then this took a while to figure out.  The problem seems to be: while "normal" assemblies referenced by the COM object are loaded in the LoadFrom context, the SettingsProvider was loading (or failing to load) in the Default context.  The upshot of this was (as I suspected) it was probing the calling App's directory, not the COM object's.  The Fusion Log viewer helped confirm that -- it's a good tool that I was unaware of.  Thanks very much for the pointer.

    The fix was to load the assembly in the AppDomain's AssemblyResolve event.:

    [VB] Return GetType(DBSettingsProvider).Assembly
    or
    [C#] Return typeof(DBSettingsProvider).Assembly


    Why, (you may ask) did my experiment of just moving the provider assembly to the calling app's directory not work?  I had an unrelated bug:  When initializing the provider, I was accessing Assembly.GetEntryAssembly().GetName().Name, but in the COM object, GetEntryAssembly() is Null/Nothing.

    So, thanks for the tip -- I could have gone around in circles for a long time looking at that.


  • Anonymous
    May 02, 2006
    No problem - glad to know you were able to resolve the issue!

  • Anonymous
    May 03, 2006
     Thanks again for the help.  While I'm picking your brain...

     I can't seem to find any way to set values in the Config parameter that gets passed to the SettingsProvider's Initialize method.  Are there attributes I'm missing, or some other method of adding Name/Value pairs to Config?

  • Anonymous
    May 08, 2006
    The config parameter is of type NameValueCollection (http://msdn2.microsoft.com/en-us/library/system.collections.specialized.namevaluecollection.aspx)

    You should just be able to use the Add method?

  • Anonymous
    May 08, 2006
    Yes, I'm familiar with the NameValueCollection type.

    The problem is that the Initialize method is called from somewhere within the CLR, so I don't have direct access to the collection.  I can't figure out how to let the CLR know what I want to put in that NameValueCollection  parameter when it calls Initialize on my SettingsProvider.

  • Anonymous
    May 08, 2006
    Ah, okay. Let me preface this reply by saying that its been ~6 months since I moved to a different team in Microsoft, so I am not as familiar with this stuff as I was before.

    IIRC, in the client app case (i.e., when your provider is used through ApplicationSettingsBase), the parameters to Initialize will both be always null, and don't mean anything.

    In the ASP.NET case, I think each provider is associated with a section in config that declares the provider. The config parameter passed to Initialize contains the values specified in this section.

    Make sense?

  • Anonymous
    May 10, 2006
    Got it.  So in the Windows Forms case, I'll need to get my initialization information from other (persistent) sources.  The application/consumer of the settings can't pass me anything.

    That's not great news, but better to know than to wonder.  Thanks for the Info.

  • Anonymous
    August 29, 2006
    I know you've stated before if you want to change where the user.config file is saved you have to write your own settings provider, but I like everything about LocalFileSettingsProvider except the "Evidence" stuff that it appends to the application name in the path to user.config. Is there anyway to extend LocalFileSettingsProvider and just override this on piece?

  • Anonymous
    August 30, 2006
    Doug: Unfortunately, no, there isn't a way to override the user.config path through the LocalFileSettingsProvider, since the path is constructed by the config system when the app domain loads. The LFSP doesn't itself control the path construction.

    Just curious though: why do you wish to override the Evidence part of the path?

  • Anonymous
    August 31, 2006
    The comment has been removed

  • Anonymous
    September 05, 2006
    The Evidence portion is appended to your path to prevent collision with other applications that might happen to have the same name (unlikely that both company name and app name will match, but not impossible - also, a security risk). Specifically, the isolation is provided at the app domain level.

    The evidence is pulled from the 'Evidence' object associated with the app domain. If your app is signed, then the evidence depends only on the key you use - if the signature changes, so will the evidence, otherwise no. If not signed, then the evidence is based on the path to your application.

    So basically, changing the assemblies loaded do not affect the evidence portion of your user.config path.

  • Anonymous
    September 05, 2006
    The comment has been removed

  • Anonymous
    September 05, 2006
    Yes, IIRC, that's correct. Please confirm experimentally though, since, as I have mentioned before, it's been nearly a year since I worked on this stuff, so don't take my word for it!

  • Anonymous
    September 07, 2006
    The comment has been removed

  • Anonymous
    September 07, 2006
    Hmm, that should work. Try a simple example with a fresh small application in VS 2005 and see if it works for you.

    Also, try running without the VS 2005 debugger attached - the debugger's hosting process can cause the signature evidence not to be picked up by the config system. If this is the case, you can disable the hosting process (it is one of the debugger options).

  • Anonymous
    September 08, 2006
    The comment has been removed

  • Anonymous
    September 08, 2006
    Ah yes, the app should be strong named - it is the strong name evidence that will be used to isolate your app's user.config path. AFAIK, you cannot get this to work without strong naming.

    What's your concern with strong naming?

  • Anonymous
    September 12, 2006
    The comment has been removed

  • Anonymous
    October 04, 2006
    Hi, I'm back. I'm trying to write a custom SettingsProvider and from looking at the examples (which aren't very complete by the way since they don't implement IApplicationSettingsProvider) when getting a value from storage, they are only setting the SettingsPropertyValue's SerializedValue and not the PropertyValue. When I do this, the SerializedValue is correct but the property is always returning the default value. Could you explain the interactions between the PropertyValue and SerializedValue and how they are used to determine the value of the property?Thanks.

  • Anonymous
    October 09, 2006
    IIRC, if you set the SerializedValue and query the PropertyValue, it will automatically deserialize it. If there is an error while deserializing, it will return the default value automatically. If you want to change this behavior to instead return exceptions when the deserialization fails, you could set the ThrowOnErrorDeserializing property on the SettingsProperty object to true.

  • Anonymous
    November 14, 2006
    Hello, I'm late to this chat (which has been really helpful) so I hope you're still there... I've created a custom ServiceProvider that reads/writes settings to a specific location used by a DLL.  This is working a charm when the DLL is initialised by a .Net application thread. The problem is that the DLL is also loaded in a COM thread.  In this case, the attribute [SettingsProvider(typeof(Csaaw.CsaawLogic.CsaawSettingsProvider))] is seemingly ignored (the SettingsProvider's constructor is not called). Also, if I interogate the Providers property of my Settings class (to get its Count) I receive the following exception: Failed to load provider type: Csaaw.CsaawLogic.CsaawSettingsProvider, CsaawLogic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null. I've been unable to figure out why my custom ServiceProvider would behave differently under COM whereas the LocalFileServiceProvider works fine. Any thoughts?

  • Anonymous
    November 15, 2006
    I've resolved the issue.  In case anyone else encounters a similar problem, the resolution was to install my DLL in the Global Assembly Cache (GAC). The problem was that when my COM application was using the DLL, the Deserialize(...) method would be looking for the DLL in the COM application's Path. Adding my DLL to the GAC made it visible to the Deserialize(...) method.

  • Anonymous
    November 15, 2006
    Rob: I was just composing a reply to your comment, when I saw that you resolved the problem. Cool :-) Note that in general you can use the tool called fuslogvw (available in the SDK) to debug assembly/type load failures of this kind.

  • Anonymous
    November 15, 2006
    Thanks for the tip and for hosting the discussion.  Without it I would've been pretty stuck! Rob

  • Anonymous
    June 18, 2009
    PingBack from http://outdoordecoration.info/story.php?id=1525