3

I need to make my CF app self-updating through the web service. I found one article on MSDN from 2003 that explains it quite well. However, I would like to talk practice here. Anyone really done it before or does everyone rely on third party solutions?

I have been specifically asked to do it this way, so if you know of any tips/caveats, any info is appreciated.

Thanks!

sarsnake
  • 26,667
  • 58
  • 180
  • 286

4 Answers4

2

This is relatively easy to do. Basically, your application calls a web service to compare its version with the version available on the server. If the server version is newer, your application downloads the new EXE as a byte[] array.

Next, because you can't delete or overwrite a running EXE file, your application renames its original EXE file to something like "MyApplication.old" (the OS allows this, fortunately). Your app then saves the downloaded byte[] array in the same folder as the original EXE file, and with the same original name (e.g. "MyApplication.exe"). You then display a message to the user (e.g. "new version detected, please restart") and close.

When the user restarts the app, it will be the new version they're starting. The new version deletes the old file ("MyApplication.old") and the update is complete.

Having an application update itself without requiring the user to restart is a huge pain in the butt (you have to kick off a separate process to do the updating, which means a separate updater application that cannot itself be auto-updated) and I've never been able to make it work 100% reliably. I've never had a customer complain about the required restart.

MusiGenesis
  • 74,184
  • 40
  • 190
  • 334
  • thanks for the answer, in my case it looks like i will have to do it self-updating. the reason for this is because our users are not very savvy and might not update the app and what will end up happening that we will have different versions everywhere - that will be a pain in the butt for sure. I would rather deal with it automatically in the early stages. – sarsnake Jun 08 '09 at 17:15
  • In my case,i can download the .cab file(cf installer) from server and it is an installer if we click that file,it will install that version on mobile device.I tried your answer,but it is not working.Is it feasible with compact framework.Please reply. – Royal Jul 19 '14 at 08:54
  • @Royal: yes, the approach is feasible with the compact framework - in fact, my version of this functioned on both Windows Mobile and regular Windows. You say you tried doing this - post your attempt as a question here on StackOverflow and point me to it, and I'll attempt to see what the problem is with your implementation. – MusiGenesis Jul 20 '14 at 15:49
2

I asked this same question a while back: How to Auto-Update Windows Mobile application

Basically you need two applications.

App1: Launches the actual application, but also checks for a CAB file (installer). If the cab file is there, it executes the CAB file.

App2: Actual application. It will call a web service, passing a version number to the service and retrieve a URL back if a new version exists (). Once downloaded, you can optionally install the cab file and shut down.

One potiencial issue: if you have files that one install puts on the file system, but can't overwrite (database file, log, etc), you will need two separate installs.

To install a cab: look up wceload.exe http://msdn.microsoft.com/en-us/library/bb158700.aspx

    private static bool LaunchInstaller(string cabFile)
    {
        // Info on WceLoad.exe
        //http://msdn.microsoft.com/en-us/library/bb158700.aspx
        const string installerExe = "\\windows\\wceload.exe";

        const string processOptions = ""; 
        try
        {
            ProcessStartInfo processInfo = new ProcessStartInfo();
            processInfo.FileName = installerExe;
            processInfo.Arguments = processOptions + " \"" + cabFile + "\"";

            var process = Process.Start(processInfo);
            if (process != null)
            {
                process.WaitForExit();
            }

            return InstallationSuccessCheck(cabFile);
        }
        catch (Exception e)
        {
            MessageBox.Show("Sorry, for some reason this installation failed.\n" + e.Message);
            Console.WriteLine(e);
            throw;
        }
    }

    private static bool InstallationSuccessCheck(string cabFile)
    {
        if (File.Exists(cabFile))
        {
            MessageBox.Show("Something in the install went wrong.  Please contact support.");

            return false;
        }
        return true;
    }

To get the version number: Assembly.GetExecutingAssembly().GetName().Version.ToString()

To download a cab:

        public void DownloadUpdatedVersion(string updateUrl)
    {
        var request = WebRequest.Create(updateUrl);
        request.Credentials = CredentialCache.DefaultCredentials;
        var response = request.GetResponse();

        try
        {
            var dataStream = response.GetResponseStream();
            string fileName = GetFileName();
            var fileStream = new FileStream(fileName, FileMode.CreateNew);

            ReadWriteStream(dataStream, fileStream);
        }
        finally
        {
            response.Close();
        }
    }
Community
  • 1
  • 1
Chris Brandsma
  • 11,666
  • 5
  • 47
  • 58
1

What exactly do you mean by "self-updating"? If you're referring to configuration or data, then webservices should work great. If you're talking about automatically downloading and installing a new version of itself, that's a different story.

Found this downloadable sample from Microsoft- looks like it should help.

Dave Swersky
  • 34,502
  • 9
  • 78
  • 118
  • I am referring to both actually. http://msdn.microsoft.com/en-us/library/aa446487.aspx this does both, but it's an old article and I was just wondering if anyone had practical experience with it. – sarsnake Feb 25 '09 at 18:31
0

If you want to use a third-party component, have a look at AppToDate developed by the guys at MoDaCo.

Tom van Enckevort
  • 4,170
  • 1
  • 25
  • 40