'Inno Setup - Get info on file in installer

How do you get information (last modification timestamp, file size) about a file which is included in the installer? It's easy to reference a file on disk, by using its path. But how do you reference a file in the installer when it doesn't have a path?

When the installer initialises, I would like to check if any of the files to be installed are already on the disk. For those files that are already on the disk (same last modification timestamp and same file size), I would like to display a window for the user to be able to select which ones they want to overwrite.



Solution 1:[1]

The following preprocessor code will generate a Pascal Scripting function that returns timestamp string for given relative file path:

#define SourcePath "C:\myappfiles"

function GetSourceFileDateTimeString(FileName: string): string;
begin

#define FileEntry(FileName, SourcePath) \
    Local[0] = GetFileDateTimeString(SourcePath, "yyyy/mm/dd hh:nn:ss", "-", ":"),\
    "  if SameText(FileName, '" + FileName + "') then " + \
        "Result := '" + Local[0] + "'" + NewLine + \
    "    else" + NewLine

#define ProcessFile(Root, Path, FindResult, FindHandle) \
    FindResult \
        ? \
            Local[0] = FindGetFileName(FindHandle), \
            Local[1] = (Len(Path) > 0 ? Path + "\" : "") + Local[0], \
            Local[2] = Root + "\" + Local[1], \
            (Local[0] != "." && Local[0] != ".." \
                ? (DirExists(Local[2]) \
                      ? ProcessFolder(Root, Local[1]) \
                      : FileEntry(Local[1], Local[2])) \
                : "") + \
            ProcessFile(Root, Path, FindNext(FindHandle), FindHandle) \
        : \
            ""
#define ProcessFolder(Root, Path) \
    Local[0] = FindFirst(Root + "\" + Path + "\*", faAnyFile), \
    ProcessFile(Root, Path, Local[0], Local[0])
    
#emit ProcessFolder(SourcePath, "")
  RaiseException(Format('Unexpected file "%s"', [FileName]));
end;

The generated script will be like:

function GetSourceFileDateTimeString(FileName: string): string;
begin
  if SameText(FileName, 'sub1\file1.exe') then Result := '2022-02-16 18:18:11'
    else
  if SameText(FileName, 'sub2\file2.exe') then Result := '2022-02-16 18:18:11'
    else
  if SameText(FileName, 'file3.exe') then Result := '2022-02-19 09:50:14'
    else
  if SameText(FileName, 'file4.exe') then Result := '2022-02-19 09:50:14'
    else
  RaiseException(Format('Unexpected file "%s"', [FileName]));
end;

(See Inno Setup: How do I see the output (translation) of the Inno Setup Preprocessor?)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1