Automatic Update

We have an application that needs autoupdate.  What needs to happen is that the application checks to see if its EXE is an old version.  If it is, it needs to start a second application WHICH WILL WAIT FOR THE **FIRST** APPLICATION TO CLOSE before it can copy the new EXE over the old one.  The SECOND application then restarts the FIRST application (which is now updated).

BTW solution must work for all 32-bit versions of Windows (95, 98, NT.....)
Who is Participating?
Ten13Connect With a Mentor Commented:
KISS! (keep it simple stupid :o)

If I understand you correctly (and I belive I do ;-) I have done this myself without problems. It is tested on both Win95 and WinNT4.0.

OK! Ready? Here we go:

Application 1: (this is psoudo code off the top of my head. May not compile!)

// You might want to do this in your mainform (TForm1.FormCreate)
  if CheckVersionInfo then begin // is the version OK?
    // Yes! Continue as normal
    Application.CreateForm(TForm1, Form1);
  else begin
    // Nope! Run the second app and exit!
    // execute: "application2.exe /p:xxx"
    ShellExecute(0, nil, 'Application2.exe', '/p:$' + IntToHex(GetCurrentProcessId(), 8), nil, SW_SHOW);

Application 2: (this is tested and can compile!)

// TForm1 is the mainform.
procedure TForm1.FormCreate(Sender: TObject);
  bOK : boolean; // is the procces terminated
  nPID : integer; // the process we want to wait for
  hProc : THandle; // handle to the very same process
  dwResult : DWORD; // WaitForSingleObject result
  bOK:= false; // assume the process is running
  if Copy(ParamStr(1), 1, 3) = '/p:' then begin // is a PID passed as a commandline parameter?
    nPID:= StrToInt(Copy(ParamStr(1), 4, Length(ParamStr(1)))); // Get the PID from the commandline parameter
    hProc:= OpenProcess(PROCESS_ALL_ACCESS, FALSE, nPID); // get a handle of the process we want to wait for
    if hProc = 0 then begin // is it a valid handle?
      bOK:= true; // the process does not exist. It is terminated!
    else begin
      dwResult:= WaitForSingleObject(hProc, INFINITE); // wait for ever for the process to end
//      dwResult:= WaitForSingleObject(hProc, 5000); // return after 5 secs
//      if dwResult = WAIT_TIMEOUT then begin // we timed out. THe process is proberbly still running
//        ShowMessage('Timeout!');
//      end;
      if dwResult = WAIT_OBJECT_0 then begin // YES!!! The process terminated
        bOK:= true;
    CloseHandle(hProc); // remeber to clean up!

  if bOK then begin
    ShowMessage('Process is terminated!');

T-T-That's all folks! Nothing to it! I'll keep an eye out for any questions :o)

- Martin
I believe the newest version of Wise Installmaster has an autoupdate feature.

millerwAuthor Commented:
Not looking for an external product.
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

Use this function in both your applications. The "YourAppName" string has to be the same in both apps (it can be any unique string).
The first application does not care what the result is, it just registers itself.
The second application does not start copying if the function returns true.

function AppStarted(YourAppName: string): boolean;
millerwAuthor Commented:

A solution that doesn't require polling is preferred.  EG a notificiation that the process has closed or that the EXE file can now be written to.  Polling is a waste of processor time.
I think the answer lies in an ENUM_WINDOWS thing

use shellexecute or some like API call to start the 2nd program and then exit the first one

use EnumWindowsCallBack on a timer to determine when the first application ends, and then copy over the file and run it again.

here is a simple example of how to implement an EnumWindowsCallBack function:

function EnumWindowsCallBack(HWND: hwnd;LPARAM : lParam):boolean stdcall;
var capt:array[0..79] of char;
    ClassName:array[0..79] of char;
  GetWindowText(HWND, capt, 79); GetClassName(HWND,ClassName,79);
  if length(capt) > 0 then begin
   for i:=0 to prgfrm.fil.Items.Count-1 do begin
    if j=0 then j:=pos(uppercase(prgfrm.fil.items[i]),uppercase(capt));
    if j<>0  then begin prgfrm.rnapp.items.add(Capt); end;
   end; //for
  end;//if capt not ''}

if you think this will work but want a code example more to what you had in mind, you'll have to wait til I get home in a couple of hours
millerwAuthor Commented:
EnumWindows is a sort of waste of time due to the fact that I have the HWND already considering I'm calling the second app from the first.  

Bear with me a second as I explain what I **think** is and should be able to be done.

The first app should be able to **TELL** the second any information it needs in order to "track" because its job is going to be to track **THE** first app.

1.  First app realizes it is of old version.
2.  First app starts second app.
3.  First app informs second app of all information it needs to detect when first app is closed.
4.  Second app starts waiting for close of first app.
5.  First app then Terminates.

You should be able to get the rest.

I'm looking at the OpenProcess command, however SYNCHRONIZE *appears* to be only available on NT.  WaitForSingleObject with the process handle of the first app will wait infinitely for the first app to close before continuing execution in the second app.

