views:

484

answers:

4

Hi guys/gals, 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!

+1  A: 

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
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.
gnomixa
+1  A: 

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
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.
gnomixa
+2  A: 

I asked this same question a while back: http://stackoverflow.com/questions/753851/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();
        }
    }
Chris Brandsma
A: 

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

tomlog

related questions