How to exclude extraction of root directory using Abbrevia AbZip in Delphi

427 Views Asked by At

I need to extract a zip file with Delphi using the Abbrevia ABZIP module. But I would like to exclude files in the root of the zip file.

Example: my zip file contains this

myfile.txt
otherfile.txt
directory1\myfile.txt
directory2\file.txt

Now I would like to exclude \myfile.txt but include \directory1\myfile.txt

I have tried the following:

procedure unzipFiles;
var
  zp  : TAbZipKit;

const
  includepath = '*.*';
  excludepath = '\myfile.txt';  // <<< various variants of "root" tried

begin
  //
  zp := TAbZipKit.Create(nil);
  zp.OpenArchive(StartDir + '\zipfile.zip');
  zp.BaseDirectory := StartDir;
  zp.ExtractOptions := [eoCreateDirs, eoRestorePath];
  zp.ExtractFilesEx(
             includepath,
             excludepath
        );
  zp.CloseArchive;
  zp.Free;
end;

Which option am I missing to "catch" only the root location of "myfile.txt" ?

** EDIT ** : if there is a way to ONLY extract subdirectories, it would also be usable for me.

1

There are 1 best solutions below

2
On

Solution found by digging into the ExtractFilesEx function. Simply use the collection FArchive and examine the properties of this.

The use the more lowlevel function ExtractAt

procedure unzipFiles;
var
  zp  : TAbZipKit;
  i   : integer; 

begin
  //
  zp := TAbZipKit.Create(nil);
  zp.OpenArchive(StartDir + '\zipfile.zip');
  zp.BaseDirectory := StartDir;
  zp.ExtractOptions := [eoCreateDirs, eoRestorePath];
 
  // ------- new 
  // examine if there is a /  in the StoredPath property
  // if blank, it's in the root.

  for i :=   0 to zp.FArchive.Count -1 do
    begin
      if   (zp.FArchive.ItemList.Items[i].StoredPath  <> '') then
        begin
          zp.ExtractAt(i, '');
        end;

    end;

(*
  zp.ExtractFilesEx(
             includepath,
             excludepath
        );
*)
  zp.CloseArchive;
  zp.Free;
end;

Solution with OnEvent handling, as per Peter Wolff

For this, a class must be added to the code.

// add these to the USES directive
uses
   AbBase, AbArcTyp, AbZipKit, Abutils;

// now add a class
type
 zip_helper = class
 public
      procedure ZipConfirmProcessItem(
                      Sender: TObject;
                      Item: TAbArchiveItem;
                      ProcessType: TAbProcessType;
                      var Confirm: Boolean);
 end;


// the class helper function could be like this:
procedure zip_helper.ZipConfirmProcessItem(
                Sender: TObject;
                Item: TAbArchiveItem;
                ProcessType: TAbProcessType;
                var Confirm: Boolean);
begin
        Confirm := (Item.StoredPath <> '');
end;


//  Now the extract from above can be changed to this:
procedure unzipDefaults;
var
  zp  : TAbZipKit;    // our zipper
  hlp: zip_helper;    // class helper

begin

  zp := nil;
  hlp := nil;
  try
          hlp := zip_helper.create;   // create the class helper
          zp := TAbZipKit.Create(nil);


          zp.OpenArchive(StartDir + '\Defaults.zip');
          zp.BaseDirectory := StartDir;
          zp.ExtractOptions := [eoCreateDirs, eoRestorePath];

           // set the event
           // 
          zp.OnConfirmProcessItem := hlp.ZipConfirmProcessItem;

          // and simply extract all
          zp.ExtractFiles('*.*');

          zp.CloseArchive;
    finally
          FreeAndNil(zp);
          freeandnil(hlp);
    end;
end;