1

I'm developing a software in .NET 4.0, which reads and writes application settings. On finish the software will be stored on a file server. No local instances will be executed.

By default the user settings XML file is stored in every users AppData\... directory, but I want to change the file location to the same directory the executable is stored.

This means, that all users should use the same XML user-settings file with modified contents.

I've read this question and answeres where a user describes how to realize that in JSON format.

Question: Isn't there any other (simple) way to tell the Settings class, where to read from and write to user settings?

The following has been discussed:

  • Users will always have enough access rights to modify the settings file.
  • Modifications on settings should be picked up by other users.
  • Users will start the application from different network computers.
  • I could implement my own XML file handled by the application (I'll keep this in mind).
Community
  • 1
  • 1
Christian St.
  • 1,751
  • 2
  • 22
  • 41
  • 2
    Why do you want to write these to the exe path? You cant always guarantee write permissions on that path. – Botonomous Sep 26 '13 at 13:36
  • @Dunbar Because all users must have the same settings. Assume the users working with the software always have the needed access rights. – Christian St. Sep 26 '13 at 13:45
  • 1
    @ChristianSt. "*Because all users must have the same settings*" - then they are no longer user settings because they aren't user specific, I'd class them as *application* settings. Those can be stored directly in the `app.config`. – James Sep 26 '13 at 14:02
  • 1
    @James They shouldn't be used as user specific settings, because settings modified by user 1 must be used by user 2. If I change the scope to application settings, they're read-only. – Christian St. Sep 26 '13 at 14:14
  • Let's break it down. You have *user-specific* settings that you want to ship with your app. If 3 users are using the same app on the same machine and 1 of those users make a change to the setting you want those to be picked up by the other users...correct? – James Sep 26 '13 at 14:28
  • @James The 3 users will execute the application from 3 different computers on the network: (_"On finish the software will be stored on a file server"_). And yes, the settings file on the network folder should be updated. Sorry, if my question wasn't clear enough... – Christian St. Sep 26 '13 at 14:38
  • @ChristianSt. So that clarifies my previous point, these settings aren't really *user-specific* because they are shared across *all* users. So why not just store them in the `app.config`? – James Sep 26 '13 at 14:43
  • @James The `app.config` file is filled with the default contents I defined with the "settings wizard" in Visual Studio. If there's no other file called app.config I don't know what you mean. – Christian St. Sep 26 '13 at 14:54
  • you should use a custom xml file that is managed by your application (locking file for writes, notifying when changed etc). Not the build-in Settings class. – Daanvl Sep 26 '13 at 15:07
  • @Daanvl I'll keep this in mind, thanks. BUT: Do you know if my intention is even possible? And if so, please give me some hints to realize that. – Christian St. Sep 26 '13 at 15:20
  • Please notice, that I extended my question with this discussion. – Christian St. Sep 26 '13 at 15:52

2 Answers2

2

I'm not sure if you can get the functionality that you want with the standard Settings class. But I do think that the end result your searching for can be accomplished.

If you want changes in settings user 1 makes to be instantly enforced for user 2, you should look at storing the settings in a database. Your application can then be periodically check this table for changes. For instance if user 1 changes the color of a control, then every time user 2 loads a screen with that control you check the database for the color.

Or, if you want the settings to be applied on start-up of you application. Use a datacontract + xml serializer to write settings to a file of your choosing on a network accessible path/folder. Then make sure you can handle read/write locking of this file.

These are just general ideas that I think you should consider. I dont claim these are your only options though. If you whish to pursue any of these things there are a bunch of blogs and stackoverflow pages with all the information you need.

good luck!

Daanvl
  • 608
  • 1
  • 9
  • 24
  • Make note that the user must have write permissions wherever this XML file is saved! (For desktop applications this would be `Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)` as non elevated users can not write to `Program Files`, but the OP said in a comment this is a network app so be sure the network path has write permissions) – Scott Chamberlain Sep 27 '13 at 17:31
  • I've voted up your answer, because your ideas are useful workarounds! If you are interested, look at my answer, how I realized my problem. – Christian St. Oct 09 '13 at 14:50
2

I added a custom Application Configuration File called AppSettings.config to my project and set its Copy to output property to Copy if newer (this copies the config file into the executables folder on building the project.

My settings must be classified as appSettings, not applicationSettings (non-editable) or userSettings (stored in the users AppData folder). Here's an example:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <!-- single values -->
    <add key="Name" value="Chris" />
    <add key="Age" value="25" />

    <!-- lists, semi-colon separated-->
    <add key="Hobbies" value="Football;Volleyball;Wakeboarding" />
  </appSettings>
</configuration>

Look at the code below, how to access and modify them:

Configuration AppConfiguration =
    ConfigurationManager.OpenMappedExeConfiguration(
        new ExeConfigurationFileMap {ExeConfigFilename = "AppSettings.config"}, ConfigurationUserLevel.None);

var settings = AppConfiguration.AppSettings.Settings;
// access
var name = settings["Name"].Value;
var age = settings["Age"].Value;
var hobbies = settings["Hobbies"].Value.Split(new[]{';'});
// modify
settings["Age"].Value = "50";
// store (writes the physical file)
AppConfiguration.Save(ConfigurationSaveMode.Modified);

I used the built-in app.config for default application settings and wanted to separate them from the editable global settings in AppSettings.config. That's why I use a custom config file.


That's not directly an answer to the question, but it solves the problem on how to store and share editable application settings in custom configuration files.

Hope it helps any other users! :-)

Christian St.
  • 1,751
  • 2
  • 22
  • 41