Now, that is the theory of what I'm thinking.  Rip it apart if you please and tell me why it is not possible if it is not.  Otherwise, anyone want to venture to write the code to actually perform it?
How about you reverse the order you run the programs in.

First you run program 2 (which would then become one, but we'll forget that for a moment :-), which version-checks program 1. Use the date/time stamp or a datafile or whatever for this.
Program 2 then informs the user that program 1 is out of date, removes and updates it and _THEN_ executes it normally.
If the program needs not be updated, the user would notice nothing from this and by used a predefined parameter you can prevent the user from running program 1 manually. E.g. program 2 runs "program1.exe /runnow" or something like that.

millerwAuthor Commented:
Ah, but actually (think if it as originally planned) first app updates the second app before calling the second app to update the first app :-)
If i understand your problem correctly, then you want a way for the second app to decide whether first app has terminated. (You're ok with all other stuff; Inter-App message communication, ShellExec etc).

I guess this can be done by using the ExitCode, as follows:

//in your second app.
  Application.ProcessMessages; \\or sleep(for a while);
until (ExitCode <> STILL_ACTIVE);

//now go ahead and delete the first app, copy the upgrade
// and start it again.

where ProcessHandle is the handle of your First app.  Either your second app can find it, or your first app can tell it to your second app.  

If you don't like polling (above wouldn't consume too much of the resources, especially if you use a larger sleep interval), then you'll have to resort to ShellHooks I would guess; But that would be an overkill.
millerwAuthor Commented:
Well, the unfortunate thing is that I don't like polling.  But that doesn't mean I won't be forced to use it if all else fails......
Well, I understand your concerns about wasting resources. But the following code:

until (ExitCode <> STILL_ACTIVE);

will poll the system only once a second, and your first app will terminate within a few seconds.  So the consumed system resources will be pretty low.

On the other hand, you'll consume a lot more of the resources, if you go for hooking the system messages (via a SHELLHOOK).  I'd think that the above loop would be a lot better with respect to saving resources.
Hey, I think you should take a look at this.  I used this component in one of my apps, and it works so well.  I tried several other more expensive AutoUpgrader options and I had so many problems.

TAutoUpgrader by UtilMind.  It works so easily on the client and the Internet side.  It is also small, allowing you not to have a bulky file.

You can track progress of the file, let the user know if no update is available, etc.
My vote is with nrico...

Write a shell application that is actually the app that your user launches.  This application will get the version information of your "real" application and compare to the "current" version.  If they are the same, it simply launches the "real" app and kills itself.  Should add only a negligable(sp?) amount of time to the startup sequence.

If they are different, it will save the current version of your "real" app as a backup, then download the new version.  If necessary, it would then launch the patch program, new install program, or perhaps just run the new executable.

You can write the "shell app" so that it can take "directions" from the web - in other words, it should be able to handle a multitude of installation mechanisms, taking it's orders from some sort of a mini-script file.

Jim Kern
millerwAuthor Commented:
ahalya:  Agreed, except for the fact that a WaitForSingleObject call does an even better job since it is instantaneous upon process close and enters an efficient wait cycle.  But, your in top running so far if my current code doesn't work.  Stick around, I just might give you guys some free code.......if I'm in a good mood--hope that tomorrow I am ;-)

perkley:  One should never assume.  Who said I'm updating from the Web? :-)

JimboKern69:  How does the shell app then get updated if a change is made to it?  Sorry, but having a tech go around to x computers to update the system is a pain in the butt.  That and telling x busy users to run an updater is bound to get overlooked by someone.  Sorry, but that is the exact reason I didn't like nrico's solution.  Running a cost analysis of this situation results in comparing my time to fix the problem now and the time needed to update, let us say, 1000 user machines in the future.  Hands down, my time costs less.

Anyone here know anything about DuplicateHandle?

WaitForSingleObject is great. But, it requires a timeout value, if i remember right.  (Since its not easy to know the time an action requires in advance, I end up with specifying a "LARGE" timeout vale; say a minute).  Then the problem is that my code loses "resposiveness" & the user may feel as if the program has "locked up" -its only for the duration of the timeout, but still it ain't pretty. Is it ?

If I check the GetExitCode function, i can process all other messages, (application.processmessages) and the user interface would be pretty responsive.

I have never used DuplicateHandle. But have seen it at
millerwAuthor Commented:
WaitForSingleObject has the ability to wait for infinity.  Just use the constant INFINITE as the timeout value.

As for responsiveness, I'm not too worried due to the fact that the actual wait time is less than a second...the time it takes for app1 to finish--which will be an actual code call, not user choice.  However, if it ends up being a concern, a simple thread will fix the issue...the thread waits while the app is responsive (however, app2 should not allow the user to just close it if app1 is still running).  As for being pretty, why don't you look below and see.

I have found that the SDK is incorrect.  The SYNCHRONIZE works on every machine I've tested so far.  Each and every machine has at least IE4 installed and it appears to contain the update so that the command works.  95 and 98 both work.  Thus, I don't need DuplicateHandle.


