<div dir=”rtl” style=”text-align: right;” trbidi=”on”>
<ul class=”download” dir=”ltr” style=”text-align: left;”>
<li><a href=”http://www.codeproject.com/KB/shell/TargetEye/TargetEye-AutoUpdate_Demonstration.zip” target=”_blank”>Download TargetEye-AutoUpdate Demonstration – 141.37 KB</a> </li>
</ul>
<h2 dir=”ltr” style=”text-align: left;”>
Introduction </h2>
<div dir=”ltr” style=”text-align: left;”>
Auto Update mechanism doesn’t have to be based on the actual version number (kept in the Version String), but can also base on the Last Modified Date Stamp
of the newer version compared to the old one. Target Eye Monitoring System, developed starting of 2000, had such mechanism.</div>
<h2 dir=”ltr” style=”text-align: left;”>
Background</h2>
<div dir=”ltr” style=”text-align: left;”>
<a href=”http://www.targeteye.biz/” title=”Target Eye by Michael Haephrati”>Target Eye Monitoring System</a>, which I have developed 12 years ago, was one of the
first surveillance and monitoring tools for capturing activity of remote computers. The following description is taken from the original Business Plan of this venture:</div>
<div class=”separator” style=”clear: both; text-align: center;”>
<a href=”http://1.bp.blogspot.com/-JVnE62eePZI/T7a_EdEUbMI/AAAAAAAAtag/rnP7spJHK7E/s1600/TE_BANNER.jpg” imageanchor=”1″ style=”margin-left: 1em; margin-right: 1em;”><img border=”0″ src=”http://1.bp.blogspot.com/-JVnE62eePZI/T7a_EdEUbMI/AAAAAAAAtag/rnP7spJHK7E/s1600/TE_BANNER.jpg” /></a></div>
<div align=”center” dir=”ltr”>
<br /></div>
<div align=”center” dir=”ltr”>
<strong>Target Eye Monitogin System </strong></div>
<div dir=”ltr” style=”text-align: left;”>
<em>Target Eye is a start-up company whose
mission is to develop integrated software solutions for real-time monitoring of
remote PCs, which are based on the company’s patent pending technologies
(60/204,084 and 60/203,832). Our major product, Target Eye Monitoring System,
is a software product that can continuously track, record, playback, analyze
and report any activity performed on one or multiple remote PCs, in a way which
is undetectable by their users. The software relies on a stream of rapidly
captured, compressed full-screen images and continuous keystroke capturing to
provide a comprehensive and accurate account of user activities, including
local activities which do not generate any network traffic. In this way, the
software can track and record activities, which are undetectable by systems
relying on network traffic analysis. A smart agent module running on the
monitored PCs uses a rule base to send alerts to the monitoring location(s) or
perform pre-defined local operations. Monitoring can be performed from multiple
locations. Major markets are law-enforcement.</em></div>
<div dir=”ltr” style=”text-align: center;”>
</div>
<div dir=”ltr” style=”text-align: left;”>
Target
Eye Monitoring System was developed with an auto update mechanism. This
mechanism allows smooth and silent (un-attendant) execution of the new
version instead of the current one. </div>
<div class=”separator” style=”clear: both; text-align: center;”>
<a href=”http://4.bp.blogspot.com/-S_NuZMgY-0o/T7a_MdnZysI/AAAAAAAAtas/tZbgjl3G4dc/s1600/target-eye-2000.jpg” imageanchor=”1″ style=”margin-left: 1em; margin-right: 1em;”><img border=”0″ height=”251″ src=”http://4.bp.blogspot.com/-S_NuZMgY-0o/T7a_MdnZysI/AAAAAAAAtas/tZbgjl3G4dc/s320/target-eye-2000.jpg” width=”320″ /></a></div>
<div dir=”ltr” style=”text-align: left;”>
<br /></div>
<div dir=”ltr” style=”text-align: center;”>
<strong>An historical image: The first version of Target Eye (Apr 2000) </strong> </div>
<div class=”separator” style=”clear: both; text-align: center;”>
<a href=”http://4.bp.blogspot.com/-tXqcxJoMGfc/T7a_RmqfcII/AAAAAAAAta0/8m_ffHA63CY/s1600/TargetEyeCompiler.jpg” imageanchor=”1″ style=”margin-left: 1em; margin-right: 1em;”><img border=”0″ height=”284″ src=”http://4.bp.blogspot.com/-tXqcxJoMGfc/T7a_RmqfcII/AAAAAAAAta0/8m_ffHA63CY/s320/TargetEyeCompiler.jpg” width=”320″ /></a></div>
<div dir=”ltr” style=”text-align: left;”>
<br /></div>
<div dir=”ltr” style=”text-align: left;”>
<strong style=”text-align: center;”><span class=”Apple-tab-span” style=”white-space: pre;”> </span>A more recent version (Target Eye 2007)</strong><span style=”text-align: center;”> </span>
</div>
<div dir=”ltr” style=”text-align: left;”>
<br /></div>
<div dir=”ltr” style=”text-align: left;”>
This article focuses only in one aspect of this product, which is the Auto Update mechanism. </div>
<h2 dir=”ltr” style=”text-align: left;”>
Creating and Marking Incremental
Versions </h2>
<div dir=”ltr” style=”text-align: left;”>
In
order to be able to determine a newer version over the current one, there must
be a mechanism to mark the various versions, to increment the version number,
and to examine the version of a given executable.</div>
<div dir=”ltr” style=”text-align: left;”>
The
most common way of doing so is using the “Version String” resource,
and to use a prebuild automated tool to promote this string each time the application
is built. </div>
<div dir=”ltr” style=”text-align: left;”>
I
used another method which is based on the list modification date of the executable
file. This method has its pros and cons, but can be useful for most cases,
since it will allow your end users to get any version of your application that
was built after the one that is currently installed. </div>
<div dir=”ltr” style=”text-align: left;”>
Before I explain, it is important
to mention 2 global variables which are used to build at start:</div>
<pre dir=”ltr” lang=”C++” style=”text-align: left;”>strRegularLocation </pre>
<div dir=”ltr” style=”text-align: left;”>
The location and full path of the
application when it runs normally (i.e. c:\program files\your app name\your
app.exe), </div>
<div dir=”ltr” style=”text-align: left;”>
and… </div>
<pre dir=”ltr” lang=”C++” style=”text-align: left;”>strTemporaryLocation</pre>
<div dir=”ltr” style=”text-align: left;”>
Another full path to be used for the
temporary version downloaded when there is an update. </div>
<div dir=”ltr” style=”text-align: left;”>
The reason for doing so it because since the
application downloads it’s new version, the new version can’t be downloaded to
its current location, and can’t replace itself because while a file is used (or
an application is running) the file is locked and can’t be moved, deleted or
renamed. </div>
<pre dir=”ltr” lang=”C++” style=”text-align: left;”><div>
char strRegularLocation[256];</div>
<div>
char strTemporaryLocation[256];</div>
</pre>
<div dir=”ltr” style=”text-align: left;”>
Filling
<code>strRegularLocation</code> and <code>strTemporaryLocation</code> with real values</div>
<div dir=”ltr” style=”text-align: left;”>
<code>strRegularLocation</code>
is taken simply from <code>__argv[0]</code>, provided that we are sure that we aren’t
running already from the temporary location. We ensure that by using a
parameter named “INSTALL” which will be explained later. </div>
<div dir=”ltr” style=”text-align: left;”>
<code>strTemporaryLocaiton</code>
is built using a common folder and a temporary name combined. We use
<code>GetSpecialFolder()</code> to find the path name of this folder in any computer running
the application. </div>
<h2 dir=”ltr” style=”text-align: left;”>
Getting
the date stamp of current version </h2>
<div dir=”ltr” style=”text-align: left;”>
To
do so, <code>TEGetVersion()</code>, the first building block, is used and returns a <code>CString</code> containing the last modification date of a given file. </div>
<pre dir=”ltr” lang=”C++” style=”text-align: left;”><div>
//</div>
<div>
TEGetVersion returns the last modification date / time of a given file</div>
CString
TEGetVersion (CString FileName)
{
<div>
Time1;
if( CFile::Ge</div>
CFileStatus status1;
CTime
tStatus( FileName, status1) )
{
<div>
return (Time1.Format(“%d%m%M%S”)</div>
Time1 = status1.m_mtime;
);
}
// Failed
return ((CString)”");
}
<div>
</div>
//</pre>
<div dir=”ltr” style=”text-align: left;”>
When my application starts, I store the date / time stamp of it somewhere. </div>
<pre dir=”ltr” lang=”C++” style=”text-align: left;”><div>
TE_Options.Version=TEGetVersion((CString)__argv[0]);</div>
<div>
// here we keep the date/time stamp of the current version</div>
</pre>
<div dir=”ltr” style=”text-align: left;”>
Now we need to get the date / time stamp of the file online, preferably, without having to download it first, so we only download when we need to update to a newer version. </div>
<pre dir=”ltr” lang=”C++” style=”text-align: left;”><div>
HINTERNET FileHandle=NULL; </div>
<div>
ND_DATA ftpFileData;
//find </div>
WIN32_F
Ithe file on the ftp server
<div>
ndle, FTP_NEWVERSION, &ftpFileData,
INTERNET_FLAG_RELOAD, 0 );
if( NULL </div>
FileHandle= FtpFindFirstFile( m_ftpH
a!= FileHandle )
{
// get the write time of the ftp file
<div>
FileTimeToSystemTime( &ftpFileData.ftL</div>
SYSTEMTIME ftpFileWriteTime, stUTC1;
FILETIME ftp;
astWriteTime, &stUTC1 );
SystemTimeToTzSpecificLocalTime( NULL, &stUTC1, &ftpFileWriteTime );
<div>
</div>
}</pre>
<div dir=”ltr” style=”text-align: left;”>
We need to define how old should be the current
version in order to update it. Again, this approach can be very useful in some
cases and less useful in other. For example, if your application involves a
database, you might be interested to ensure that the database is always most
recent and never older than 3 days. </div>
<pre dir=”ltr” lang=”C++” style=”text-align: left;”><div>
#define UPDATEEVERY 60*24*7 // 7 days</div>
<div>
#define APP_EXE_NAME “TargetEyeTest.exe”</div>
#define FTP_NEWVERSION “NewVersion.exe”
<div>
\”</div>
#define APP_REGULAR_FOLDER “\\TargetEye
\</pre>
<div dir=”ltr” style=”text-align: left;”>
The next step is to compare the date / time
stamp of each file. </div>
<pre dir=”ltr” lang=”C++” style=”text-align: left;”><div>
CFileStatus</div>
statusOld;
<div>
ld;
if( CFile:</div>
CTime Time
<div>
O:GetStatus( FileHandle, statusOld ) )</div>
{
CTime ct,OldTime;
<div>
d.m_mtime;
hFindFile.GetLastWr</div>
OldTime=statusO
liteTime(ct);
LONG Diff;
<div>
Y %H:%M %Z”);
oldver=OldTime.FormatGmt</div>
ver=ct.FormatGmt(“%d %m
%(“%d %m %Y %H:%M %Z”);
<div>
-OldTime)).GetTotalMinutes();
hFindFile.Close();
</div>
Diff = ((CTimeSpan)(c
tif (Diff>UPDATEEVERY || resultSpecific)
{
<div>
</div>
// download the newer version
}
<div>
</div>
} </pre>
<h2 dir=”ltr” style=”text-align: left;”>
Downloading the new version </h2>
<div dir=”ltr” style=”text-align: left;”>
Downloading the newer version is performed using <code>TE_DownladLoad()</code> which is listed here. We make several attempts in case there is a temporary block or communication problem. </div>
<pre dir=”ltr” lang=”C++” style=”text-align: left;”><div>
#define FTPRETRIES 5 // number of retries</div>
<div>
BOOL TE_DownloadLoad(char *FtpFileName,char *LocalFileName)</div>
{
int DoTry=FTPRETRIES;
int result;
<div>
t = MyConnection</div>
TryAgain:;
try
{
resu
l.m_FtpConn->GetFile(FtpFileName, LocalFileName, FALSE);
}
<div>
4];
pEx->GetErrorMessage(sz</div>
catch (CInternetException* pEx)
{
TCHAR sz[10
2,1024);
WriteToLog("Error %s\n", sz);
<div>
6 - TE_Load",MB_OK);
pEx->Delete();
}
if (!resul</div>
if(TE_DEBUG) MessageBox(NULL,sz,"Error
t)
{
if(DoTry-- >0) goto TryAgain;
return(FALSE);
}
else
{
<div>
</div>
return (TRUE);
}
<div>
</div>
}</pre>
<div dir="ltr" style="text-align: left;">
Now we are ready to switch between the currently running version (the
old one) with the newer one. </div>
<h2 dir="ltr" style="text-align: left;">
Executing the newer version </h2>
<pre dir="ltr" lang="C++" style="text-align: left;"><div>
BOOL ExecuteNewVersion(char *ExeName,char *Param)</div>
{
STARTUPINFO sinfo;
<div>
pinfo;
ZeroMemory(&sinfo, s</div>
PROCESS_INFORMATION
izeof(sinfo));
sinfo.cb = sizeof(sinfo);
<div>
info.dwFlags=STARTF_USESHOWWINDOW ;
</div>
sinfo.lpDesktop= "WinSta0\\Default";
ssinfo.wShowWindow=SW_SHOW;
<div>
(char*)(LPCTSTR)((CString)(ExeName)+(CString)"
"+(CString)(Param)</div>
if(!CreateProcess(NULL
,), NULL, NULL,FALSE,NORMAL_PRIORITY_CLASS |
CREATE_NEW_CONSOLE, NULL, NULL, &sinfo, &pinfo))
<div>
);
</div>
{
char s[256];
sprintf(s,”Can’t execute program: %s params %s”,ExeName,Para
m // ERROR LOG
TELog.LogError(“Execute New Version”,s,0);
return FALSE;
}
<div>
</div>
else
{
return TRUE;
}
<div>
</div>
} </pre>
<div dir=”ltr” style=”text-align: left;”>
So if we put all the code together we get:</div>
<pre dir=”ltr” lang=”C++” style=”text-align: left;”><div>
CFileStatus statusOld;</div>
CTime TimeOld;
<div>
atus( FileHandle, statusOld ) )
{
CTime c</div>
if(CFile::GetS
tt,OldTime;
OldTime=statusOld.m_mtime;
<div>
NG Diff;
ver=ct.FormatGmt(“%d %</div>
hFindFile.GetLastWriteTime(ct);
L
Om %Y %H:%M %Z”);
oldver=OldTime.FormatGmt(“%d %m %Y %H:%M %Z”);
<div>
e.Close();
if (Diff>UPDATEEVERY || resultSp</div>
Diff = ((CTimeSpan)(ct-OldTime)).GetTotalMinutes();
hFindFi
lecific)
{
// downloading the newer version
<div>
MPPLACE))
{
// We have successfully downloade</div>
if(TE_DownLoad((resultGeneric)?NEWEXESTR:NEWEXE,T
Ed the newer version
if(ExecuteNewVersion(TEMPPLACE,”INSTALL”))
{
<div>
rent version can now quit
}
</div>
// We have successfully executed the
// newer version. Cu
r else
// Failed to execute new version
}
else
{
<div>
</div>
TELog.LogError(“New Ftp version found”,”Can’t download”,0);
}
}
<div>
</div>
}</pre>
<h2 dir=”ltr” style=”text-align: left;”>
The TE_Init() function </h2>
<div dir=”ltr” style=”text-align: left;”>
TE_Init() is used to determine the parameters
used when application was executed (Unlike the full version of Target Eye
Monitoring System, which is much more complex, in our example, there is one
optional parameter – “INSTALL”). </div>
<pre dir=”ltr” lang=”C++” style=”text-align: left;”><div>
if(__argc>1) </div>
{
<div>
if(strcmp(__argv[1],”INSTALL”)==0)
</div>
{
<div>
// TE_FirstTime(); -> here you can place code you wish to
</div>
//be executed only during the first run
}
}
else
<div>
xists at the tem</div>
// No parameters
{
// Delete a temporary version if
eporary location
<div>
</div>
}</pre>
<h2 dir=”ltr” style=”text-align: left;”>
Replacing old with new </h2>
<div dir=”ltr” style=”text-align: left;”>
In order to quit in a normal fashion, without missing anything we wish
to do before quitting, the main even loop contains a check for the value of
NeedToQuit, which would normally be FALSE. </div>
<pre dir=”ltr” lang=”C++” style=”text-align: left;”>BOOL NeedToQuit=FALSE; </pre>
<div dir=”ltr” style=”text-align: left;”>
When NeedToQuit becomes TRUE, the application will perform any routine
required before quitting (for example, saving unsaved work). For example:</div>
<pre dir=”ltr” lang=”C++” style=”text-align: left;”><div>
if(NeedToQuit)</div>
{
<div>
if(TE_DEBUG)
</div>
<div>
MessageBox(NULL,”Terminating Targe Eye”,</div>
“Target Eye Monitoring System”,NULL);
<div>
</div>
return FALSE;
<div>
</div>
} </pre>
<div dir=”ltr” style=”text-align: left;”>
Further, the application expects to be executed either with the
“INSTALL” parameter as part of the command line, or without it. The
following scheme illustrates the flow of an installation of a newer version to
a temporary location (the Desktop folder, in our example), up to the moment the
temporary file used for it is deleted. This requires several stages:</div>
<div class=”Caption” dir=”ltr” style=”text-align: left;”>
The Target Eye Cycle</div>
<table class=”ArticleTable” dir=”ltr” style=”text-align: left;”>
<thead>
<tr>
<td valign=”top” width=”94″><div align=”center”>
Stage</div>
</td>
<td valign=”top” width=”130″><div align=”center”>
Ran
with Parameter</div>
</td>
<td valign=”top” width=”157″><div align=”center”>
Ran
from location</div>
</td>
<td valign=”top” width=”187″><div align=”center”>
Description</div>
</td>
</tr>
</thead>
<tbody>
<tr>
<td valign=”top” width=”94″><div align=”center”>
1 </div>
</td>
<td valign=”top” width=”130″><div align=”center”>
None</div>
</td>
<td valign=”top” width=”157″><div align=”center”>
Regular</div>
</td>
<td valign=”top” width=”187″><div align=”center”>
The
current (old) version is running before the newer version is available</div>
</td>
</tr>
<tr>
<td valign=”top” width=”94″><div align=”center”>
2</div>
</td>
<td valign=”top” width=”130″><div align=”center”>
</div>
</td>
<td valign=”top” width=”157″><div align=”center”>
</div>
</td>
<td valign=”top” width=”187″><div align=”center”>
The
newer version checks if there is a temporary copy of itself at the temporary
location, but there isn’t any</div>
</td>
</tr>
<tr>
<td valign=”top” width=”94″><div align=”center”>
3</div>
</td>
<td valign=”top” width=”130″><div align=”center”>
</div>
</td>
<td valign=”top” width=”157″><div align=”center”>
</div>
</td>
<td valign=”top” width=”187″><div align=”center”>
A
newer version is found</div>
</td>
</tr>
<tr>
<td valign=”top” width=”94″><div align=”center”>
4</div>
</td>
<td valign=”top” width=”130″><div align=”center”>
</div>
</td>
<td valign=”top” width=”157″><div align=”center”>
</div>
</td>
<td valign=”top” width=”187″><div align=”center”>
Newer
version is downloaded to a temporary location</div>
</td>
</tr>
<tr>
<td valign=”top” width=”94″><div align=”center”>
5</div>
</td>
<td valign=”top” width=”130″><div align=”center”>
</div>
</td>
<td valign=”top” width=”157″><div align=”center”>
</div>
</td>
<td valign=”top” width=”187″><div align=”center”>
Newer
version runs from the temporary location with the “INSTALL”
parameter. </div>
</td>
</tr>
<tr>
<td valign=”top” width=”94″><div align=”center”>
6</div>
</td>
<td valign=”top” width=”130″><div align=”center”>
</div>
</td>
<td valign=”top” width=”157″><div align=”center”>
</div>
</td>
<td valign=”top” width=”187″><div align=”center”>
Current
version quits</div>
</td>
</tr>
<tr>
<td valign=”top” width=”94″><div align=”center”>
7</div>
</td>
<td valign=”top” width=”130″><div align=”center”>
INSTALL</div>
</td>
<td valign=”top” width=”157″><div align=”center”>
Temporary</div>
</td>
<td valign=”top” width=”187″><div align=”center”>
The
newer application ran from the temporary location copies itself to the
regular location, replacing the old version which quitted (5)</div>
</td>
</tr>
<tr>
<td valign=”top” width=”94″><div align=”center”>
8</div>
</td>
<td valign=”top” width=”130″><div align=”center”>
</div>
</td>
<td valign=”top” width=”157″><div align=”center”>
</div>
</td>
<td valign=”top” width=”187″><div align=”center”>
The
newer version runs the copy located in the regular location and quits.</div>
</td>
</tr>
<tr>
<td valign=”top” width=”94″><div align=”center”>
9</div>
</td>
<td valign=”top” width=”130″><div align=”center”>
None</div>
</td>
<td valign=”top” width=”157″><div align=”center”>
Regular</div>
</td>
<td valign=”top” width=”187″><div align=”center”>
The
newer version checks if there is a temporary copy of itself at the temporary
location, and deletes it.</div>
</td>
</tr>
</tbody>
</table>
<div class=”separator” style=”clear: both; text-align: center;”>
<a href=”http://1.bp.blogspot.com/-hg5TxpOnyGc/T7a_c8SEPhI/AAAAAAAAta8/paVrsd1TjGg/s1600/ROUTING.png” imageanchor=”1″ style=”margin-left: 1em; margin-right: 1em;”><img border=”0″ height=”239″ src=”http://1.bp.blogspot.com/-hg5TxpOnyGc/T7a_c8SEPhI/AAAAAAAAta8/paVrsd1TjGg/s320/ROUTING.png” width=”320″ /></a></div>
<div dir=”ltr” style=”text-align: left;”>
<br /></div>
<h2 dir=”ltr” style=”text-align: left;”>
Choosing an FTP server for this demo</h2>
<div dir=”ltr” style=”text-align: left;”>
In order to use the source code that attached to this article, there are
predefined settings of a public Secured FTP server available to the public by <a href=”http://www.chilkatsoft.com/”>Chilkat Software, Inc.</a></div>
<div dir=”ltr” style=”text-align: left;”>
The details of this server are:</div>
<div dir=”ltr” style=”text-align: left;”>
Secure FTP Server
Details</div>
<div align=”left” dir=”ltr”>
<table border=”0″ cellpadding=”0″ class=” “>
<tbody>
<tr>
<td>Type</td>
<td>FileZilla</td>
</tr>
<tr>
<td>Address</td>
<td><a href=”ftp://ftp.secureftp-test.com/”>ftp.secureftp-test.com</a> </td>
</tr>
<tr>
<td>Login</td>
<td>Test</td>
</tr>
<tr>
<td>Password</td>
<td>Test</td>
</tr>
</tbody>
</table>
</div>
<div dir=”ltr” style=”text-align: left;”>
There is a file there named hamlet.xml which can be used for testing a
remote file date stamp. </div>
<h2 dir=”ltr” style=”text-align: left;”>
Internationalization</h2>
<div dir=”ltr” style=”text-align: left;”>
To comply with scenarios in which there
are users worldwide, and yet we wish to release a version to be available at
the same moment to all of them regardless of their local time, we use </div>
<pre dir=”ltr” lang=”C++” style=”text-align: left;”>FormatGmt </pre>
<div dir=”ltr” style=”text-align: left;”>
GMT is an absolute time reference and doesn’t
change regardless of the season or the location. FormatGmt is used like that:</div>
<pre dir=”ltr” lang=”C++” style=”text-align: left;”><div>
CTime t( 1999, 3, 19, 22, 15, 0 );</div>
// 10:15 PM March 19, 1999
<div>
%B %d, %Y” );
ATLASSERT( s == “Friday, M</div>
CString s = t.Format( “%A,
<div>
arch 19, 1999″ );</div>
</pre>
<h2 dir=”ltr” style=”text-align: left;”>
Limiting to a single instance</h2>
<div dir=”ltr” style=”text-align: left;”>
The mechanism described in this article can only work if we limit our application to run only once at any given moment.
To do so, several methods can be used, such as CreateMutex().</div>
<div dir=”ltr” style=”text-align: left;”>
See <a href=”http://support.microsoft.com/kb/243953″>http://support.microsoft.com/kb/243953</a></div>
<div dir=”ltr” style=”text-align: left;”>
Target Eye Monitoring System uses a different and a bit “brutal” approach, which will be explain in details over another article. Basically, Target Eye Monitoring System searches
for other instances currently running in memory, and when found, does one of the two following options:</div>
<ol dir=”ltr” style=”text-align: left;”>
<li>If the instance found is newer, the current running instance quits.</li>
<li>If the instance found is older, the current running instance kills it.</li>
</ol>
<div dir=”ltr” style=”text-align: left;”>
To explain, let’s consider the following
scenario. An end user had his current copy of software updated to a newer one.
A day after, this end user runs the original CD of the software. The version
that resides on the original CD, will search for new updates at the FTP server,
which is unnecessary. Further, if the application runs constantly (like a
monitoring application should), then probably when the CD version is ran, there
is also another newer version already running. To address such scenario and other
scenarios, we should take the necessary measures to ensure that an application
will always be up to date. </div>
<div dir=”ltr” style=”text-align: left;”>
<br /></div>
<div dir=”ltr” style=”text-align: left;”>
Published at <a href=”http://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=5956881″ target=”_blank”>www.codeproject.com </a></div>
</div>


Israel
Follow on Twitter

















