Search code examples
inno-setuppascalscript

How to set creation time of existing file in Inno Setup Pascal Script


When copying a file by FileCopy (or also RenameFile) from a directory to another one an original creation time changes to the current date. I would like to set the creation time to the original one.

I can get the original time values by FindFirst, but how to get a handle of a file to use when calling SetFileTime?

In the [Code] section of Inno Setup, I have this code:

If FileCopy(F1, F2,False) then
  If FindFirst(F1,FindRec) then
    Try
      Fhandle := ??????????? (FindRec.FindHandle don't works)
      SetFileTime(
        Fhandle, FindRec.CreationTime, FindRec.LastAccessTime, FindRec.LastWriteTime)
    finally
      FindClose(FindRec);
    end

EDIT:

After the answer of Martin I have modified the code as follow (sorry if is far than perfect... I am a VB.NET programmer, not a Pascal programmer):

{ C1 and C2 are full Paths }
if Not FileCopy(C1, C2, False) then
   begin
     MsgBox('Data reading error 01. Setup will be aborted.', mbError, MB_OK);
     Result := false;
     exit;
   end;

if FindFirst(C2, FindRec) then 
    try
     begin
      MyTime := FindRec.LastWriteTime //remains the original one
     end;
    finally
      FindClose(FindRec);
    end
 else
   begin
     MsgBox('Data reading error 02. Setup will be aborted.', mbError, MB_OK);
     Result := false;
     exit;
    end;
 end;  

 FileStream := TFileStream.Create(C2, fmOpenReadWrite);
 Try
    if not SetFileTime(FileStream.Handle, MyTime, MyTime, MyTime) Then
       begin
        MsgBox('Data reading error 03. Setup will be aborted.', mbError, MB_OK);
        Result := false;
        exit;
     end;
 Finally
    FileStream.Free;
 end;  

Solution

  • To obtain a handle of a file, you can use TFileStream class:

    var
      FileStream: TFileStream;
    begin
      { ... }
      FileStream := TFileStream.Create(FileName, fmOpenReadWrite);
      try
        SetFileTime(FileStream.Handle, CreationTime, LastAccessTime, LastWriteTime);
      finally
        FileStream .Free;
      end;
    end;
    

    Though as @Ken wrote, in most cases, it would be easier to use [Files] section entry with an external flag.