Both applications have a message called SX_PROCESSINFO defined.  The message is used to transmit the actual ProcessID of the first app over to the second.

Here is the code for app1:

function EnumerateTW(AWnd: HWND; PID: LongWord): Boolean; StdCall;
  PostMessage(AWnd, SX_PROCESSINFO, PID, 0);
  Result := True;

procedure TForm1.FormShow(Sender: TObject);
  zAppName: String;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  FillChar(StartupInfo, Sizeof(StartupInfo), #0);
  StartupInfo.cb := Sizeof(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := SW_SHOWDEFAULT;
  zAppName := ExtractFilePath(Application.EXEName)+'AppTwo.Exe';
  CreateProcess(nil, PChar(zAppName), nil, nil, False, CREATE_NEW_CONSOLE or
    NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo);
  WaitForInputIdle(ProcessInfo.hProcess, INFINITE);
  EnumThreadWindows(ProcessInfo.dwThreadId, @EnumerateTW, GetCurrentProcessID);

The second app then accepts the message and runs the following code in its message handler:

procedure TForm1.SXProcessInfo(var Message: TMessage);
  PID: LongWord;
  PHND: LongWord;
  With Message do
    PID := LongWord(WParam);
    If PID <> 0 then
      PHND := OpenProcess(SYNCHRONIZE, False, PID);
      If PHND <> 0 then
        WaitForSingleObject(PHND, INFINITE);
        ShowMessage('Application was terminated');
    Result := 1;

You should be able to figure out where to place all the code that is missing from where to close the first app, where to run the code in the second app for the update, where to place the thread routines if you want to do it that way.

Let me know what you think.
millerwAuthor Commented:

Thanks for the reply.  I do like your is much simpler than mine :-).  

You seem to be a knowledgeable fellow so let me ask your opinion since you have done something like this already.  My application is a DB app that uses the database to store and update its own files.  The problem, is I would like to make it so that the Updater doesn't have to have database access.  Thus, I'd like for the EXE to "download" the data from the database and then someway tell the updater "here is the data for update" then quit.  One issue here is that the EXE update is not necessarily one this time it is a collection of 3 but that is of course subject to change :-).

I would like to perform the operation in a secure fashion (although the speed of the operation would be almost too fast for user "mistakes" :-), eg passing the downloaded file(s) handle(s) or something of that sort to where a user cannot gain access to the file(s).  I do have the ability to "compress" the three files into a single proprietary file format and pass only one handle or something of that sort.  

I have thought of creating *.~XXX file(s) that is/are simply renamed to *.XXX but that can cause problems if a user opens the ~XXX file before the updater gets to it.  That could, however, cause the updater to exit out abnormally of course instead of restarting the EXE...which would start the update procedure all over again :-)

So what do you think?  

I presume that your application is to run in a big organization. You want to launch updates transparently from the users and the users may not know that an update has been deployed or where to find the update file.
Well I have a couple of ideas. Concept if you will. Starting with the spimplest:

1. Have a file placed on a networkdrive. Your "update.exe" app. will then just copy this file to the client pc, overwriteting the main application. You could encrypt the file somehow to avoid nosy people to poke or "steal".

2. Supply your  "update.exe" with DB support and fetch the updated aplication from the DB. The DB could be password protected to avoid nosy people... etc...

3. Do your company have an intertnet (or even better intranet) web server in the house? If so, put your updated application on the FTP part of the web server. From your "update.exe" app just do an simple You could password protect the ftp access and even encrypt the latestrelease.exe file to protectect nosy... you get the drift I hope ;-)

4. Write your own server program to run on your server. A program that constantly runs on your server. Acces this program from "update.exe" with TCP/IP and transfer the latestrelease.exe. Encryption, password etc.

Depending on the security you want I'll go for number 1 or 3. Number 1 is the absolutely the easist one. With some encryption you don't have to wory about the users poking around. Futhermore you don't need to map a networkdrive. Just fetch the file from \\server\DBApp\latestupdate.exe. You can even password protect the \\server\DBApp share so your users can't browse it.
Number 3 has a very hight security factor, but requires that your company has a webserver running in the house.

Make up your mind and please come back with any quyestions and I'll try to give you a hint or two.
Good luck

- Martin

How goes? Did you solve your problem? Which solution did you use?

- Martin
millerwAuthor Commented:
The solution used is as follows:

1.  Check for the EXE and all EXE support file versions being old.
2.  If old, download all new versions into a proprietary compressed file format.
3.  Launch the updater (a glorified uncompressor really).
4.  Exit.

The updater then uncompresses everything and relaunches the executable.

I've been meaning to come back here and award you the points....I did use your "parameter method" to pass information which also solves the problem of the Updater being executed outside of the EXE calling it.  However, I did use the compressed file instead of the ideas above because it gives security as well as allowing the updater to not require access to the database--password concerns and such.

So far, the algorithm takes only about 1-3 seconds for a complete update (all files of the application are being updated all at once).  

My project manager is glowing :-)

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.