Search code examples
inno-setupwildcardpascalfile-copyingdelphi

Inno Setup - FileCopy use wildcard character in pathname


I'm trying to copy all database files over from a previous installation to a new installation, which has a new pathname. The problem is that the installer will not know the names of the database files, so I'm trying to use a wildcard character.

I tried using TFileStream.Create(), but this was searching for a single file, such as "*.mdb", and I kept getting an error saying it couldn't find that file. I also tried using FileCopy(), but it seems to simply fail and move on. I even tried using Exec() to run it through command line, but it would just freeze the installation.

I've searched online a long time for an answer and read through a lot of the documentation. I just need to know how I can use a wildcard character to copy files with unknown names. Below are examples of what I've tried.

TFileStream.Create()

    OldDBs := 'C:\Users\seang\Desktop\Old\*.mdb';
    NewDBs := 'C:\Users\seang\Desktop\New\*.mdb';
    SourceDB:= TFileStream.Create(OldDBs, fmOpenRead);
    DestDB:= TFileStream.Create(NewDBs, fmCreate);
    DestDB.CopyFrom(SourceDB, SourceDB.Size);
    SourceDB.Free;
    DestDB.Free;

FileCopy()

    FileCopy('C:\Users\seang\Desktop\Old\*.mdb', 'C:\Users\seang\Desktop\New\*.mdb', True);

Command Line

    Exec('cmd.exe', 'COPY "C:\Users\seang\Desktop\Old\*.mdb" "C:\Users\seang\Desktop\New\*.mdb"', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);

Solution

  • You need to use FindFirst, FindNext, and FindClose to iterate through the folder. You get each database name, and then copy it individually. An example of doing that in Pascal (Delphi) can be found here. There's also an example of using them in the InnoSetup help file, in the Support Functions Reference section on File System Functions:

    // This example counts all of the files (not folders) in the System directory.
    var
      FilesFound: Integer;
      FindRec: TFindRec;
    begin
      FilesFound := 0;
      if FindFirst(ExpandConstant('{sys}\*'), FindRec) then begin
        try
          repeat
            // Don't count directories
            if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then
              FilesFound := FilesFound + 1;
          until not FindNext(FindRec);
        finally
          FindClose(FindRec);
        end;
      end;
      MsgBox(IntToStr(FilesFound) + ' files found in the System directory.',
        mbInformation, MB_OK);
    end;
    

    You can change the loop above to look in the proper old folder for each *.mdb (in the FindFirst call) and change the line that counts to a block that copies each file found into the new folder (using either FileCopy or a TFileStream, whichever you prefer).