To work with the application config file, I use the Configuration API: I declare my Section-class, add a description to app.config.

In doing so, I use the following configuration level:

ConfigurationUserLevel.PerUserRoamingAndLocal 

So, I store the config file in

 Local Settings\Application Data\"Company"\"Application"\version\ 

The problem is that when a version is changed, the place of the config file is changed and read using standard means of the Configuration API (OpenExeConfiguration).

In the Settings API there is a possibility for

 class MyUserSettings : ApplicationSettingsBase 

call the Upgrade() method, which allows you to read the settings from the old version of the application. I understand that this opportunity provides a LocalFileSettingsProvider .

The question is: is it possible by means of the Configuration API load the settings of the previous version of the application? If this is not possible, how to embed your section in the Settings API
( MyUserSettings : ApplicationSettingsBase )?

    2 answers 2

    Unfortunately, at the moment I came to the conclusion that it is impossible to implement automatic reading.

    The idea was based on the fact that the catalog

      Local Settings\Application Data\"Company"\"Application"\ 

    compare all versions with the current one, open the config file of the previous version and overwrite it as new. This algorithm should be executed once when the application is first launched. The code looks like this:

      if (Properties.Settings.Default.CallUpgrade) { Assembly assem = Assembly.GetExecutingAssembly(); AssemblyName assemName = assem.GetName(); Version curver = assemName.Version; DirectoryInfo dir = Directory.GetParent(Application.LocalUserAppDataPath); DirectoryInfo[] dirs = dir.GetDirectories(); if (dirs.Length < 1) return; Version[] vrs = new Version[dirs.Length]; for (int i = 0; i < dirs.Length; i++) vrs[i] = new Version(dirs[i].Name); Array.Sort(vrs); if (vrs[vrs.Length - 1] < curver) { ExeConfigurationFileMap file = new ExeConfigurationFileMap(); file.LocalUserConfigFilename = dir.FullName + "\\" + vrs[vrs.Length - 1].ToString() + "\\user.config"; file.ExeConfigFilename = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath; file.RoamingUserConfigFilename = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoaming).FilePath; ConfigurationManager.OpenMappedExeConfiguration(file, ConfigurationUserLevel.PerUserRoamingAndLocal).SaveAs( dir.ToString() + "\\" + curver.ToString() + "\\user.config"); Properties.Settings.Default.CallUpgrade = false; Properties.Settings.Default.Save(); } } 

    The algorithm could not be debugged due to the fact that configs ( user.config ) actually do not lie directly in the Application.LocalUserAppDataPath directory, as Microsoft claims, but along certain surrogate paths, for example:

     Local Settings\Application Data\"Company"\"Application"_Url_npzl40sahdaapou10uiyprujpbidwoao\version\ 

    and for each copy of the exe-shnik there is a creation of a new similar directory. And this is not saying that when debugging the config is saved in the directory

     Local Settings\Application Data\"Company"\"Application"vhost.exe\version\ 

    In general, I feel that users will have to worry about the security of their config themselves. The benefit of maintaining the settings in a separate file is provided by the development.

      I had a similar problem and I solved it like this. I got a string property whose default value is an empty string. When I started the program, I filled this property with some random value. But before that I checked if it was empty, then I called Upgrade to extract its value from the previous version.

       Properties.Settings.Default.Reload(); if (String.IsNullOrEmpty(Properties.Settings.Default.local)) Properties.Settings.Default.Upgrade(); if (String.IsNullOrEmpty(ProjectsProfiler.Properties.Settings.Default.local)) { Properties.Settings.Default.local = GetRandomString(); Properties.Settings.Default.Save(); } 

      As a result, when launching a new version, all settings safely migrate from the config of the previous version.

      • If you carefully read my message and read the code in my answer, you can see: 1) I also use the variable approximately, but it is not of the string type (the horror is GetRandomString :), but of the bool type. 2) I use not the Settings API, but the Configuration API, I myself lead configuration sections and handler classes. For them, the Properties.Settings.Default.Upgrade method does not work. But in principle, I have already abandoned the Configuration API in favor of my own saving via XML serialize, because. with standard APIs it is very difficult to save an object of the collection type: you have to do your typecoverter - time costs will not be worth it - XeoN
      • >> only it is not of type string (horror is GetRandomString :), but of type bool GetRandomString is a collective name, the original function is called differently. The constructed string is not only used to mark the fact of launch, it plays the role of the installation identifier. - ganouver