0

I am trying to write my own update source code to update my application from the web basically I use two INI files. One on the web and one on the client side. The client side holds the current version number and the url to the server side ini. The server side ini holds the newest version and the url to the new download.

Anyways, all seems to work great. The file downloads great, but I would like to know the how one goes about closing the current application to run the new downloaded file (installer)

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
JakeSays
  • 2,048
  • 8
  • 29
  • 43
  • 3
    ...What have you tried? it should be simple 2 lines of code, 1) execute update application, 2) terminate current application – Jerry Dodge Apr 11 '13 at 14:32
  • aside from ini i'd use standard format on server like http://en.wikipedia.org/wiki/Portable_Application_Description If you run on Windows NT you can just rename the currently runniong application and download new one, then run it and close current one. However a separate up[adter is better because replacing EXE in Program Files would require UAC elevation and Administrator grants. So, i think best approach would be having small version checker app like Notepad++ does. It would be started by your application, check for update, download it if found – Arioch 'The Apr 11 '13 at 14:48
  • and after downloading would ask main application to exit and let it do update. You can ask this by using broadcast `PostMessage` after `RegisterWindowsMessage` call. Or you can use readymade libraries like `CromisIPC` – Arioch 'The Apr 11 '13 at 14:50
  • http://torry.net/pages.php?id=56 – Arioch 'The Apr 11 '13 at 14:55
  • Jerry, that is what I did, I was wanting to make sure that was the appropriate way to do it – JakeSays Apr 11 '13 at 14:59
  • 2
    @Johnny then you should have told us that. – Jerry Dodge Apr 11 '13 at 15:40

2 Answers2

6

Why not simply run the updater and the immediately close the current application?

ShellExecute(nil, nil, PathToUpdater, nil, nil, SW_SHOWNORMAL);
Application.Terminate; // Or some other way

Surely the updater doesn't mind that the original process lives a few milliseconds into its lifetime?

Andreas Rejbrand
  • 105,602
  • 8
  • 282
  • 384
  • 1
    Also the updater may wait for the application to terminate ;) – iPath ツ Apr 11 '13 at 14:41
  • @iPath: Certainly. A good updater should make a few attempts (with brief pauses in between) if something fails. – Andreas Rejbrand Apr 11 '13 at 14:42
  • 4
    @AndreasRejbrand Better to pass PID to the updater and let it wait until main program is signaled. – David Heffernan Apr 11 '13 at 14:52
  • I'm for IPC. Updater should download update package an *ASK* main app for termination. Then the application would *ASK* user if it can update now (like NotePad++, Azureus and any sane app do), and if user confirms - it will send its `ProcessID` to updater (using `RegisterWindowsMessage` + `PostMessage`, or using `CromisIPC` or whatever) then updater would `WaitForSingleObject` and finally do update and re-launch. As a user i would be very mad if application would be closed and updated at some random moment without asking my confirmation. – Arioch 'The Apr 11 '13 at 14:53
  • @David: Good idea. One just has to replace one of the `nil`s above. – Andreas Rejbrand Apr 11 '13 at 14:55
4

The normal procedure is like this:

  1. The main program detects that an update is ready.
  2. The main program silently downloads the update to a temporary location. The download is performed in a background thread.
  3. When the download is complete and verified, the main program restarts.
  4. Whenever the program starts and notices that there is a new update waiting to be installed it terminates and runs a separate executable that performs the update.
  5. When the update is complete, the program is restarted again.

The main benefit of this is that the user is not compelled to wait for the download to occur. A process which may take time and may fail. Thus giving the user as little downtime as possible.

There is a tricky scenario to handle. That's when the program starts the updater and then shuts itself down. If the main process doesn't close before the update opens the executable, then the updater can fail. The most elegant way to handle this is for the main program to pass its PID to the updater. The updater can then open a handle to that process and wait until it is signaled.

An alternative approach, quite similar, goes like this:

  1. The main program detects that an update is ready and fires off a separate executable to perform the update. Or, the main program periodically fires off the updater to check whether or not there is an update available.
  2. The update process silently downloads the update to a temporary location.
  3. When the download is complete and verified, the updater signals the main process to terminate.
  4. Once the main process has terminated (the updater waits for it to do so), the updater performs the update.
  5. When the update is complete, the main program is restarted.

To be honest, the second approach seems more attractive to me. It has a much better separation of concerns. The main program is concerned with its business. The updater is concerned with its job. Obviously there has to be interaction and cooperation between them, but this is kept to a bare minimum.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • i'm for separate checker/upgrader like in Notepad++ For a simple reason - it would not be replaced by upgrade and would not raise alerts of firewalls and antiviruses – Arioch 'The Apr 11 '13 at 14:57
  • @Arioch'The That's a very sound approach. Write it up as an answer. – David Heffernan Apr 11 '13 at 14:59
  • That is just a nuance. And it is still not truly robust, for example what should we do if the EXE is run in several instances, like on terminal server or network share ? half of users agreed to close and update while another half declined? This basically just cannot be resolved without turning updater into a separate launcher application, that would select an actual EXE to run. And there it goes on and one... – Arioch 'The Apr 11 '13 at 15:31
  • 1
    @Arioch'The Yes, if you consider all update scenarios you can enter an enormous world of pain. Just imagine the fun involved in servicing something like Windows in all its flavours, through Windows Update et al! – David Heffernan Apr 11 '13 at 15:36