How do I retain My.Settings values through a software upgrade

robertb_NZ

Well-known member
Joined
May 11, 2010
Messages
146
Location
Auckland, New Zealand
Programming Experience
10+
My VB.NET software is delivered through ClickOnce. When users download a new version their settings are lost and they have to reconfigure it, but I want their settings to be retained as far as possible. How do I achieve this?

I thought that I'd fixed this problem. I found this paper
Client Settings FAQ

This said that the answer was to use the Upgrade function. Of course you only want to call this function the first time that the new version is run, so you define a setting "CallUpgrade" and put code like this in your application's startup code: -
C#:
   if (Properties.Settings.Value.CallUpgrade) {
      Properties.Settings.Value.Upgrade();
      Properties.Settings.Value.CallUpgrade = false;
   }

I defined a setting CallUpgrade (Type Boolean, Scope User, Value True), and wrote this code at the beginning of Startup_Load. Startup is the start form of my Windows Form application, it's only function is to wrap the real code in a Try/Catch so that I can get diagnostics when there's a problem.
VB.NET:
    Private Sub Startup_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Try
            If My.Settings.CallUpgrade Then  '15.5:Settings
                My.Settings.Upgrade()
                My.Settings.CallUpgrade = False
            End If
            ...
I thought that this had fixed the problem, but a user reports that they still have to reset their configuration to the previous values. All My.Settings values have scope User, none are Application. So what have I got wrong?
 
Here's a quote from the page you linked to:
In Clickonce, when you install a new version of your application, ApplicationSettingsBase will detect it and automatically upgrade settings for you at the point settings are loaded. In non-Clickonce cases, there is no automatic upgrade - you have to call Upgrade yourself.
Here's a quote from your post:
My VB.NET software is delivered through ClickOnce.
Based on that, why are you writing any code to do this at all?
 
You should be saving user configurations in the application data folder, in a new subfolder under your companies name and then when your application upgrades, it won't be overwriting your my settings config. When your application updates, you tell it where to find the previous configuration and load in the values from the config file you stored in your application data folder, to your upgraded application config file. This is how I used to do it, although there is another recommendation by Microsoft here ApplicationSettingsBase.Upgrade Method (System.Configuration)
 
Two more pieces of info for you ClickOnce and Application Settings - Visual Studio
And also read over this blog which I found amusing but helpful nonetheless Where do I put my data to keep it safe from ClickOnce updates?
He goes over the exact same process I was recommending and I think you will find it useful. If you want to get around the last recommendation I made regarding leaving residual files on the computer even after uninstall (Ie your settings file) being stored in the app_data folder. You would need to build a custom installer and add the directory that I mentioned above as an attribute to delete when your application is ever to be uninstalled. Otherwise those files will never be removed.
 
In Clickonce, when you install a new version of your application, ApplicationSettingsBase will detect it and automatically upgrade settings for you at the point settings are loaded.
It's not that straight forward as made out John. When the upgrade commences, it will use a new version of the application from within a new folder version created by the updater, and that settings file will not retain the values. It's been many years since I used clickonce for anything, so I am only going on what memory serves. But if memory serves me correct, the OP will need to follow the steps I outlined on #4.
 
I have defined My.Settings names either from the Settings tab of the project, or when defining the dataBindings property of a control. Either way it ends up in the list shown in the Settings tab, and also I see that it appears in <userSettings><Jazz.My.MySettings>... </Jazz.My.MySettings></userSettings> within app.config.

Is this relevant to this issue?
 
No its not particularly relevant. But if you stop looking at your application and read everything I gave you. I expect tomorrow you will be saying thank you, and it's all working as intended now. The only thing you should be concerned with re your settings is that your MySettings are configured for user-scope.
 
I've read through the references (including lower levels). Using RobinDotNet's VB code it is easy to create an appropriate folder in LocalApplicationData with
VB.NET:
            Dim localAppData As String = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
            Dim userFilePath As String = Path.Combine(localAppData, "MANASYSJazz")
            If (Not Directory.Exists(userFilePath)) Then
                Directory.CreateDirectory(userFilePath)
            End If
His example then continues creating a file in this folder "My File.txt". Obviously this is just an example, and implies manual saving of the settings. But for me, My.Settings is perfect for what I want as long as it persists through an update. What I think I want to do is to create a file here "user.config", and then have my application use this. How do I achieve this? I really don't want to consider creating custom logic to do what My.Settings is already doing perfectly and very simply except for one problem.
 
Actually, I think we're barking up the wrong tree. Because of this problem I'm learning more about how it's all working: I've just found that all along my application HAS been creating files in Appdata\Local. There is a folder
C:\Users\Robertbw10\AppData\Local\Jazz_Software_Ltd,_New_Ze
which contains a subfolder
\Jazz.exe_Url_gvqgj4gis3ay0k0ofauvdaylzusjgro5
which contains a series of subfolders
\3.15.5.214
\3.15.5.215
etc
Each of these folders contains a single file, user.config.
3.15.5.214 is the currently-released build of my application, 3.15.5.215 is the version I'm currently working on with Visual Basic.

So everything is almost OK. All I need is code to update the latest version from the previous one. Or to drop a level of folder - why do we need separate \3.15.5.214, 215 folders - it's the same application?
 
Last edited:
Back
Top