[DUG] How to replace a file currently in use (Windows)

John Bird johnkbird at paradise.net.nz
Wed Jan 19 13:53:27 NZDT 2011


I do it slightly differently – I have a dedicated loader program which can update a number of files and programs in one go.   It runs as the startup/splash screen for the main app menu.

Updated programs are in an update folder,
working programs are in a (local) folder

It does:
-Reads a list of files to check
-copies any newer files from the update folder to the working folder
-because it only copies newer files it is fast.
-checks the dates and times of all files afterwards, and retries a second way if any discrepancies.   Logs progress and errors.  Warns if any not latest.
-runs the main menu program and quits.

-Main menu also periodically checks same list for pending updates and turns the “get updates” button bright yellow.
-If “Get updates” clicked it runs the updater program and quits.

Main smart is to check date and time file stamps are within 10 seconds to be the same.   Different file systems have different time granularities (FAT32 I think is around 2 seconds and NTFS is milliseconds I think) so if you copy from one to another the dates and times will likely be slightly different if update and working folders are on different filesystems.

(Also the updater program is the only one run from the updates folder – all others from working folder)

This sort of scheme is used by Firefox too – it runs a program updater.exe and quits, updater.exe  does the updates   (usually a number of files are updated), and then runs firefox again.

function xfFilesChanged(file1: string; file2: string): integer;
//check 2 files modification date
//returns 0=both files same, 1=file1 later, 2=file2 later
//if within 10secs counted as same
//note if one file does not exist, returns other as later
var
  fileage1, fileage2: integer;
  dtdate1, dtdate2, dt10secs: TDateTime;
begin
  result := 0;
  fileage1 := FileAge(file1);
  fileage2 := FileAge(file2);
  if (fileage1 < 0) and (fileage2 > 0) then
  begin
    result := 2;
    exit;
  end;
  if (fileage2 < 0) and (fileage1 > 0) then
  begin
    result := 1;
    exit;
  end;
  if (fileage1 < 0) or (fileage2 < 0) then exit; //maybe both don't exist
  dtdate1 := FileDatetoDateTime(fileage1);
  dtdate2 := FileDatetoDateTime(fileage2);
  if dtdate1 = dtdate2 then
  begin
    result := 0;
    exit;
  end;
  //now if not same, check if within 10 secs
  //in case of different filesystems
  dt10secs := encodetime(0, 0, 10, 0);
  if (dtdate2 > (dtdate1 - dt10secs))
    and (dtdate2 < (dtdate1 + dt10secs)) then
  begin
    result := 0;
    exit;
  end;
  //still different
  if dtdate1 > dtdate2 then result := 1
  else result := 2;
end;


John
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://listserver.123.net.nz/pipermail/delphi/attachments/20110119/e6a7c971/attachment.html 


More information about the Delphi mailing list