0

We have a ClickOnce deployed application. We would like make sure that the installations only update 1 version jump eacn time. (Other best practice solutions are welcome as well).

Say for example a user has version 1.16 installed, in the mean time there has been 2 new releases so the version on the server is now 1.18. We would like to ensure that the next time the application updates, it updates first from 1.16 to 1.17. Then the next time it updates, it updates from 1.17 to 1.18 etc. I.e. it does not update directly from 1.16 to 1.18.

Why, you might ask. Well it relates to the fact that our application has a local (SQL EXPRESS) database. We have a custom update class which is invoked when the application starts up. It detects if a CO update has occured, if so it updates the local db with any schema changes that may have been made. I.e. the CO update first delivers the files necessary to perform the scehma changes, and then the custom update class performs the actual db modification. This is a problem when jumping more than 1 version since in this example the db changes script from v.16 to v.17 will never be applied.

Our first approach has been to daisy chain CO update folders. That is v.16 updates from 1.17, 1.17 updates from 1.18, but this does not seem to solve the problem.

Any ideas?

sreddy
  • 200
  • 2
  • 9

2 Answers2

1

I am pasting a method I use to find the version of the program if it is launched from the desktop and the version of the update if it is launched from ClickOnce.

    private string GetTheVersion()
    {
        string version = string.Empty;
        Version currentVersion;
        Version updateVersion;
        StringBuilder sb = new StringBuilder();
        if (ApplicationDeployment.IsNetworkDeployed)
        {
                currentVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion;
            updateVersion = ApplicationDeployment.CurrentDeployment.UpdatedVersion;

            sb.AppendLine(string.Format("Current Version: {0}.{1}.{2}.{3}", currentVersion.Major.ToString(), currentVersion.Minor.ToString(), currentVersion.MajorRevision.ToString(), currentVersion.MinorRevision.ToString()));
            sb.AppendLine(string.Format("Updated Version: {0}.{1}.{2}.{3}", updateVersion.Major.ToString(), updateVersion.Minor.ToString(), updateVersion.MajorRevision.ToString(), updateVersion.MinorRevision.ToString()));
            version = sb.ToString();
        }
        else
        {
            currentVersion = Assembly.GetCallingAssembly().GetName().Version;
            version = string.Format("Current Version: {0}.{1}.{2}.{3}", currentVersion.Major.ToString(), currentVersion.Minor.ToString(), currentVersion.MajorRevision.ToString(), currentVersion.MinorRevision.ToString());
        }

        return version;
    }

There is more there than you need, of course, but you can then use the methods of the ApplicationDeployment.CurrentDeployment class to determine whether or not to perform the update. You could pass the minimum version you want the existing app to be in a command line argument or url querystring variable, depending on how you are deploying.

Joey

Joseph Morgan
  • 163
  • 1
  • 9
1

I have a robust ClickOnce application that also makes use of SQL Server Express on the end user's PC. In our case, syncing of the local database schema is managed on our web server.

After the application starts, version information is pulled from the current client database (with a version of "0" being returned if the DB doesn't exist) and then a web service returns the necessary script files to build the local database. The ClickOnce application then executes the scripts in sequential order and the database schema is built, perfectly, regardless of when the last time was that the user launched the application.

After the local schema has been updated, any data that the user needs to access is re-synced from the server. This is because each time I update a data table, I have to DROP the table and then recreate them from within my schema update scripts.

If you would rather not manage this type of complex server/client script/db management system, why can't you bundle the associated SQL scripts with your application? You could accomplish this by defining a table within your client DB that maintains the current DB version. When your user downloads a new update to your application, check the version of the DB and, depending on the client's current DB version, execute the available scripts or commands that you've compiled with your application.

Only add scripts to each subsequent publication of your application and never remove old ones. New SQL scripts should DROP and recreate any object that is being updated. This can save you quite a few headaches if your application happens to crash in the middle of a script being executed by your application. I've learned this the hard way.

I would recommend creating a syncing mechanism where version checks are managed from your server, instead of having scripts or having embedded SQL commands compiled with your application. This way, minor changes to the database can be made without having to publish your application. Trust me, your user's will thank you because they won't have to download frequent application updates. Instead, these types of changes will be seamless and will take place automatically behind-the-scenes.

RLH
  • 15,230
  • 22
  • 98
  • 182