Search code examples
inno-setupunzip

How to unzip multiple files with InnoTools post install?


The script sample I have came from http://www.saidsimple.com/daniel/blog/117966/ and it’s only set for one zip. I want to be able to unzip any zips in a particular location. I guess one approach might be a wildcard *.zip when the zip name might vary depending on earlier installer selections.

No unzipping occurs. I’ve missed defining something or procedure is not setup properly. In my use the zips are text files the intended program reads for functions.

[Setup] …
SolidCompression=true
Compression=lzma
CreateAppDir=false
DirExistsWarning=false
ShowLanguageDialog=false
CreateUninstallRegKey=no
#include <idp.iss>

[Files]
Source: "{tmp}\text.net";  DestDir: "{userappdata}\ccc"; Flags: external; Components: abc
Source: "{tmp}\HLNJ.zip";  DestDir: "{userappdata}\ccc"; Flags: external deleteafterinstall; Components: hlnj
Source: "{tmp}\HNJ.zip"; DestDir: "{userappdata}\ccc"; Flags: external deleteafterinstall; Components: hnj

[Code]
const
  SHCONTCH_NOPROGRESSBOX = 4;
  SHCONTCH_RESPONDYESTOALL = 16;
procedure InitializeWizard; ...
begin ...
end;
procedure CurStepChanged(CurStep: TSetupStep); ...
begin
  if CurStep = ssPostInstall then 
  begin ...
end;
end;

procedure unzip(ZipFile, TargetFldr: PAnsiChar);
var
 shellobj: variant;
 ZipFileV, TargetFldrV: variant;
 SrcFldr, DestFldr: variant;
 shellfldritems: variant;
