myleseven
asked on
Update system
Hi everyone,
I am tryin to build an update system for my application.
I am just wondering the best way to go about doing it.
The basic logic for my system looks something like this:
logic
Client click update
Connect to server
Send client version number eg 1.2.10
Compare version on server with client version
if version on server is higher then
begin
get server address of files to be downloaded
for each file to be downloaded
begin
download
end;
when finished downloading
run installer
begin
for each file that was downloaded
begin
rename current file as old file eg simplewriter_old.exe
rename downloaded file eg simplewriter_new.exe -> simplewriter.exe
delete simplewriter_old.exe
end;
end;
end else
begin
output 'no need to update'
end;
But at the moment I have quite a static system that is heavily dependent on the code that is on my clients machines.
Is there anyway I can build a system where the user can connect to eg some php script and this script on the server takes care of the update for the user? Is this advised?
The reason that I am thinking to do this is because as things change so much, it would be better to have code that I can edit on the server as the changes happen rather than being dependent on the code that is comiled in the exe on the users comptuer...
What are your thoughuts?
cheers
myles
I am tryin to build an update system for my application.
I am just wondering the best way to go about doing it.
The basic logic for my system looks something like this:
logic
Client click update
Connect to server
Send client version number eg 1.2.10
Compare version on server with client version
if version on server is higher then
begin
get server address of files to be downloaded
for each file to be downloaded
begin
download
end;
when finished downloading
run installer
begin
for each file that was downloaded
begin
rename current file as old file eg simplewriter_old.exe
rename downloaded file eg simplewriter_new.exe -> simplewriter.exe
delete simplewriter_old.exe
end;
end;
end else
begin
output 'no need to update'
end;
But at the moment I have quite a static system that is heavily dependent on the code that is on my clients machines.
Is there anyway I can build a system where the user can connect to eg some php script and this script on the server takes care of the update for the user? Is this advised?
The reason that I am thinking to do this is because as things change so much, it would be better to have code that I can edit on the server as the changes happen rather than being dependent on the code that is comiled in the exe on the users comptuer...
What are your thoughuts?
cheers
myles
ASKER
The outputted source might look like this:
#$D#$A'newVersion: 1.2.11<br>
newTotSize: 3 Mega Bytes<br>
<br>
mmFlag: true<br>
mmAppName: App1_1.2.11.exe<br>
mmDownload: www.mySite.co.nz/Updates/myProg_1.2.11/App1_1.2.11.exe<br>
<br>
swFlag: false<br>
swAppName: App2_1.2.11.exe<br>
swDownload: www.mySite.co.nz/Updates/myProg_1.2.11/App2_1.2.11.exe<br>
<br>
snFlag: false<br>
snAppName: App3_1.2.11.exe<br>
snDownload: www.mySite.co.nz/Updates/myProg_1.2.11/App3_1.2.11.exe<br>
<br>
smFlag: false<br>
smAppName: App4_1.2.11.exe<br>
smDownload: www.mySite.co.nz/Updates/myProg_1.2.11/App4_1.2.11.exe<br>
<br>
ssFlag: true<br>
ssAppName: App5_1.2.11.exe<br>
ssDownload: www.mySite.co.nz/Updates/myProg_1.2.11/App5_1.2.11.exe<br>
<br>
inFlag: false<br>
inAppName: App6_1.2.11.exe<br>
inDownload: www.mySite.co.nz/Updates/myProg_1.2.11/App6_1.2.11.exe<br>
<br>
'#$D#$A#$D#$A#$D#$A#$D#$A# $D#$A#$D#$ A
#$D#$A'newVersion: 1.2.11<br>
newTotSize: 3 Mega Bytes<br>
<br>
mmFlag: true<br>
mmAppName: App1_1.2.11.exe<br>
mmDownload: www.mySite.co.nz/Updates/myProg_1.2.11/App1_1.2.11.exe<br>
<br>
swFlag: false<br>
swAppName: App2_1.2.11.exe<br>
swDownload: www.mySite.co.nz/Updates/myProg_1.2.11/App2_1.2.11.exe<br>
<br>
snFlag: false<br>
snAppName: App3_1.2.11.exe<br>
snDownload: www.mySite.co.nz/Updates/myProg_1.2.11/App3_1.2.11.exe<br>
<br>
smFlag: false<br>
smAppName: App4_1.2.11.exe<br>
smDownload: www.mySite.co.nz/Updates/myProg_1.2.11/App4_1.2.11.exe<br>
<br>
ssFlag: true<br>
ssAppName: App5_1.2.11.exe<br>
ssDownload: www.mySite.co.nz/Updates/myProg_1.2.11/App5_1.2.11.exe<br>
<br>
inFlag: false<br>
inAppName: App6_1.2.11.exe<br>
inDownload: www.mySite.co.nz/Updates/myProg_1.2.11/App6_1.2.11.exe<br>
<br>
'#$D#$A#$D#$A#$D#$A#$D#$A#
ASKER
Basically after verifying that there is a newer version on the Web my updater will pull the source code from the web
and for example then call the proc: StartUpdate
function TfrmUpdate.StartUpdate(sMo therDownlo adPath, sSource, sInstallerPath, sVersiononWeb : string): string;
{Begins the download process
1. Creates a logfile to record what files were downloaded
2. Prepares system to download each file if it has not been already}
{Returns: File path of the downloaded installer or c_Null if it has not yet been downloaded}
var
sLocalDownloadPath,sLogPat h : string;
aTextFile : TextFile;
begin
g_DoDownload := true;
sInstallerPath := c_null;
//create a log file to store the info as to which files were downloaded
//each log will be unique for the download version
//this log file will not be re writtain to but wil be appended to
//The installer will refer to this file when installing the files....
if (g_DoDownload = true) then
begin
sLocalDownloadPath := sMotherDownloadPath + 'installer\';
ForceDirectories(sLocalDow nloadPath) ;
sLogPath := sLocalDownloadPath + 'log_'+ sVersiononWeb+ '.txt';
If FileExists(sLogPath) = false then
begin
AssignFile(aTextFile, sLogPath);
Rewrite(aTextFile);
closefile(atextfile);
end;
end;
//prepare to download mainmenu
//NOTE: mmFlag is the flag on the server that lets system know it needs to download this file
if (g_DoDownload = true) and (StrToBool(getKeyValue('mm Flag:',sSo urce))) then
begin
sLocalDownloadPath := sMotherDownloadPath + 'App1\';
PrepareSavetoDisk(sLogPath ,sSource,s LocalDownl oadPath,'m mDownload: ','mmAppNa me');
end;
if (g_DoDownload = true) and (StrToBool(getKeyValue('sw Flag:',sSo urce))) then
begin
//repare to download simplewriter
sLocalDownloadPath := sMotherDownloadPath + 'App2\';
PrepareSavetoDisk(sLogPath ,sSource,s LocalDownl oadPath,'s wDownload: ','swAppNa me');
end;
if (g_DoDownload = true) and (StrToBool(getKeyValue('sm Flag:',sSo urce))) then
begin
//prepare to download simplemail
sLocalDownloadPath := sMotherDownloadPath + 'App3\';
PrepareSavetoDisk(sLogPath ,sSource,s LocalDownl oadPath,'s mDownload: ','smAppNa me');
end;
if (g_DoDownload = true) and (StrToBool(getKeyValue('sn Flag:',sSo urce))) then
begin
//prepare to download simplenet
sLocalDownloadPath := sMotherDownloadPath + 'App4\';
PrepareSavetoDisk(sLogPath ,sSource,s LocalDownl oadPath,'s nDownload: ','snAppNa me');
end;
if (g_DoDownload = true) and (StrToBool(getKeyValue('ss Flag:',sSo urce))) then
begin
//prepare to download simpleshortcut
sLocalDownloadPath := sMotherDownloadPath + 'App5\';
PrepareSavetoDisk(sLogPath ,sSource,s LocalDownl oadPath,'s sDownload: ','ssAppNa me');
end;
//NOTE: The installer must be downloaded last as a shortcut is placed on the desktop
// and if user does a partial download then we don't want the user to be able to click
// the shortcut to install the software if it has not all been downloaded
if (g_DoDownload = true) and (StrToBool(getKeyValue('in Flag:',sSo urce))) then
begin
//prepare to download installer exe
sLocalDownloadPath := sMotherDownloadPath + 'installer\';
sInstallerPath:=PrepareSav etoDisk(sL ogPath,sSo urce,sLoca lDownloadP ath,'inDow nload','in AppName');
result := sInstallerPath;
end;
result := sInstallerPath;
end;
and for example then call the proc: StartUpdate
function TfrmUpdate.StartUpdate(sMo
{Begins the download process
1. Creates a logfile to record what files were downloaded
2. Prepares system to download each file if it has not been already}
{Returns: File path of the downloaded installer or c_Null if it has not yet been downloaded}
var
sLocalDownloadPath,sLogPat
aTextFile : TextFile;
begin
g_DoDownload := true;
sInstallerPath := c_null;
//create a log file to store the info as to which files were downloaded
//each log will be unique for the download version
//this log file will not be re writtain to but wil be appended to
//The installer will refer to this file when installing the files....
if (g_DoDownload = true) then
begin
sLocalDownloadPath := sMotherDownloadPath + 'installer\';
ForceDirectories(sLocalDow
sLogPath := sLocalDownloadPath + 'log_'+ sVersiononWeb+ '.txt';
If FileExists(sLogPath) = false then
begin
AssignFile(aTextFile, sLogPath);
Rewrite(aTextFile);
closefile(atextfile);
end;
end;
//prepare to download mainmenu
//NOTE: mmFlag is the flag on the server that lets system know it needs to download this file
if (g_DoDownload = true) and (StrToBool(getKeyValue('mm
begin
sLocalDownloadPath := sMotherDownloadPath + 'App1\';
PrepareSavetoDisk(sLogPath
end;
if (g_DoDownload = true) and (StrToBool(getKeyValue('sw
begin
//repare to download simplewriter
sLocalDownloadPath := sMotherDownloadPath + 'App2\';
PrepareSavetoDisk(sLogPath
end;
if (g_DoDownload = true) and (StrToBool(getKeyValue('sm
begin
//prepare to download simplemail
sLocalDownloadPath := sMotherDownloadPath + 'App3\';
PrepareSavetoDisk(sLogPath
end;
if (g_DoDownload = true) and (StrToBool(getKeyValue('sn
begin
//prepare to download simplenet
sLocalDownloadPath := sMotherDownloadPath + 'App4\';
PrepareSavetoDisk(sLogPath
end;
if (g_DoDownload = true) and (StrToBool(getKeyValue('ss
begin
//prepare to download simpleshortcut
sLocalDownloadPath := sMotherDownloadPath + 'App5\';
PrepareSavetoDisk(sLogPath
end;
//NOTE: The installer must be downloaded last as a shortcut is placed on the desktop
// and if user does a partial download then we don't want the user to be able to click
// the shortcut to install the software if it has not all been downloaded
if (g_DoDownload = true) and (StrToBool(getKeyValue('in
begin
//prepare to download installer exe
sLocalDownloadPath := sMotherDownloadPath + 'installer\';
sInstallerPath:=PrepareSav
result := sInstallerPath;
end;
result := sInstallerPath;
end;
ASKER
function TfrmUpdate.GetKeyValue(sKe y,sSource: string):st ring;
var
iStart, iEnd : integer;
lSource, lKey : string ;
begin
lSource := lowercase(sSource);
lKey := lowercase(sKey);
//ensure there is a ':' at end of lKey
if lKey[Length(lKey)] <> ':' then lKey := lKey + ':';
iStart := PosEx(lKey,lSource) + length(lkey);
iEnd := posex('<br>',lSource,iStar t);
result := trim(MidStr(sSource,iStart ,iEnd-iSta rt));
end;
var
iStart, iEnd : integer;
lSource, lKey : string ;
begin
lSource := lowercase(sSource);
lKey := lowercase(sKey);
//ensure there is a ':' at end of lKey
if lKey[Length(lKey)] <> ':' then lKey := lKey + ':';
iStart := PosEx(lKey,lSource) + length(lkey);
iEnd := posex('<br>',lSource,iStar
result := trim(MidStr(sSource,iStart
end;
ASKER
The ,major problem is that the client code is heaveily dependent on the variables that it pulls from the webpage source
as can be seen from the delphi code:
if (g_DoDownload = true) and (StrToBool(getKeyValue('sn
begin
//prepare to download simplenet
sLocalDownloadPath := sMotherDownloadPath + 'App4\';
PrepareSavetoDisk(sLogPath
end;
can you see how I have 'hardcoded' in the value 'snFlag'. This value is then used as the key in 'GetKeyValue' to pull the boolean value that this snFlag refers to. I have used this system throughout the client code as can be seen in the call to proc:
PrepareSavetoDisk(sLogPath
with snDOwnload and snAppName both 'keys' that are used to reference values in the URL source
The thing is if I add for example a completely new application then my users won't be able to download this new application as they won't have the hardcoded 'Keys'
Do you see where my problem is?
Any ideas
ASKER
I think I need some sort of loop system to be able to pull the keys from the php page...
Hi
(This is the question I always ask for this)
If the user is on version 1 of "SimpleWriter.exe" and the latest version is version 3
does the user
A) download "SimpleWriter.exe" version 2, runs it and checks for next update, then downloads "SimpleWriter.exe" version 3, runs it, checks for updates, sees it is the latest update, and stops.
or
B) download "SimpleWriter1 to SimpleWriter2.exe", then "SimpleWriter2 to SimpleWriter3.exe"
or do they just
B) download "SimpleWriter.exe" version 3 ?
Is the updater code inside "SimpleWriter.exe" or is it "MyUpdater.exe"
and can you download updates for "MyUpdater.exe"
You could have the updater, update itself first ( so it gets the new available "hardcoded" application "snFlag")
If the applications are updating 1 version at a time, you can have a version that knows about the new stuff
and runs an update again once it is installed
V1.0 knows current snFlag
V1.5 knows current snFlag, and new snFlag, and will download new snFlag stuff next time
V2.0 knows current snFlag, and new snFlag
so when you upgrade to v1.5 it learns about the new snFlag, and when it updates, it downlaods the new files for snFlag
(This is the question I always ask for this)
If the user is on version 1 of "SimpleWriter.exe" and the latest version is version 3
does the user
A) download "SimpleWriter.exe" version 2, runs it and checks for next update, then downloads "SimpleWriter.exe" version 3, runs it, checks for updates, sees it is the latest update, and stops.
or
B) download "SimpleWriter1 to SimpleWriter2.exe", then "SimpleWriter2 to SimpleWriter3.exe"
or do they just
B) download "SimpleWriter.exe" version 3 ?
Is the updater code inside "SimpleWriter.exe" or is it "MyUpdater.exe"
and can you download updates for "MyUpdater.exe"
You could have the updater, update itself first ( so it gets the new available "hardcoded" application "snFlag")
If the applications are updating 1 version at a time, you can have a version that knows about the new stuff
and runs an update again once it is installed
V1.0 knows current snFlag
V1.5 knows current snFlag, and new snFlag, and will download new snFlag stuff next time
V2.0 knows current snFlag, and new snFlag
so when you upgrade to v1.5 it learns about the new snFlag, and when it updates, it downlaods the new files for snFlag
ASKER
Hi thanks Loki,
Yes that is a good question that you asked.
I think for general bug fixes and releases it would be ok for a user to go from version1.2.10 straight to version 1.2.13 for example
For major and minor realeases eg 1.2 move to 1.4 or 1 move to 3 I am still thinking abuot that one.
My upgrade system is reasonably primitive in that the user needs to download an entire exe for each app being upgraded so, it is probably ok to allow big jumps at this stage.
If I broke up my .exe's into .dll's etc perhaps I might need to step the user up through the version's I am not sure? as I havn't worked so much with .dll's before. What do you think?
The updater code is inside installer.exe
This file is downloaded from the server with all the latest .exe
I am thinking to have another variable inside the php code this would be a comma delimited string that holds all the flag keys
eg FlagKeys = mmFlag,snFlag,swFlag etc
downloadKeys=mmDownload,sn Download,s wDownload etc
I could then pull these vars from the client side app and loop through them as needed...
what do you think?
Yes that is a good question that you asked.
I think for general bug fixes and releases it would be ok for a user to go from version1.2.10 straight to version 1.2.13 for example
For major and minor realeases eg 1.2 move to 1.4 or 1 move to 3 I am still thinking abuot that one.
My upgrade system is reasonably primitive in that the user needs to download an entire exe for each app being upgraded so, it is probably ok to allow big jumps at this stage.
If I broke up my .exe's into .dll's etc perhaps I might need to step the user up through the version's I am not sure? as I havn't worked so much with .dll's before. What do you think?
The updater code is inside installer.exe
This file is downloaded from the server with all the latest .exe
I am thinking to have another variable inside the php code this would be a comma delimited string that holds all the flag keys
eg FlagKeys = mmFlag,snFlag,swFlag etc
downloadKeys=mmDownload,sn
I could then pull these vars from the client side app and loop through them as needed...
what do you think?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
.zipping up the files would be great, but how can do I extract them during install, especially if the user doesn't have winzip
you can make a self-extracting zip file (.exe)
ASKER
Can you point me as to where I can find out how to make a self-extracting zip it sounds great!
ok I gotta go now, be back tomorrow
cheers
Myles
I think it's a professional (ie. bought) feature, but I could be wrong
if you're using WinZip, it's Action->Make .exe
if you're using pkzip in dos mode, it's Zip2Exe
if you're using WinZip, it's Action->Make .exe
if you're using pkzip in dos mode, it's Zip2Exe
ASKER
Thanks heaps for your help loki
I havn't tried the zip extractoin yet but I will have a look later.
Anyway the points are yours
cheers
Myles
I havn't tried the zip extractoin yet but I will have a look later.
Anyway the points are yours
cheers
Myles
ASKER
<?PHP
//Run Code
FileDetails();
//Functions and Procs
function FileDetails()
{
$newVersion = "1.2.11";
echo "newVersion: " .$newVersion."<br>";
$newTotSize = "3 Mega Bytes"; //how can I make this dynamic
echo "newTotSize: " .$newTotSize."<br>";
echo "<br>";
//--Note: mmFlag will let system know if it should download this file
//download details for App1
$mmFlag = "true"; //tells client if can download this app
echo "mmFlag: " .$mmFlag."<br>";
$mmAppName = "App1_".$newVersion.".exe"
echo "mmAppName: " .$mmAppName."<br>";
$mmDownload = "www.mySite.co.nz/Updates/myProg_".$newVersion."/".$mmAppN
echo "mmDownload: " .$mmDownload."<br>";
echo "<br>";
//download details for App2
$swFlag = "false";
echo "swFlag: " .$swFlag."<br>";
$swAppName = "App2_".$newVersion.".exe"
echo "swAppName: " .$swAppName."<br>";
$swDownload = "www.mySite.co.nz/Updates/myProg_".$newVersion."/".$swAppN
echo "swDownload: " .$swDownload."<br>";
echo "<br>";
//download details for App3
$snFlag = "false";
echo "snFlag: " .$snFlag."<br>";
$snAppName = "App3_".$newVersion.".exe"
echo "snAppName: " .$snAppName."<br>";
$snDownload = "www.mySite.co.nz/Updates/myProg_".$newVersion."/".$snAppN
echo "snDownload: " .$snDownload."<br>";
echo "<br>";
//download details for App4
$smFlag = "false";
echo "smFlag: " .$smFlag."<br>";
$smAppName = "App4_".$newVersion.".exe"
echo "smAppName: " .$smAppName."<br>";
$smDownload = "www.mySite.co.nz/Updates/myProg_".$newVersion."/".$smAppN
echo "smDownload: " .$smDownload."<br>";
echo "<br>";
//download details for App5
$ssFlag = "true";
echo "ssFlag: " .$ssFlag."<br>";
$ssAppName = "App5_".$newVersion.".exe"
echo "ssAppName: " .$ssAppName."<br>";
$ssDownload = "www.mySite.co.nz/Updates/myProg_".$newVersion."/".$ssAppN
echo "ssDownload: " .$ssDownload."<br>";
echo "<br>";
//download details for App6
$inFlag = "false";
echo "inFlag: " .$inFlag."<br>";
$inAppName = "App6_".$newVersion.".exe"
echo "inAppName: " .$inAppName."<br>";
$inDownload = "www.simpleware.co.nz/Updates/myProg_".$newVersion."/".$inAppN
echo "inDownload: " .$inDownload."<br>";
echo "<br>";
}
?>