views:

62

answers:

3

Hi,

I am developping a C/GTK application. I will soon be releasing a new version, and I thought it would be useful to include some update mechanism to it so that the application will be able to update itself.

I really only need something simple; it is sufficient if it only worked on Windows, since on Linux the application is in the repo so users can update it easily.

So I wanted to ask, is there some easy and simple way to do this (like some small library), or would I have to implement it myself?

Thanks.

P.S.

I really want something very simple, for example, let's say the application would download a webpage from a server which would contain the latest version number. If the applications version number!=server version number, it would fetch a setup.exe, somehow check its authenticity and run it.

A: 

omaha is pretty cool, if you have the resources to set up the corresponding server side.

ephemient
I hate google's update approach. There's no reason for the update check to run more often than I use the program, running the updater on a schedule is just stupid.
Ben Voigt
From a quick look, it's way too complicated for what I need -- added a PS to question to clarify.
houbysoft
+2  A: 

This might not be a full answer to the question, but they're some things you might want to take into account if you're to implement it yourself:

For the "checking for update" part, without actually downloading it, you may download a text file from an online location, containing the latest version string (e.g. 1.24). This code snippet should do the job for the Windows version (although I have not tested it):

#include <wininet.h>

_Bool CheckForUpdate() {
    DWORD flags = 0; // Not really used. DWORD == unsigned long

    if (!InternetGetConnectedState(&flags, 0)) {
        // The user is not connected to the Internet. Finished?
    }

    // Open the connection (HINTERNET == void *):
    HINTERNET connection = InternetOpen("User Agent", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
    if (http == NULL) {
        // Error.
        ...
    }

    HINTERNET updateFile = InternetOpenUrl(connection, "URL", NULL, FLAGS, 0);
    if (updateFile == NULL) {
        // Something went wrong.
        ...
        InternetcloseHandle(connection); // Close the handle.
        ...
    }

    // Reached here, we have the connection up, reading the file:
    char latestVersion[10] = {0};
    DWORD bytesRead = 0;
    if (InternetReadFile(updateFile, latestVersion, sizeof(latestVersion), &bytesRead) == FALSE) {
        // Error.
        ...
        InternetCloseHandle(updateFile);
        InternetCloseHandle(connection);
        ...
    }

    // Internet stuff is finished, so the handles can be closed now:
    InternetCloseHandle(updateFile);
    InternetCloseHandle(connection);

    // Check if there's a new version available:
    if (strcmp(latestVersion, CURRENT_VERSION) > 0) {
        // An update is available.
        return 1;
    } else {
        // No new updates available.
        return 0;
    }
}

There are links to the docs on the Wininet functions I used in the end of the answer, where you can see what's each parameter for.

When calling InternetOpen() the user agent string may be your application name for example. I wrote INTERNET_OPEN_TYPE_DIRECT as it's the most common setup, no proxy configuration is specified.

In the InternetOpenUrl() call the second parameter should be the URL to the text file as a NULL terminated string. For the FLAGS parameter in that call check the online docs on the different ones you have (checkout the links at the bottom of the post). For example, a possible flags combination would be the following:

INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_AUTH | INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_NO_UI

The strcmp() call should work well with letters among the versions too, so following the above example "1.24c" should be a newer version than "1.24" or "1.24a".

In case you have several release paths (like beta versions for example) you may use several fields on the text file or have several files. This might be useful if you don't want to push unstable releases to all users but only the ones willing to use such builds.

If there's no error when reading the file you can also add a check to see if the HTTP status code was 200 (OK) using the HttpQueryInfo() function with the HTTP_QUERY_STATUS_CODE flag.

Anyway, all this is only to get acknowledged of new versions, you may just notify of that to your users via a message or use a similar scheme to download the new setup application. For the authentication phase you can add to the version file a checksum of the setup file and calculate it once the file is downloaded.

Links to the online documentation on the Wininet API:

Hope that helps.

Xandy
Thanks, this definitively helps, +1. Didn't choose the answer yet, but seeing as there doesn't seem to be a library that can do what I want, I'll probably end up implementing it myself in which case I'll accept this answer.
houbysoft