begin
 if FileExists('{userappdata}\ccc\HLNJ.zip') then begin
 ForceDirectories('{userappdata}\ccc’);
 shellobj := CreateOleObject('Shell.Application');
 ZipFileV := string(ZipFile);
 TargetFldrV := string(TargetFldr);
 SrcFldr := shellobj.NameSpace(ZipFileV);
 DestFldr := shellobj.NameSpace(TargetFldrV);
 shellfldritems := SrcFldr.Items;
 DestFldr.CopyHere(shellfldritems, SHCONTCH_NOPROGRESSBOX or SHCONTCH_RESPONDYESTOALL); 
 end;
end;

procedure ExtractSomething(src, target : AnsiString);
begin
 unzip(ExpandConstant(src), ExpandConstant(target));

end;

I would expect one of the zips to be unzipped. But nothing, even in inno log; nothing happens in this section of code. At least deletion of zip works.

EDIT: I’m revisiting an issue I did not solve last year. The problem is getting the Unzip to work. Zip downloads to location but is deleted without unzipping first. EDIT 2: Might not be the best but appears to work. I’ve changed my recent code to a working version for Inno 5 (edited the filenames, removed setup.)

; #pragma include __INCLUDE__ + ";" + ReadReg(HKLM, "Software\Mitrich Software\Inno Download Plugin", "InstallDir")
#pragma include __INCLUDE__ + ";" + "c:\lib\InnoDownloadPlugin"

[Setup]
#include <idp.iss>

[Types]
Name: custom;  Description: "Custom installation"; Flags: iscustom

[Components]
Name: conn;  Description: “CC File”;  Types: custom; Flags: exclusive
Name: hlnj;  Description: “H L (Recommended)”; Types: custom; Flags: exclusive

[Files]
Source: "{tmp}\text.net";  DestDir: "{userappdata}\ccc”; Flags: external; Components: conn
Source: "{tmp}\HLNJ.zip”;  DestDir: "{userappdata}\ccc”; Flags: external deleteafterinstall; Components: hlnj conn

[Code]
const
  SHCONTCH_NOPROGRESSBOX = 4;
  SHCONTCH_RESPONDYESTOALL = 16;
procedure InitializeWizard;
begin
    idpAddFileComp('http://ccc.sourceforge.net/text.net',  ExpandConstant('{tmp}\text.net'),  'conn');
    idpAddFileComp('http://ccc.sourceforge.net/SecurityUpdates/HLNJ.zip',  ExpandConstant('{tmp}\HLNJ.zip'), 'hlnj');

    idpDownloadAfter(wpReady);
end;

procedure CurStepChanged1(CurStep: TSetupStep);
begin
  if CurStep = ssPostInstall then 
  begin
    FileCopy(ExpandConstant('{tmp}\text.net'), ExpandConstant('{userappdata}\ccc\text.net'), false);
    FileCopy(ExpandConstant('{tmp}\HLNJ.zip'), ExpandConstant('{userappdata}\ccc\HLNJ.zip'), false);
end;
end;

procedure unzip(ZipFile, TargetFldr: variant);
var
 shellobj: variant;
 SrcFldr, DestFldr: variant;
 shellfldritems: variant;
begin
 if FileExists(ZipFile) then begin
   if not DirExists(TargetFldr) then 
      if not ForceDirectories(TargetFldr) then begin
        MsgBox('Can not create folder '+TargetFldr+' !!', mbError, MB_OK);
        Exit;
      end;   

   shellobj := CreateOleObject('Shell.Application');
   SrcFldr := shellobj.NameSpace(ZipFile);
   DestFldr := shellobj.NameSpace(TargetFldr);
   shellfldritems := SrcFldr.Items;
   DestFldr.CopyHere(shellfldritems, SHCONTCH_NOPROGRESSBOX or SHCONTCH_RESPONDYESTOALL);

if FileExists(TargetFldr+'\HLNJ.zip') then MsgBox('HLNJ.zip'+ZipFile+
 ' extracted to '+TargetFldr, mbInformation, MB_OK);
 end else MsgBox('HLNJ.zip  does not exist', mbError, MB_OK);
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssPostInstall then 
  begin
     unzip(ExpandConstant('{userappdata}\ccc\HLNJ.zip'),ExpandConstant('{userappdata}\ccc'));
  end;
  end;

Solution

  • You can not even extract one .zip file. So step by step first one and then ...

    The code is not complete. So one can only guess what is missing or wrong.

    To test the proper functioning of the unzip procedure you should use a simple standard inno-setup program.

    If this works you can add extra features and then find the error easier.

    Also the used constants "src" and "target" are not visible. How are they constructed?

    unzip(ExpandConstant(src), ExpandConstant(target));
    

    The use of different types of data should be avoided.

    AnsiString vs PAnsiChar

    procedure unzip(ZipFile, TargetFldr: PAnsiChar);
    ....
    end;
    
    procedure ExtractSomething(src, target : AnsiString);
    begin
      unzip(ExpandConstant(src), ExpandConstant(target));
    end;
    

    The use of {tmp} will, I suspect, made by the #include idp.iss download. This code also not exists.

    We will simulate this and use a known zip file from a known directory. So we do not need the download of the files.

    Information also does not harm but makes it easier to find fault.
    I used some MsgBox() for that.

    A simple procedure is for the beginning following.

    • Copy the HLNJ.zip file to C:\HLNJ.zip and look for a file or folder name part of the HLNJ.zip so we can test the extraction.
    • I use here a file named atext.txt wich is part of my HLNJ.zip

    CreateOleObject needs variants so use them instead.

     [Files]
     ; Simulate the download of HLNJ.zip is ok
     ; On the development PC .. on the client PC.
     Source: "C:\HLNJ.zip"; DestDir: "{tmp}";
    
     ; Now "HLNJ.zip" is in the {tmp} folder so we can use it.
     Source: "{tmp}\HLNJ.zip";  DestDir: "{userappdata}\ccc"; Flags: external deleteafterinstall
    
    [Code]
    const
      SHCONTCH_NOPROGRESSBOX = 4;
      SHCONTCH_RESPONDYESTOALL = 16;
    
    ....
    
    procedure unzip(ZipFile, TargetFldr: variant);// <--- variant instead of PAnsiChar 
    var
     shellobj: variant;
     SrcFldr, DestFldr: variant;
     shellfldritems: variant;
    begin
     if FileExists(ZipFile) then begin
       if not DirExists(TargetFldr) then 
          if not ForceDirectories(TargetFldr) then begin
            MsgBox('Can not create folder '+TargetFldr+' !!', mbError, MB_OK);
            Exit;
          end;    
    
       shellobj := CreateOleObject('Shell.Application');
       SrcFldr := shellobj.NameSpace(ZipFile);
       DestFldr := shellobj.NameSpace(TargetFldr);
       shellfldritems := SrcFldr.Items;
       DestFldr.CopyHere(shellfldritems, SHCONTCH_NOPROGRESSBOX or SHCONTCH_RESPONDYESTOALL);
    
       if FileExists(TargetFldr+'\atext.txt') then MsgBox('ZipFile '+ZipFile+
         ' extracted to '+TargetFldr, mbInformation, MB_OK);
    
     end else MsgBox('ZipFile '+ZipFile+' does not exist', mbError, MB_OK);
    end;
    
    
    procedure CurStepChanged(CurStep: TSetupStep);
    begin
      if CurStep = ssPostInstall then 
      begin
         unzip(ExpandConstant('{userappdata}\ccc\HLNJ.zip'),ExpandConstant('{userappdata}\ccc\extracted'));
      end;
    end;
    

    enter image description here