Read modified time from one file and use it to set the time for files in a whole directory

China☆狼群 提交于 2019-12-02 01:39:54
TLama

To change the last modified time (let's call it LastWriteTime for now) for all files from a specified directory by the LastWriteTime of a certain file, use the following code after you have your files extracted. You can follow the commented version of the previous version of this post, but note that I've had bugs there (mixed time parameters and unused file flag parameter), but the point remains.

Also note that this code is for ANSI version of InnoSetup. If you need to use this for Unicode version, you should define the CreateFile function import as CreateFileW instead of CreateFileA or use the trick suggested by kobik in this post.

[code]
const
  OPEN_EXISTING = 3;  
  FILE_SHARE_WRITE = 2;
  GENERIC_WRITE = $40000000;
  INVALID_HANDLE_VALUE = 4294967295;

function CreateFile(lpFileName: string; dwDesiredAccess, dwShareMode,
  lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes: DWORD;
  hTemplateFile: THandle): THandle; 
  external 'CreateFileA@kernel32.dll stdcall';
function CloseHandle(hObject: THandle): BOOL; 
  external 'CloseHandle@kernel32.dll stdcall';
function SetFileTime(hFile: THandle; const lpCreationTime, lpLastAccessTime, 
  lpLastWriteTime: TFileTime): BOOL; 
  external 'SetFileTime@kernel32.dll stdcall';

function FileSetTime(const AFileName: string; const ACreationTime, 
  ALastAccessTime, ALastWriteTime: TFileTime): Boolean;
var
  FileHandle: THandle;
begin
  Result := False;
  FileHandle := CreateFile(AFileName, GENERIC_WRITE, FILE_SHARE_WRITE, 0,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if FileHandle <> INVALID_HANDLE_VALUE then
  try
    Result := SetFileTime(FileHandle, ACreationTime, ALastAccessTime, 
      ALastWriteTime);
  finally
    CloseHandle(FileHandle);
  end;
end; 

procedure ModifyLastWriteTime(const ASourceFile, ATargetFolder: string);
var
  FindRec: TFindRec;
  LastWriteTime: TFileTime;
begin
  if FindFirst(ASourceFile, FindRec) then
  begin
    LastWriteTime := FindRec.LastWriteTime;
    if FindFirst(ATargetFolder + '*.*', FindRec) then
    try
      repeat
        if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
          FileSetTime(ATargetFolder + FindRec.Name, FindRec.CreationTime, 
            FindRec.LastAccessTime, LastWriteTime);
      until
        not FindNext(FindRec);
    finally
      FindClose(FindRec);
    end;
  end;
end;

And the usage. The first parameter of the ModifyLastWriteTime procedure is the name of the source file from which the LastWriteTime is taken. The second parameter is the directory in what the files will get modified their LastWriteTime values by the source file (don't forget to have the trailing backslash in the target folder parameter):

ModifyLastWriteTime('c:\SourceFile.xxx', 'c:\TargetFolder\')

About the second question, you can delete the files which have been extracted in a procedure called

Procedure CancelButtonClick(CurPageID: Integer; Var Cancel, Confirm: Boolean);
Begin
End;

As explained in the chm, section Pascal Scripting: Event Functions

About the first question I would suggest you to use inno setup [files] section instead of extracting from an archive. You could probably extract this archive to a local folder (so from your side, before compiling, and add this local folder to the [files]. But I may misunderstand your imperative about the file modification date.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!