The Unofficial Newsletter of Delphi Users - by Robert
Vivrette
Auto Upgrading!
by Daniel J. Wojcik - wojcik@liaeur.21taacom.army.mil
I sit in my little office waaaaay over here and write applications for
all of those people waaaay over there in entirely too many different offices.
Well, I'm much too lazy to visit them and reload their systems every time
I make a change to the apps I write.
Luckily, we're all on the network, and I've come up with a fairly simple
way of giving them updates as needed.
I created a small application whose sole purpose in life is to copy
newer versions of the main app from a network server. Here's a skeleton
of my main apps' DPR file:
{**************************************************************************}
program THIS;
uses
SysUtils,
Windows,
Forms,
...;
You'll have to put in the Windows, since Delphi doesn't normally include
it in a DPR file. The '...' is where all the forms you've created
go, of course.
Var
Fn : String;
TSI : TStartupInfo;
TPI : TProcessInformation;
{$R *.RES}
begin
Use FileAge to check the dates...it doesn't mind UNC paths & filenames...
why hard-code a drive letter, if you don't have to?
IF FileAge('\\SomeServer\SomeDir\this.exe')
> FileAge(ParamStr(0)) THEN
IF Application.MessageBox('There
is a newer version THIS.EXE available.'+
#13'Would you like to get the newer version?',
'Upgrade Time!',1) = 1 THEN
Begin
Run the upgrade mini-app (which must be in the same directory as the main
app). If it starts, exit from this copy of the main app.
Since Application.Initialize hasn't been called yet, there be shouldn't
anything to clean up, resources-wise.
Fn := ExtractFilePath(ParamStr(0))+'UpgradeThis.exe';
FillChar(TSI, SizeOf(TSI), 0);
TSI.CB := SizeOf(TSI);
IF CreateProcess (PChar(Fn), NIL, NIL, NIL, False,
DETACHED_PROCESS, NIL, NIL, TSI, TPI) THEN
Exit
Of course, if the mini-app doesn't start for some reason, tell the user
they'll have to get the newer version the old-fashioned way. I still
exit the main app to give them the opportunity to do so. However,
just take out the exit in the next block to continue loading the current
version of the app if you'd rather.
ELSE
Begin
messagebeep(0);
Application.MessageBox('Unable to copy the file.'+'
' Please copy it manually.',
'Copy Error!',1);
Exit;
End;
End;
Application.Initialize;
Application.Title := 'This';
Application.HelpFile := 'This.hlp';
{autocreate forms, etc.}
Application.Run;
end.
The upgrade mini-app is a console application, so be sure to set the Linker
option to Generate Console Application.
program UpgradeThis;
uses
Forms,
SysUtils,
Windows;
Var
Fn : String;
TSI : TStartupInfo;
TPI : TProcessInformation;
{$R *.RES}
begin
Use CopyFile to copy the new version...just like FileAge, it doesn't mind
UNC paths & filenames.
IF CopyFile('\\SomeServer\SomeDir\this.exe',
PChar(ExtractFilePath(ParamStr(0))+'this.exe'),False) THEN
Begin
Once the new version of the main app has been copied, attempt to run it.
No reason it shouldn't run, so I didn't do any error checking in this block.
The worst that would happen is the user will be forced to run the app as
they normally do.
Fn := ExtractFilePath(ParamStr(0))+'this.exe';
FillChar(TSI, SizeOf(TSI),
0);
TSI.CB := SizeOf(TSI);
CreateProcess (PChar(Fn),
NIL, NIL, NIL, False,
DETACHED_PROCESS, NIL, NIL, TSI, TPI);
End
ELSE
Application.MessageBox('Could
not copy THIS.EXE', 'Error!', mb_OK);
end.
Notice there isn't any Application.Initialize or Application.Run in this
little app.
These methods can be extended to check for and copy newer versions of
the Help file (use GetWindowsDir or GetWindowsDirectory and append
"Help" to it in the upgrade app) or even newer versions of the upgrade
app.
The adventurous can make a universal upgrade app using commandline parameters
instead of the hard-coded filenames I use.